2 #include<particle_simulator.hpp>
3 #include<unordered_map>
6 #include"Common/binary_tree.h"
10 #ifndef ARRAY_ALLOW_LIMIT
11 #define ARRAY_ALLOW_LIMIT 1000000000
14 #ifdef PARTICLE_SIMULATOR_MPI_PARALLEL
15 template <
class Ttree>
16 void SetRankComm(
const PS::F64ort pos_domain[], Ttree &tree,
17 PS::ReallocatableArray<PS::S32> & rank_neighbor,
19 rank_neighbor.clearSize();
21 const PS::S32 my_rank = PS::Comm::getRank();
22 const PS::S32 n_proc = PS::Comm::getNumberOfProc();
24 PS::F64ort pos_my_domain = tree.getOuterBoundaryOfLocalTree();
25 PS::F64ort pos_my_domain_in = tree.getInnerBoundaryOfLocalTree();
26 PS::F64ort * pos_domain_out =
new PS::F64ort[n_proc];
27 PS::Comm::allGather(&pos_my_domain, 1, pos_domain_out);
30 PS::F64ort * pos_domain_in =
new PS::F64ort[n_proc];
31 PS::Comm::allGather(&pos_my_domain_in, 1, pos_domain_in);
36 rank_neighbor.clearSize();
37 for(
int i=0; i<n_proc; i++){
38 if(i==my_rank)
continue;
40 else if( pos_my_domain.contained(pos_domain_in[i]) || pos_my_domain_in.contained(pos_domain_out[i])){
41 rank_neighbor.push_back(i);
45 delete [] pos_domain_in;
46 delete [] pos_domain_out;
68 <<
" rank="<<
rank_<<std::endl;
99 PS::ReallocatableArray< std::pair<PS::S32, PS::S32> > & adr_ngb){
184 PS::ReallocatableArray<Cluster> cluster_comm_;
185 std::unordered_map<PS::S32, PS::S32> id_to_adr_pcluster_;
187 PS::ReallocatableArray< std::pair<PS::S32, PS::S32> > adr_ngb_multi_cluster_;
188 PS::ReallocatableArray<PS::S32> * adr_sys_one_cluster_;
189 PS::ReallocatableArray<PtclCluster> * ptcl_cluster_;
190 PS::ReallocatableArray<PS::S32> id_cluster_send_;
191 PS::ReallocatableArray<PS::S32> id_cluster_recv_;
192 PS::ReallocatableArray<PS::S32> adr_pcluster_send_;
193 PS::ReallocatableArray<PS::S32> adr_pcluster_recv_;
194 PS::ReallocatableArray<PS::S32> n_cluster_send_;
195 PS::ReallocatableArray<PS::S32> n_cluster_recv_;
196 PS::ReallocatableArray<PS::S32> n_cluster_disp_send_;
197 PS::ReallocatableArray<PS::S32> n_cluster_disp_recv_;
198 PS::ReallocatableArray<PS::S32> rank_send_cluster_;
199 PS::ReallocatableArray<PS::S32> rank_recv_cluster_;
201 PS::ReallocatableArray<PS::S32> adr_sys_ptcl_send_;
202 PS::ReallocatableArray<PtclComm> ptcl_send_;
203 PS::ReallocatableArray<PS::S32> rank_send_ptcl_;
204 PS::ReallocatableArray<PS::S32> n_ptcl_send_;
205 PS::ReallocatableArray<PS::S32> n_ptcl_disp_send_;
206 PS::ReallocatableArray<PS::S32> rank_recv_ptcl_;
207 PS::ReallocatableArray<PS::S32> n_ptcl_recv_;
208 PS::ReallocatableArray<PS::S32> n_ptcl_disp_recv_;
210 void packDataToThread0(T * data){
211 const PS::S32 n_thread = PS::Comm::getNumberOfThread();
212 PS::S32 size_data_th0 = data[0].size();
213 PS::S32 size_data = size_data_th0;
214 for(
PS::S32 i=1; i<n_thread; i++){
215 size_data += data[i].size();
221 data[0].resizeNoInitialize(size_data);
224 const PS::S32 ith = PS::Comm::getThreadNum();
226 PS::S32 offset = size_data_th0;
227 for(
PS::S32 i=1; i<ith; i++) offset += data[i].size();
228 for(
PS::S32 i=0; i<data[ith].size(); i++) data[0][i+offset] = data[ith][i];
237 PS::ReallocatableArray< std::pair<PS::S32, PS::S32> > & adr_ngb_array,
239 if(target->
adr_sys_ < 0) fg_isolated =
false;
241 target->
next_ = NULL;
245 for(
PS::S32 i=0; i<n_ngb; i++){
246 PS::S32 adr_ngb = adr_ngb_array[target_adr+i].second;
247 if( (p_first+adr_ngb)->flag_searched_ ==
false){
248 p_top->
next_ = p_first+adr_ngb;
249 p_top = p_first+adr_ngb;
250 searchClusterImpl(p_first+adr_ngb, p_first, p_top, n_ptcl_in_cluster,
251 adr_ngb_array, fg_isolated);
256 void setNgbAdrHead(PS::ReallocatableArray< std::pair<PS::S32, PS::S32> > id_ngb_multi_cluster[]){
257 const PS::S32 size_ngb = id_ngb_multi_cluster[0].size();
259 for(
PS::S32 i=0; i<size_ngb; i++){
260 if(id_ngb_multi_cluster[0][i].first == ptcl_cluster_[0][n_cnt].id_){
261 ptcl_cluster_[0][n_cnt].adr_ngb_head_ = i;
267 void mergePtclCluster(
const PS::ReallocatableArray<PtclOuter> ptcl_outer[],
268 PS::ReallocatableArray< std::pair<PS::S32, PS::S32> > id_ngb_multi_cluster[]){
269 if(ptcl_outer[0].size() == 0)
return;
270 const PS::S32 size = ptcl_outer[0].size();
271 PS::S32 id_tmp = ptcl_outer[0][0].id_;
272 PS::S32 adr_ngb_head = id_ngb_multi_cluster[0].size();
273 PS::S32 rank_tmp = ptcl_outer[0][0].rank_org_;
276 if(id_tmp != ptcl_outer[0][i].id_){
277 ptcl_cluster_[0].push_back(
PtclCluster(id_tmp, -1, adr_ngb_head, n_cnt,
false, NULL, rank_tmp) );
278 id_tmp = ptcl_outer[0][i].id_;
279 rank_tmp = ptcl_outer[0][i].rank_org_;
280 adr_ngb_head += n_cnt;
283 id_ngb_multi_cluster[0].push_back( std::pair<PS::S32, PS::S32>
284 (ptcl_outer[0][i].id_,
285 ptcl_outer[0][i].id_ngb_));
288 ptcl_cluster_[0].push_back(
PtclCluster(id_tmp, -1, adr_ngb_head, n_cnt,
false, NULL, rank_tmp) );
292 template<
class T>
bool operator() (
const T & left,
const T & right)
const {
293 return left.id_ == right.id_;
296 struct OPEqualSecond{
297 template<
class T>
bool operator() (
const T & left,
const T & right)
const {
298 return left.second == right.second;
302 template<
class T>
bool operator() (
const T & left,
const T & right)
const {
303 return left.id_ < right.id_;
306 struct OPLessIDCluster{
307 template<
class T>
bool operator() (
const T & left,
const T & right)
const {
308 return left.id_cluster_ < right.id_cluster_;
311 struct OPLessRankOrg{
312 template<
class T>
bool operator() (
const T & left,
const T & right)
const {
313 return left.rank_org_ < right.rank_org_;
317 template<
class T>
bool operator() (
const T & left,
const T & right)
const {
318 return left.rank_ < right.rank_;
322 template<
class T>
bool operator() (
const T & left,
const T & right)
const {
323 return left.first < right.first;
327 template<
class T>
bool operator() (
const T & left,
const T & right)
const {
328 return left.second < right.second;
334 const PS::S32 n_thread = PS::Comm::getNumberOfThread();
335 adr_sys_one_cluster_ =
new PS::ReallocatableArray<PS::S32>[n_thread];
336 ptcl_cluster_ =
new PS::ReallocatableArray<PtclCluster>[n_thread];
350 template<
class Tpsoft,
class Tepj>
354 PS::F64 r_crit_i = _pi.changeover.getRout();
358 auto& pi_cm = _pi.group_data.cm;
361 assert(pi_cm.mass>=0.0);
364 if (pi_cm.mass>0.0) {
365 pi.
mass = pi_cm.mass;
366 pi.
vel[0] = pi_cm.vel.x;
367 pi.
vel[1] = pi_cm.vel.y;
368 pi.
vel[2] = pi_cm.vel.z;
375 for (
PS::S32 j=0; j<_nb; j++) {
376 if (_pi.id==_pb[j].id)
continue;
377 auto& pbj_cm = _pb[j].group_data.cm;
379 assert(pbj_cm.mass>=0.0);
384 if (pbj_cm.mass>0.0) {
385 pj.
vel[0] = pbj_cm.vel.x;
386 pj.
vel[1] = pbj_cm.vel.y;
387 pj.
vel[2] = pbj_cm.vel.z;
388 pj.
mass = pbj_cm.mass;
395 pj.
mass= _pb[j].mass;
400 COMM::Binary::particleToSemiEcc(semi, ecc, r, rv, pi, pj, _G);
402 PS::F64 r_crit_j = _pb[j].r_out;
405 if (peri < r_crit_max && !(rv<0 && r>r_crit_max) ) {
406 _index[n_nb_new++] = j;
408 #ifdef CLUSTER_DEBUG_PRINT
410 std::cerr<<
"Reject id.i "<<_pi.id<<
" id.j "<<_pb[j].id<<
" peri "
411 <<peri<<
" r_out.i "<<r_crit_i<<
" r_out.j "<<r_crit_j<<
" dr "<<r<<
" drdv "<<rv
412 <<
" cm.vel.i "<<pi.
vel[0]<<
" "<<pi.
vel[1]<<
" "<<pi.
vel[2]<<
" m.i "<<pi.
mass<<
" "
413 <<
" status.i "<<_pi.group_data.artificial.status<<
" mass_bk.i "<<_pi.group_data.artificial.mass_backup
414 <<
" cm.vel.j "<<pj.
vel[0]<<
" "<<pj.
vel[1]<<
" "<<pj.
vel[2]<<
" m.j "<<pj.
mass<<
" "
415 <<
" status.j "<<_pb[j].group_data.artificial.status<<
" mass_bk.j "<<_pb[j].group_data.artificial.mass_backup
424 template<
class Tsys,
class Ttree,
class Tepj>
427 const PS::F64ort pos_domain[],
430 static PS::ReallocatableArray<PtclOuter> * ptcl_outer = NULL;
431 static PS::ReallocatableArray< std::pair<PS::S32, PS::S32> > * id_ngb_multi_cluster = NULL;
432 const PS::S32 n_thread = PS::Comm::getNumberOfThread();
433 if(ptcl_outer==NULL) ptcl_outer =
new PS::ReallocatableArray<PtclOuter>[n_thread];
434 if(id_ngb_multi_cluster==NULL) id_ngb_multi_cluster =
new PS::ReallocatableArray< std::pair<PS::S32, PS::S32> >[n_thread];
435 const PS::S32 my_rank = PS::Comm::getRank();
437 const PS::S32 n_loc = sys.getNumberOfParticleLocal();
438 #ifdef CLUSTER_VELOCITY
444 const PS::S32 ith = PS::Comm::getThreadNum();
446 adr_sys_one_cluster_[ith].clearSize();
447 id_ngb_multi_cluster[ith].clearSize();
448 for(
PS::S32 i=0; i<ptcl_cluster_[ith].size(); i++) ptcl_cluster_[ith][i].clear();
449 ptcl_cluster_[ith].clearSize();
450 for(
PS::S32 i=0; i<ptcl_outer[ith].size(); i++) ptcl_outer[ith][i].clear();
451 ptcl_outer[ith].clearSize();
453 for(
PS::S32 i=0; i<n_loc; i++){
454 if(sys[i].n_ngb == 1){
456 adr_sys_one_cluster_[ith].push_back(i);
461 PS::S32 n_ngb_tree_i = tree.getNeighborListOneParticle(sys[i], nbl) ;
462 if(n_ngb_tree_i!=sys[i].n_ngb) {
463 std::cerr<<
"Error: particle "<<i<<
" Tree neighbor search number ("<<n_ngb_tree_i<<
") is inconsistent with force kernel neighbor number ("<<sys[i].n_ngb<<
")!\n Neighbor ID from tree: ";
464 for(
int j=0; j<n_ngb_tree_i; j++) {
465 std::cerr<<(nbl+j)->
id<<
" ";
467 std::cerr<<std::endl;
476 #ifdef SAVE_NEIGHBOR_ID_IN_FORCE_KERNEL
479 PS::S32 n_ngb_force_i = sys[i].n_ngb;
481 if (n_ngb_force_i<=4) {
482 for (
PS::S32 k=0; k<n_ngb_force_i; k++) {
483 nb_pack[k] = *tree.getEpjFromId(sys[i].id_ngb[k]);
488 else sys[i].n_ngb = tree.getNeighborListOneParticle(sys[i], nbl) - 1;
491 PS::S32 n_ngb_force_i = sys[i].n_ngb;
493 sys[i].n_ngb = tree.getNeighborListOneParticle(sys[i], nbl) - 1;
496 if(n_ngb_force_i<sys[i].n_ngb+1) {
497 std::cerr<<
"Error: particle "<<i<<
" Tree neighbor search number ("<<sys[i].n_ngb+1<<
") is inconsistent with force kernel neighbor number ("<<n_ngb_force_i<<
")!\n Neighbor ID from tree: ";
498 for(
int j=0; j<sys[i].n_ngb+1; j++) {
499 std::cerr<<(nbl+j)->
id<<
" ";
501 std::cerr<<std::endl;
507 if(sys[i].n_ngb == 0){
511 adr_sys_one_cluster_[ith].push_back(i);
515 PS::S32 adr_ngb_head_i = id_ngb_multi_cluster[ith].size();
516 PS::S32 n_ngb_i = sys[i].n_ngb;
518 #ifdef CLUSTER_VELOCITY
520 PS::S32 neighbor_index[n_ngb_i];
523 assert(n_ngb_check>=0);
525 sys[i].n_ngb = n_ngb_check;
528 if (n_ngb_check==0) {
529 adr_sys_one_cluster_[ith].push_back(i);
533 for(
PS::S32 j=0; j<n_ngb_check; j++) {
534 PS::S32 index = neighbor_index[j];
535 auto* nbj = nbl + index;
537 id_ngb_multi_cluster[ith].push_back( std::pair<PS::S32, PS::S32>(sys[i].
id, nbj->id) );
538 if( nbj->rank_org != my_rank ){
539 ptcl_outer[ith].push_back(
PtclOuter(nbj->id, sys[i].id, nbj->rank_org));
542 ptcl_cluster_[ith].push_back(
PtclCluster(sys[i].
id, i, adr_ngb_head_i, n_ngb_check,
false, NULL, my_rank) );
546 for (
int j=0; j<n_ngb_i+1; j++) {
548 if (sys[i].
id==nbj->id)
continue;
550 id_ngb_multi_cluster[ith].push_back( std::pair<PS::S32, PS::S32>(sys[i].
id, nbj->id) );
551 if( nbj->rank_org != my_rank ){
552 ptcl_outer[ith].push_back(
PtclOuter(nbj->id, sys[i].id, nbj->rank_org));
555 ptcl_cluster_[ith].push_back(
PtclCluster(sys[i].
id, i, adr_ngb_head_i, n_ngb_i,
false, NULL, my_rank) );
560 packDataToThread0(adr_sys_one_cluster_);
561 packDataToThread0(ptcl_cluster_);
562 packDataToThread0(id_ngb_multi_cluster);
563 packDataToThread0(ptcl_outer);
564 setNgbAdrHead(id_ngb_multi_cluster);
565 n_pcluster_self_node_ = ptcl_cluster_[0].size();
566 std::sort(ptcl_outer[0].getPointer(), ptcl_outer[0].getPointer(ptcl_outer[0].size()), OPLessID());
582 mergePtclCluster(ptcl_outer, id_ngb_multi_cluster);
583 id_to_adr_pcluster_.clear();
584 for(
PS::S32 i=0; i<ptcl_cluster_[0].size(); i++){
585 id_to_adr_pcluster_.insert(std::pair<PS::S32, PS::S32>(ptcl_cluster_[0][i].id_, i));
587 adr_ngb_multi_cluster_.clearSize();
591 adr_ngb_multi_cluster_.resizeNoInitialize(id_ngb_multi_cluster[0].size());
592 for(
PS::S32 i=0; i<id_ngb_multi_cluster[0].size(); i++){
593 const PS::S32 adr_self = id_to_adr_pcluster_[id_ngb_multi_cluster[0][i].first];
594 const PS::S32 adr_ngb = id_to_adr_pcluster_[id_ngb_multi_cluster[0][i].second];
595 adr_ngb_multi_cluster_[i] = std::pair<PS::S32, PS::S32>(adr_self, adr_ngb);
601 for(
PS::S32 i=0; i<n_pcluster_self_node_; i++){
602 if(ptcl_cluster_[0][i].id_ != sys[ptcl_cluster_[0][i].adr_sys_].
id){
603 std::cerr<<
"i="<<i<<
" ptcl_cluster_[0][i].adr_sys_="<<ptcl_cluster_[0][i].adr_sys_
604 <<
" ptcl_cluster_[0][i].id_="<<ptcl_cluster_[0][i].id_
605 <<
" sys[ptcl_cluster_[0][i].adr_sys_].id="<<sys[ptcl_cluster_[0][i].adr_sys_].id<<std::endl;
607 assert(ptcl_cluster_[0][i].id_ == sys[ptcl_cluster_[0][i].adr_sys_].
id);
609 std::cerr<<
"PASS: checkPtclCluster"<<std::endl;
614 const PS::S32 my_rank = PS::Comm::getRank();
615 const PS::S32 n_loc = ptcl_cluster_[0].size();
622 static PS::ReallocatableArray<Cluster> cluster_isolated;
623 for(
PS::S32 i=0; i<cluster_isolated.size(); i++) cluster_isolated[i].clear();
624 cluster_isolated.clearSize();
629 for(
PS::S32 i=0; i<n_loc; i++){
630 bool flag_isolated =
true;
631 if(ptcl_cluster_[0][i].flag_searched_ ==
false){
633 PtclCluster * p_top = ptcl_cluster_[0].getPointer(i);
634 searchClusterImpl(ptcl_cluster_[0].getPointer(i), ptcl_cluster_[0].getPointer(),
635 p_top, n_ptcl_in_cluster,
636 adr_ngb_multi_cluster_, flag_isolated);
638 PtclCluster * p_tmp = ptcl_cluster_[0].getPointer(i);
641 while(p_tmp != NULL){
642 if(p_tmp->
id_ < id_cluster) id_cluster = p_tmp->
id_;
644 p_tmp = p_tmp->
next_;
646 cluster_isolated.push_back(
Cluster(id_cluster, n_ptcl_in_cluster, n_ptcl_in_cluster, adr_sys_multi_cluster_isolated_head, my_rank) );
651 PtclCluster * p_tmp = ptcl_cluster_[0].getPointer(i);
653 while(p_tmp != NULL){
654 if(p_tmp->
id_ < id_cluster) id_cluster = p_tmp->
id_;
655 PS::S32 adr_pcluster = p_tmp-ptcl_cluster_[0].getPointer();
657 p_tmp = p_tmp->
next_;
669 std::cerr<<
"PASS: checkMediator (1st)"<<std::endl;
674 std::cerr<<
"PASS: checkMediator (2nd)"<<std::endl;
678 for(
PS::S32 i=0; i<ptcl_cluster_[0].size(); i++){
679 ptcl_cluster_[0][i].setIdClusterImpl(ptcl_cluster_[0], adr_ngb_multi_cluster_);
683 #ifdef PARTICLE_SIMULATOR_MPI_PARALLEL
684 template <
class Ttree>
685 void connectNodes(PS::F64ort pos_domain[], Ttree & tree){
686 const PS::S32 n_proc_tot = PS::Comm::getNumberOfProc();
687 const PS::S32 my_rank = PS::Comm::getRank();
688 static PS::ReallocatableArray<PS::S32> rank_neighbor;
689 static PS::ReallocatableArray<PS::S32> n_send_org;
690 static PS::ReallocatableArray<PS::S32> n_send_org_disp;
691 static PS::ReallocatableArray<PS::S32> id_send_org;
692 static PS::ReallocatableArray<PS::S32> n_send;
693 static PS::ReallocatableArray<PS::S32> n_recv;
694 static PS::ReallocatableArray<PS::S32> n_send_disp;
695 static PS::ReallocatableArray<PS::S32> n_recv_disp;
696 static PS::ReallocatableArray<PS::S32> id_send;
697 static PS::ReallocatableArray<PS::S32> id_recv;
698 rank_neighbor.clearSize();
699 n_send_org.resizeNoInitialize(n_proc_tot);
700 n_send_org_disp.resizeNoInitialize(n_proc_tot+1);
701 SetRankComm(pos_domain, tree, rank_neighbor);
702 for(
PS::S32 i=0; i<n_proc_tot; i++) n_send_org[i] = 0;
704 for(
PS::S32 i=n_pcluster_self_node_; i<ptcl_cluster_[0].size(); i++){
705 assert(ptcl_cluster_[0][i].rank_org_ != my_rank);
706 n_send_org[ptcl_cluster_[0][i].rank_org_]++;
709 n_send_org_disp[0] = 0;
710 static PS::ReallocatableArray<PS::S32> n_cnt_send;
711 n_cnt_send.resizeNoInitialize(n_proc_tot);
712 for(
PS::S32 i=0; i<n_proc_tot; i++) {
713 n_send_org_disp[i+1] = n_send_org_disp[i] + n_send_org[i];
717 id_send_org.resizeNoInitialize(n_send_org_disp[n_proc_tot]);
718 for(
PS::S32 i=n_pcluster_self_node_; i<ptcl_cluster_[0].size(); i++){
719 PS::S32 rank = ptcl_cluster_[0][i].rank_org_;
720 PS::S32 adr = n_send_org_disp[rank] + n_cnt_send[rank];
721 id_send_org[adr] = ptcl_cluster_[0][i].id_;
725 const PS::S32 n_rank_send = rank_neighbor.size();
726 n_send.resizeNoInitialize(n_rank_send);
727 n_recv.resizeNoInitialize(n_rank_send);
728 n_send_disp.resizeNoInitialize(n_rank_send+1);
729 n_recv_disp.resizeNoInitialize(n_rank_send+1);
730 id_send.resizeNoInitialize(ptcl_cluster_[0].size());
733 for (
PS::S32 i=0; i<n_rank_send; i++) {
734 PS::S32 rank = rank_neighbor[i];
735 n_send[i] = n_send_org[rank];
736 if (n_send[i]!=n_cnt_send[rank]) {
737 std::cerr<<
"n_send["<<i<<
"]="<<n_send[i]<<
" != n_cnt_send["<<rank<<
"]="<<n_cnt_send[rank]<<std::endl;
740 n_send_disp[i+1] = n_send_disp[i] + n_send[i];
743 for (
PS::S32 j=0; j<n_send[i]; j++) {
744 id_send[n_send_disp[i]+j] = id_send_org[n_send_org_disp[rank]+j];
749 PS::Comm::sendIrecv(n_send.getPointer(), rank_neighbor.getPointer(), 1, n_rank_send,
750 n_recv.getPointer(), rank_neighbor.getPointer(), 1, n_rank_send);
753 static PS::ReallocatableArray<MPI_Request> req_send;
754 static PS::ReallocatableArray<MPI_Request> req_recv;
755 static PS::ReallocatableArray<MPI_Status> stat_send;
756 static PS::ReallocatableArray<MPI_Status> stat_recv;
757 req_send.resizeNoInitialize(n_proc_tot);
758 req_recv.resizeNoInitialize(n_proc_tot);
759 stat_send.resizeNoInitialize(n_proc_tot);
760 stat_recv.resizeNoInitialize(n_proc_tot);
762 for(
PS::S32 i=0; i<rank_neighbor.size(); i++){
763 PS::S32 rank = rank_neighbor[i];
764 MPI_Isend(n_send.getPointer(i), 1, PS::GetDataType<PS::S32>(),
765 rank, 1837, MPI_COMM_WORLD, req_send.getPointer(i));
766 MPI_Irecv(n_recv.getPointer(i), 1, PS::GetDataType<PS::S32>(),
767 rank, 1837, MPI_COMM_WORLD, req_recv.getPointer(i));
769 MPI_Waitall(rank_neighbor.size(), req_send.getPointer(), stat_send.getPointer());
770 MPI_Waitall(rank_neighbor.size(), req_recv.getPointer(), stat_recv.getPointer());
774 for(
PS::S32 i=0; i<n_rank_send; i++){
775 n_recv_disp[i+1] = n_recv_disp[i] + n_recv[i];
777 id_recv.resizeNoInitialize(n_recv_disp[n_rank_send]);
780 PS::Comm::sendIrecvV(id_send.getPointer(), rank_neighbor.getPointer(), n_send.getPointer(), n_send_disp.getPointer(), n_rank_send,
781 id_recv.getPointer(), rank_neighbor.getPointer(), n_recv.getPointer(), n_recv_disp.getPointer(), n_rank_send);
784 rank_send_cluster_.resizeNoInitialize(0);
785 rank_recv_cluster_.resizeNoInitialize(0);
786 n_cluster_send_.resizeNoInitialize(0);
787 n_cluster_recv_.resizeNoInitialize(0);
790 for(
PS::S32 i=0; i<n_rank_send; i++){
791 PS::S32 rank = rank_neighbor[i];
793 rank_recv_cluster_.push_back(rank);
794 n_cluster_recv_.push_back(n_send[i]);
796 MPI_Isend(id_send.getPointer(n_send_disp[i]), n_send[i], PS::GetDataType<PS::S32>(),
797 rank, 1871, MPI_COMM_WORLD, req_send.getPointer(n_proc_recv));
802 rank_send_cluster_.push_back(rank);
803 n_cluster_send_.push_back(n_recv[i]);
805 MPI_Irecv(id_recv.getPointer(n_recv_disp[i]), n_recv[i], PS::GetDataType<PS::S32>(),
806 rank, 1871, MPI_COMM_WORLD, req_recv.getPointer(n_proc_send));
812 MPI_Waitall(n_proc_recv, req_send.getPointer(), stat_send.getPointer());
813 MPI_Waitall(n_proc_send, req_recv.getPointer(), stat_recv.getPointer());
815 adr_pcluster_send_.clearSize();
816 adr_pcluster_recv_.clearSize();
817 for(
PS::S32 i=0; i<n_recv_disp.back(); i++){
819 auto itr = id_to_adr_pcluster_.find(id_recv[i]);
820 assert(itr != id_to_adr_pcluster_.end());
821 assert(id_to_adr_pcluster_[id_recv[i]] < n_pcluster_self_node_);
823 adr_pcluster_send_.push_back(id_to_adr_pcluster_[id_recv[i]]);
825 for(
PS::S32 i=0; i<n_send_disp.back(); i++){
827 auto itr = id_to_adr_pcluster_.find(id_send[i]);
828 assert(itr != id_to_adr_pcluster_.end());
838 assert(id_to_adr_pcluster_[id_send[i]] >= n_pcluster_self_node_);
840 adr_pcluster_recv_.push_back(id_to_adr_pcluster_[id_send[i]]);
842 n_cluster_disp_send_.resizeNoInitialize(n_proc_send+1);
843 n_cluster_disp_recv_.resizeNoInitialize(n_proc_recv+1);
844 n_cluster_disp_send_[0] = n_cluster_disp_recv_[0] = 0;
845 for(
PS::S32 i=0; i<n_proc_send; i++) n_cluster_disp_send_[i+1] = n_cluster_disp_send_[i] + n_cluster_send_[i];
846 for(
PS::S32 i=0; i<n_proc_recv; i++) n_cluster_disp_recv_[i+1] = n_cluster_disp_recv_[i] + n_cluster_recv_[i];
849 void setIdClusterGlobalIteration(){
854 std::cerr<<
"Error: size overflow: rank: "<<PS::Comm::getRank()<<
" n_cluster_disp_send_.back()="<<n_cluster_disp_send_.back()<<
" size="<<n_cluster_disp_send_.size()<<std::endl;
857 std::cerr<<
"Error: size overflow: rank: "<<PS::Comm::getRank()<<
" n_cluster_disp_recv_.back()="<<n_cluster_disp_recv_.back()<<
" size="<<n_cluster_disp_recv_.size()<<std::endl;
860 id_cluster_send_.resizeNoInitialize(n_cluster_disp_send_.back());
861 id_cluster_recv_.resizeNoInitialize(n_cluster_disp_recv_.back());
864 const PS::S32 n_proc_tot = PS::Comm::getNumberOfProc();
865 static PS::ReallocatableArray<MPI_Request> req_send;
866 static PS::ReallocatableArray<MPI_Request> req_recv;
867 static PS::ReallocatableArray<MPI_Status> stat_send;
868 static PS::ReallocatableArray<MPI_Status> stat_recv;
869 req_send.resizeNoInitialize(n_proc_tot);
870 req_recv.resizeNoInitialize(n_proc_tot);
871 stat_send.resizeNoInitialize(n_proc_tot);
872 stat_recv.resizeNoInitialize(n_proc_tot);
875 bool flag_itr_glb =
true;
878 flag_itr_glb =
false;
880 for(
PS::S32 i=0; i<adr_pcluster_send_.size(); i++){
881 PS::S32 adr = adr_pcluster_send_[i];
882 assert(adr <= ptcl_cluster_[0].size());
883 id_cluster_send_[i] = ptcl_cluster_[0][adr].id_cluster_;
886 PS::Comm::sendIrecvV(id_cluster_send_.getPointer(), rank_send_cluster_.getPointer(), n_cluster_send_.getPointer(), n_cluster_disp_send_.getPointer(), rank_send_cluster_.size(),
887 id_cluster_recv_.getPointer(), rank_recv_cluster_.getPointer(), n_cluster_recv_.getPointer(), n_cluster_disp_recv_.getPointer(), rank_recv_cluster_.size());
891 for(
PS::S32 i=0; i<rank_send_cluster_.size(); i++){
892 PS::S32 rank = rank_send_cluster_[i];
893 MPI_Isend(id_cluster_send_.getPointer(n_cluster_disp_send_[i]), n_cluster_send_[i], PS::GetDataType<PS::S32>(),
894 rank, 1947, MPI_COMM_WORLD, req_send.getPointer(n_proc_send));
897 for(
PS::S32 i=0; i<rank_recv_cluster_.size(); i++){
898 PS::S32 rank = rank_recv_cluster_[i];
899 MPI_Irecv(id_cluster_recv_.getPointer(n_cluster_disp_recv_[i]), n_cluster_recv_[i], PS::GetDataType<PS::S32>(),
900 rank, 1947, MPI_COMM_WORLD, req_recv.getPointer(n_proc_recv));
903 MPI_Waitall(n_proc_send, req_send.getPointer(), stat_send.getPointer());
904 MPI_Waitall(n_proc_recv, req_recv.getPointer(), stat_recv.getPointer());
907 bool flag_itr_loc =
false;
908 for(
PS::S32 i=0; i<id_cluster_recv_.size(); i++){
909 PS::S32 adr = adr_pcluster_recv_[i];
910 if(id_cluster_recv_[i] < ptcl_cluster_[0][adr].id_cluster_){
911 ptcl_cluster_[0][adr].id_cluster_ = id_cluster_recv_[i];
912 flag_itr_loc |=
true;
917 PS::S32 id_clucster_prev = ptcl_cluster_[0][adr].id_cluster_;
918 ptcl_cluster_[0][adr].setIdClusterImpl(ptcl_cluster_[0], adr_ngb_multi_cluster_);
919 if( id_clucster_prev != ptcl_cluster_[0][adr].id_cluster_){
920 flag_itr_loc |=
true;
923 flag_itr_glb = PS::Comm::synchronizeConditionalBranchOR(flag_itr_loc);
934 void sendAndRecvCluster(
const Tsys & sys){
935 PS::S32 my_rank = PS::Comm::getRank();
936 PS::S32 n_proc = PS::Comm::getNumberOfProc();
937 static PS::ReallocatableArray<Cluster> cluster_loc;
938 cluster_loc.clearSize();
941 cluster_loc.push_back(
Cluster(id_cluster_ref, 0, 0, 0, my_rank) );
945 cluster_loc.push_back(
Cluster(id_cluster_ref, 0, 0, i, my_rank) );
948 cluster_loc.back().n_ptcl_++;
953 static PS::ReallocatableArray<PS::S32> n_cluster_recv;
954 static PS::ReallocatableArray<PS::S32> n_cluster_recv_disp;
955 n_cluster_recv.resizeNoInitialize(n_proc);
956 n_cluster_recv_disp.resizeNoInitialize(n_proc+1);
957 PS::S32 n_cluster_tot_loc = cluster_loc.size();
958 PS::Comm::allGather(&n_cluster_tot_loc, 1, n_cluster_recv.getPointer());
959 n_cluster_recv_disp[0] = 0;
960 for(
PS::S32 i=0; i<n_proc; i++){
961 n_cluster_recv_disp[i+1] = n_cluster_recv[i] + n_cluster_recv_disp[i];
964 static PS::ReallocatableArray<Cluster> cluster_recv;
965 cluster_recv.resizeNoInitialize(n_cluster_recv_disp[n_proc]);
966 if(n_cluster_tot_loc > 0){
967 PS::Comm::allGatherV(cluster_loc.getPointer(), n_cluster_tot_loc,
968 cluster_recv.getPointer(),
969 n_cluster_recv.getPointer(), n_cluster_recv_disp.getPointer());
973 PS::Comm::allGatherV(&tmp, n_cluster_tot_loc,
974 cluster_recv.getPointer(),
975 n_cluster_recv.getPointer(), n_cluster_recv_disp.getPointer());
983 for(
PS::S32 i0=0; i0<n_cluster_tot_loc; i0++){
984 const PS::S32 id_cluster = cluster_loc[i0].id_;
985 const PS::S32 n_ptcl_in_cluster = cluster_loc[i0].n_ptcl_stored_;
986 PS::S32 rank_send_tmp = my_rank;
987 PS::S32 n_ptcl_max = n_ptcl_in_cluster;
988 for(
PS::S32 i1=0; i1<n_proc; i1++){
989 if(i1 == my_rank)
continue;
997 for(
PS::S32 i2=n_cluster_recv_disp[i1]; i2<n_cluster_recv_disp[i1+1]; i2++){
998 if(id_cluster == cluster_recv[i2].id_){
1006 if( (n_ptcl_max < cluster_recv[i2].n_ptcl_stored_) ||
1007 (n_ptcl_max == cluster_recv[i2].n_ptcl_stored_ && rank_send_tmp > i1) ){
1009 n_ptcl_max = cluster_recv[i2].n_ptcl_stored_;
1014 cluster_loc[i0].rank_ = rank_send_tmp;
1016 std::sort(cluster_loc.getPointer(), cluster_loc.getPointer(cluster_loc.size()), OPLessRank());
1021 ptcl_send_.clearSize();
1022 rank_send_ptcl_.clearSize();
1023 n_ptcl_send_.clearSize();
1024 adr_sys_ptcl_send_.clearSize();
1025 if(cluster_loc.size() > 0){
1026 PS::S32 rank_send_ref = -999999;
1027 for(
PS::S32 i=0; i<cluster_loc.size(); i++){
1028 if(cluster_loc[i].rank_ == my_rank)
continue;
1029 if( rank_send_ref != cluster_loc[i].rank_){
1030 rank_send_ref = cluster_loc[i].rank_;
1031 rank_send_ptcl_.push_back(rank_send_ref);
1032 n_ptcl_send_.push_back(0);
1035 PS::S32 n_tmp = cluster_loc[i].n_ptcl_;
1037 for(
PS::S32 ii=0; ii<n_tmp; ii++){
1043 const auto &p = sys[adr_sys];
1044 adr_sys_ptcl_send_.push_back(adr_sys);
1046 ptcl_send_.back().id_cluster = cluster_loc[i].id_;
1048 if(ptcl_send_.back().mass==0&&ptcl_send_.back().group_data.artificial.isUnused()) {
1049 std::cerr<<
"Error! sending particle is unused! adr="<<adr_sys<<std::endl;
1053 n_ptcl_send_.back()++;
1063 assert(cluster_loc[i].n_ptcl_stored_ == n_cnt);
1070 n_ptcl_disp_send_.resizeNoInitialize(rank_send_ptcl_.size()+1);
1071 n_ptcl_disp_send_[0] = 0;
1072 for(
PS::S32 i=0; i<rank_send_ptcl_.size(); i++){
1073 n_ptcl_disp_send_[i+1] = n_ptcl_disp_send_[i] + n_ptcl_send_[i];
1077 static PS::ReallocatableArray<MPI_Request> req_send;
1078 static PS::ReallocatableArray<MPI_Status> stat_send;
1079 req_send.resizeNoInitialize(n_proc);
1080 stat_send.resizeNoInitialize(n_proc);
1081 for(
PS::S32 i=0; i<rank_send_ptcl_.size(); i++){
1082 PS::S32 rank = rank_send_ptcl_[i];
1083 MPI_Isend(ptcl_send_.getPointer(n_ptcl_disp_send_[i]), n_ptcl_send_[i],
1084 PS::GetDataType<PtclComm>(),
1085 rank, 2136, MPI_COMM_WORLD, req_send.getPointer(i));
1095 rank_recv_ptcl_.clearSize();
1096 n_ptcl_recv_.clearSize();
1097 for(
PS::S32 i0=0; i0<n_proc; i0++){
1098 if(i0 == my_rank)
continue;
1099 bool flag_recv =
false;
1100 n_ptcl_recv_.push_back(0);
1101 rank_recv_ptcl_.push_back(i0);
1102 for(
PS::S32 i1=n_cluster_recv_disp[i0]; i1<n_cluster_recv_disp[i0+1]; i1++){
1103 PS::S32 id_cluster = cluster_recv[i1].id_;
1104 for(
PS::S32 i2=0; i2<cluster_loc.size(); i2++){
1105 if(id_cluster == cluster_loc[i2].id_ && cluster_loc[i2].rank_ == my_rank){
1106 n_ptcl_recv_.back() += cluster_recv[i1].n_ptcl_stored_;
1112 n_ptcl_recv_.resizeNoInitialize(n_ptcl_recv_.size()-1);
1113 rank_recv_ptcl_.resizeNoInitialize(rank_recv_ptcl_.size()-1);
1118 n_ptcl_disp_recv_.resizeNoInitialize(n_ptcl_recv_.size()+1);
1119 n_ptcl_disp_recv_[0] = 0;
1120 for(
PS::S32 i=0; i<n_ptcl_recv_.size(); i++){
1121 n_ptcl_disp_recv_[i+1] = n_ptcl_disp_recv_[i] + n_ptcl_recv_[i];
1125 ptcl_recv_.resizeNoInitialize(n_ptcl_disp_recv_[n_ptcl_recv_.size()]);
1128 PS::Comm::sendIrecvV(ptcl_send_.getPointer(), rank_send_ptcl_.getPointer(), n_ptcl_send_.getPointer(), n_ptcl_disp_send_.getPointer(), rank_send_ptcl_.size(),
1129 ptcl_recv_.getPointer(), rank_recv_ptcl_.getPointer(), n_ptcl_recv_.getPointer(), n_ptcl_disp_recv_.getPointer(), rank_recv_ptcl_.size());
1132 static PS::ReallocatableArray<MPI_Request> req_recv;
1133 static PS::ReallocatableArray<MPI_Status> stat_recv;
1134 req_recv.resizeNoInitialize(n_proc);
1135 stat_recv.resizeNoInitialize(n_proc);
1136 for(
PS::S32 i=0; i<rank_recv_ptcl_.size(); i++){
1137 PS::S32 rank = rank_recv_ptcl_[i];
1138 MPI_Irecv(
ptcl_recv_.getPointer(n_ptcl_disp_recv_[i]), n_ptcl_recv_[i],
1139 PS::GetDataType<PtclComm>(),
1140 rank, 2136, MPI_COMM_WORLD, req_recv.getPointer(i));
1143 MPI_Waitall(rank_send_ptcl_.size(), req_send.getPointer(), stat_send.getPointer());
1144 MPI_Waitall(rank_recv_ptcl_.size(), req_recv.getPointer(), stat_recv.getPointer());
1159 template<
class Tsys,
class Tphard>
1160 void SendSinglePtcl(Tsys & _sys,
1161 PS::ReallocatableArray<Tphard> & _ptcl_hard){
1162 for(
PS::S32 i=0; i<ptcl_send_.size(); i++){
1163 PS::S32 adr = adr_sys_ptcl_send_[i];
1165 assert(_sys[adr].
id == ptcl_send_[i].
id);
1168 if(ptcl_send_[i].group_data.artificial.isSingle() || (ptcl_send_[i].group_data.artificial.isMember() && ptcl_send_[i].getParticleCMAddress()<0)) {
1169 ptcl_send_[i].DataCopy(_sys[adr]);
1174 PS::Comm::sendIrecvV(ptcl_send_.getPointer(), rank_send_ptcl_.getPointer(), n_ptcl_send_.getPointer(), n_ptcl_disp_send_.getPointer(), rank_send_ptcl_.size(),
1175 ptcl_recv_.getPointer(), rank_recv_ptcl_.getPointer(), n_ptcl_recv_.getPointer(), n_ptcl_disp_recv_.getPointer(), rank_recv_ptcl_.size());
1178 static PS::ReallocatableArray<MPI_Request> req_send;
1179 static PS::ReallocatableArray<MPI_Status> stat_send;
1180 static PS::ReallocatableArray<MPI_Request> req_recv;
1181 static PS::ReallocatableArray<MPI_Status> stat_recv;
1182 req_send.resizeNoInitialize(rank_send_ptcl_.size());
1183 stat_send.resizeNoInitialize(rank_send_ptcl_.size());
1184 req_recv.resizeNoInitialize(rank_recv_ptcl_.size());
1185 stat_recv.resizeNoInitialize(rank_recv_ptcl_.size());
1187 for(
PS::S32 i=0; i<rank_send_ptcl_.size(); i++){
1188 PS::S32 rank = rank_send_ptcl_[i];
1189 MPI_Isend(ptcl_send_.getPointer(n_ptcl_disp_send_[i]), n_ptcl_send_[i],
1190 PS::GetDataType<PtclComm>(),
1191 rank, 2239, MPI_COMM_WORLD, req_send.getPointer(i));
1193 for(
PS::S32 i=0; i<rank_recv_ptcl_.size(); i++){
1194 PS::S32 rank = rank_recv_ptcl_[i];
1195 MPI_Irecv(
ptcl_recv_.getPointer(n_ptcl_disp_recv_[i]), n_ptcl_recv_[i],
1196 PS::GetDataType<PtclComm>(),
1197 rank, 2239, MPI_COMM_WORLD, req_recv.getPointer(i));
1199 MPI_Waitall(rank_send_ptcl_.size(), req_send.getPointer(), stat_send.getPointer());
1200 MPI_Waitall(rank_recv_ptcl_.size(), req_recv.getPointer(), stat_recv.getPointer());
1204 const PS::S32 n = _ptcl_hard.size();
1206 const PS::S32 adr = _ptcl_hard[i].adr_org;
1207 if(adr <0 && (_ptcl_hard[i].group_data.artificial.isSingle() || (_ptcl_hard[i].group_data.artificial.isMember() && _ptcl_hard[i].getParticleCMAddress()<0) )){
1209 assert(
ptcl_recv_[-(adr+1)].
id == _ptcl_hard[i].
id );
1211 _ptcl_hard[i].DataCopy(
ptcl_recv_[-(adr+1)]);
1223 template<
class Tsys,
class Tphard>
1224 void SendPtcl(Tsys & _sys,
1225 PS::ReallocatableArray<Tphard> & _ptcl_hard){
1226 for(
PS::S32 i=0; i<ptcl_send_.size(); i++){
1227 PS::S32 adr = adr_sys_ptcl_send_[i];
1229 assert(_sys[adr].
id == ptcl_send_[i].
id);
1232 ptcl_send_[i].DataCopy(_sys[adr]);
1236 PS::Comm::sendIrecvV(ptcl_send_.getPointer(), rank_send_ptcl_.getPointer(), n_ptcl_send_.getPointer(), n_ptcl_disp_send_.getPointer(), rank_send_ptcl_.size(),
1237 ptcl_recv_.getPointer(), rank_recv_ptcl_.getPointer(), n_ptcl_recv_.getPointer(), n_ptcl_disp_recv_.getPointer(), rank_recv_ptcl_.size());
1240 static PS::ReallocatableArray<MPI_Request> req_send;
1241 static PS::ReallocatableArray<MPI_Status> stat_send;
1242 static PS::ReallocatableArray<MPI_Request> req_recv;
1243 static PS::ReallocatableArray<MPI_Status> stat_recv;
1244 req_send.resizeNoInitialize(rank_send_ptcl_.size());
1245 stat_send.resizeNoInitialize(rank_send_ptcl_.size());
1246 req_recv.resizeNoInitialize(rank_recv_ptcl_.size());
1247 stat_recv.resizeNoInitialize(rank_recv_ptcl_.size());
1249 for(
PS::S32 i=0; i<rank_send_ptcl_.size(); i++){
1250 PS::S32 rank = rank_send_ptcl_[i];
1251 MPI_Isend(ptcl_send_.getPointer(n_ptcl_disp_send_[i]), n_ptcl_send_[i],
1252 PS::GetDataType<PtclComm>(),
1253 rank, 2239, MPI_COMM_WORLD, req_send.getPointer(i));
1255 for(
PS::S32 i=0; i<rank_recv_ptcl_.size(); i++){
1256 PS::S32 rank = rank_recv_ptcl_[i];
1257 MPI_Irecv(
ptcl_recv_.getPointer(n_ptcl_disp_recv_[i]), n_ptcl_recv_[i],
1258 PS::GetDataType<PtclComm>(),
1259 rank, 2239, MPI_COMM_WORLD, req_recv.getPointer(i));
1261 MPI_Waitall(rank_send_ptcl_.size(), req_send.getPointer(), stat_send.getPointer());
1262 MPI_Waitall(rank_recv_ptcl_.size(), req_recv.getPointer(), stat_recv.getPointer());
1266 const PS::S32 n = _ptcl_hard.size();
1268 const PS::S32 adr = _ptcl_hard[i].adr_org;
1271 assert(
ptcl_recv_[-(adr+1)].
id == _ptcl_hard[i].
id );
1273 _ptcl_hard[i].DataCopy(
ptcl_recv_[-(adr+1)]);
1284 template<
class Tsys,
class Tphard>
1285 void writeAndSendBackPtcl(Tsys & _sys,
1286 const PS::ReallocatableArray<Tphard> & _ptcl_hard,
1287 PS::ReallocatableArray<PS::S32> &_mass_modify_list) {
1290 const PS::S32 n = _ptcl_hard.size();
1292 const PS::S32 adr = _ptcl_hard[i].adr_org;
1295 assert( _sys[adr].
id == _ptcl_hard[i].
id);
1297 #ifdef STELLAR_EVOLUTION
1298 PS::F64 mass_bk = _sys[adr].group_data.artificial.isMember()? _sys[adr].group_data.artificial.getMassBackup(): _sys[adr].mass;
1299 assert(mass_bk!=0.0);
1301 _sys[adr].DataCopy(_ptcl_hard[i]);
1302 #ifdef STELLAR_EVOLUTION
1303 _sys[adr].dm = _sys[adr].mass - mass_bk;
1304 if (_sys[adr].dm!=0.0) _mass_modify_list.push_back(adr);
1306 assert(!std::isinf(_sys[adr].pos[0]));
1307 assert(!std::isnan(_sys[adr].pos[0]));
1308 assert(!std::isinf(_sys[adr].vel[0]));
1309 assert(!std::isnan(_sys[adr].vel[0]));
1313 ptcl_recv_[-(adr+1)].DataCopy(_ptcl_hard[i]);
1318 PS::Comm::sendIrecvV(
ptcl_recv_.getPointer(), rank_recv_ptcl_.getPointer(), n_ptcl_recv_.getPointer(), n_ptcl_disp_recv_.getPointer(), rank_recv_ptcl_.size(),
1319 ptcl_send_.getPointer(), rank_send_ptcl_.getPointer(), n_ptcl_send_.getPointer(), n_ptcl_disp_send_.getPointer(), rank_send_ptcl_.size());
1322 static PS::ReallocatableArray<MPI_Request> req_recv;
1323 static PS::ReallocatableArray<MPI_Status> stat_recv;
1324 static PS::ReallocatableArray<MPI_Request> req_send;
1325 static PS::ReallocatableArray<MPI_Status> stat_send;
1326 req_recv.resizeNoInitialize(rank_recv_ptcl_.size());
1327 stat_recv.resizeNoInitialize(rank_recv_ptcl_.size());
1328 req_send.resizeNoInitialize(rank_send_ptcl_.size());
1329 stat_send.resizeNoInitialize(rank_send_ptcl_.size());
1331 for(
PS::S32 i=0; i<rank_recv_ptcl_.size(); i++){
1332 PS::S32 rank = rank_recv_ptcl_[i];
1333 MPI_Isend(
ptcl_recv_.getPointer(n_ptcl_disp_recv_[i]), n_ptcl_recv_[i],
1334 PS::GetDataType<PtclComm>(),
1335 rank, 2303, MPI_COMM_WORLD, req_recv.getPointer(i));
1337 for(
PS::S32 i=0; i<rank_send_ptcl_.size(); i++){
1338 PS::S32 rank = rank_send_ptcl_[i];
1339 MPI_Irecv(ptcl_send_.getPointer(n_ptcl_disp_send_[i]), n_ptcl_send_[i],
1340 PS::GetDataType<PtclComm>(),
1341 rank, 2303, MPI_COMM_WORLD, req_send.getPointer(i));
1343 MPI_Waitall(rank_send_ptcl_.size(), req_send.getPointer(), stat_send.getPointer());
1344 MPI_Waitall(rank_recv_ptcl_.size(), req_recv.getPointer(), stat_recv.getPointer());
1347 for(
PS::S32 i=0; i<ptcl_send_.size(); i++){
1348 PS::S32 adr = adr_sys_ptcl_send_[i];
1350 assert(_sys[adr].
id == ptcl_send_[i].
id);
1352 #ifdef STELLAR_EVOLUTION
1353 PS::F64 mass_bk = _sys[adr].group_data.artificial.isMember()? _sys[adr].group_data.artificial.getMassBackup(): _sys[adr].mass;
1355 _sys[adr].DataCopy(ptcl_send_[i]);
1356 #ifdef STELLAR_EVOLUTION
1357 _sys[adr].dm = _sys[adr].mass - mass_bk;
1358 if (_sys[adr].dm!=0.0) _mass_modify_list.push_back(adr);
1360 assert(!std::isinf(_sys[adr].pos[0]));
1361 assert(!std::isnan(_sys[adr].pos[0]));
1362 assert(!std::isinf(_sys[adr].vel[0]));
1363 assert(!std::isnan(_sys[adr].vel[0]));
1372 return adr_sys_one_cluster_[0];
1377 return adr_sys_ptcl_send_;