CLDS2_Database::SLDS2_DbConnection& CLDS2_Database::x_GetDbConnection(void) const { if ( !m_DbConn ) { m_DbConn.Reset(new TDbConnectionsTls); } SLDS2_DbConnection* db_conn = m_DbConn->GetValue(); if ( !db_conn ) { auto_ptr<SLDS2_DbConnection> conn_ptr(new SLDS2_DbConnection); db_conn = conn_ptr.get(); m_DbConn->SetValue(conn_ptr.release(), sx_DbConn_Cleanup, 0); } return *db_conn; }
void Pane_ghost_connectivity:: finalize_pconn(vector<vector<map<pair<int,int>,int> > > &nodes_to_send, vector<vector<map<pair<int,int>,int> > > &nodes_to_recv, vector<vector<deque<int> > > &elems_to_send, vector<vector<int> > &elem_renumbering, vector<pane_i_vector> &recv_info){ map<pair<int,int>,int>::iterator rns_pos,gnr_pos; vector<vector<int> > node_pos; // Buff for #elmts to recv from each incident pane vector<vector<int> > n_elem; // Get the name of the buffer window string buf_name(_buf_window->name()); // Save ptrs to conn tables so we don't have to look up // as each element's connectivity is registered vector<vector<int*> > conn_ptr(_npanes); node_pos.resize(_npanes); n_elem.resize(_npanes); // Determine buffer space required: // 1 (#comm panes) + 2 per adj pane (comm pane id and #entities) // + total #entries in entity list (ie node lists for nodes to receive) for(int i=0; i< _npanes; ++i){ int gcr_size =1, rcs_size =1, gnr_size =1, rns_size = 1; int n_comm_panes = _cpanes[i].size(); int pane_id = _panes[i]->id(); // Real nodes to send for(int j=0, nj = nodes_to_send[i].size(); j<nj; ++j) rns_size += 2+nodes_to_send[i][j].size(); // Ghost nodes to receive for(int j=0, nj = nodes_to_recv[i].size(); j<nj; ++j) gnr_size += 2+nodes_to_recv[i][j].size(); // Real cells to send for(int j=0, nj = (int)elems_to_send[i].size(); j<nj; ++j) rcs_size += 2+elems_to_send[i][j].size(); // Ghost cells to receive n_elem[i].resize(n_comm_panes,0); for(int j=0, nj = (int)_cpanes[i].size(); j<nj; ++j){ gcr_size += 2; for(int ind=0, size = (int)recv_info[i][j].size(); ind < size; ind += 1+2*Connectivity::size_of_nodes_pe(recv_info[i][j][ind])){ gcr_size++; n_elem[i][j]++; } } node_pos[i].assign(elem_renumbering[i].begin(),elem_renumbering[i].end()); // Make room for pointers to all potential connectivity tables conn_ptr[i].resize(Connectivity::TYPE_MAX_CONN,NULL); // Resize connectivity tables for(int j=0; j<Connectivity::TYPE_MAX_CONN; ++j){ int nelems = elem_renumbering[i][j+1]; elem_renumbering[i][j+1] += elem_renumbering[i][j]; if(nelems >0){ const string conn_name = _etype_str[j]+"virtual"; int nnodes = Connectivity::size_of_nodes_pe(j); // Resize connectivity table and keep a pointer to its buffer void* addr; _buf_window->set_size(conn_name.c_str(), pane_id, nelems,nelems); _buf_window->resize_array(conn_name.c_str(), pane_id, &addr,nnodes,nelems); conn_ptr[i][j] = (int*)addr; COM_assertion_msg(addr!= NULL, "Could not allocate space for connectivity table"); } } // Resize pconn Attribute *pconn = NULL; pconn = _panes[i]->attribute(COM::COM_PCONN); int rsize = pconn->size_of_real_items(); int gsize = rns_size + gnr_size + rcs_size + gcr_size; void *addr; _buf_window->set_size("pconn", pane_id, rsize+gsize,gsize); _buf_window->resize_array("pconn",pane_id,&addr); pconn = _panes[i]->attribute(COM::COM_PCONN); int* pconn_ptr = (int*)addr; int rns_ind = rsize; int gnr_ind = rns_ind + rns_size; int rcs_ind = gnr_ind + gnr_size; int gcr_ind = rcs_ind + rcs_size; // each block begins w/ # of communicating blocks pconn_ptr[rns_ind++] = n_comm_panes; pconn_ptr[gnr_ind++] = n_comm_panes; pconn_ptr[rcs_ind++] = n_comm_panes; pconn_ptr[gcr_ind++] = n_comm_panes; // Offset to start of ghost element_ids int real_offset = _panes[i]->size_of_real_elements()+1; // My current implementation only sends nodes to panes w/ a ghost // copy of a local element, so there are the same number of communicating // panes in each pconn block. // If the code is generalized in the future, there may need to be // separate loops for some pconn blocks. for(int j=0; j <n_comm_panes; ++j){ // Write communicating-pane id to buffer int comm_pane_id = _cpanes[i][j]; pconn_ptr[rns_ind++] = comm_pane_id; pconn_ptr[gnr_ind++] = comm_pane_id; pconn_ptr[rcs_ind++] = comm_pane_id; pconn_ptr[gcr_ind++] = comm_pane_id; // Write number of enties to buffer pconn_ptr[rns_ind++] = nodes_to_send[i][j].size(); pconn_ptr[gnr_ind++] = nodes_to_recv[i][j].size(); pconn_ptr[rcs_ind++] = elems_to_send[i][j].size(); pconn_ptr[gcr_ind++] = n_elem[i][j]; // Write entities to ghost pconn buffers for(rns_pos = nodes_to_send[i][j].begin(); rns_pos != nodes_to_send[i][j].end(); ++rns_pos) pconn_ptr[rns_ind++] = rns_pos->second; for(gnr_pos = nodes_to_recv[i][j].begin(); gnr_pos != nodes_to_recv[i][j].end(); ++gnr_pos) pconn_ptr[gnr_ind++] = gnr_pos->second; for(int k=0, nk = (int)elems_to_send[i][j].size(); k<nk; ++k) pconn_ptr[rcs_ind++] = elems_to_send[i][j][k]; // The GCR block is more complicated because we want all ghost elements // of a single type to have contiguous element ids, which is required // by Roccom if we want to register one connectivity table per type int recv_size = recv_info[i][j].size(); int index = 0; while(index < recv_size){ int elem_type = recv_info[i][j][index]; int nnodes = Connectivity::size_of_nodes_pe(elem_type); // id offset within the correct connectivity table int conn_offset = node_pos[i][elem_type]++; pconn_ptr[gcr_ind++] = real_offset + elem_renumbering[i][elem_type]++; // Write out ghost element's nodes for(int k=1; k <= 2*nnodes; k+=2){ map<pair<int,int>,int>::iterator pos; pos = _local_nodes[i]. find(make_pair(recv_info[i][j][index+k], recv_info[i][j][index+k+1])); COM_assertion(pos != _local_nodes[i].end()); conn_ptr[i][elem_type][nnodes*conn_offset+(k-1)/2] = pos->second; } index += 2*nnodes+1; } } int new_size = _local_nodes[i].size(); int new_gsize = new_size - _panes[i]->size_of_real_nodes(); // 1) Extend nodal coords to accommodate ghost nodes _buf_window-> set_size("nc", pane_id, new_size, new_gsize); _buf_window->resize_array("nc", pane_id, &addr,3); } // 4) Update ghost nodal coordinates using newly constructed pconn MAP::Rocmap::update_ghosts(_buf_window->attribute(COM::COM_NC)); }