Exemple #1
0
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)); 
}