Ejemplo n.º 1
0
void TrilinosFEVbrMatrix::get_values(BlockAccumulator& values)
{
  cf3_assert(m_is_created);
  Epetra_SerialDenseMatrix **val;
  int* colindices;
  int blockrowsize;
  int dummyneq;
  int hits=0;
  const int numblocks=values.indices.size();
  const int rowoffset=(numblocks-1)*m_neq;
  const int neqneq=m_neq*m_neq;
  if (m_converted_indices.size()<numblocks) m_converted_indices.resize(numblocks);
  for (int i=0; i<(const int)numblocks; i++) m_converted_indices[i]=m_p2m[values.indices[i]];
  int* idxs=(int*)&m_converted_indices[0];
  values.mat.setConstant(0.);
  for (int irow=0; irow<(const int)numblocks; irow++)
  {
    if (idxs[irow]<m_blockrow_size)
    {
      hits=0;
      TRILINOS_ASSERT(m_mat->ExtractMyBlockRowView(idxs[irow],dummyneq,blockrowsize,colindices,val));
      for (int j=0; j<(const int)blockrowsize; j++)
      {
        for (int icol=0; icol<(const int)numblocks; icol++)
          if (colindices[j]==idxs[icol])
          {
            double *emv=val[j][0].A();
            int col_idx = icol*m_neq;
            for (double* l=emv; emv<(const double*)(l+neqneq); ++col_idx)
            {
              int row_idx = irow*m_neq;
              for (double* m=emv; emv<(const double*)(m+m_neq);)
                values.mat(row_idx++, col_idx) = *emv++;
            }

            hits++;
            //break; // this is arguable, can be that the blockaccumulator fills to the same id more than once (repetitive same id entries in values.indices)
          }
        if (hits==numblocks) break;
      }
    }
  }
}
Ejemplo n.º 2
0
void TrilinosCrsMatrix::get_values(BlockAccumulator& values)
{
  cf3_assert(m_is_created);
  values.mat.setZero();
  const Uint nb_nodes = values.indices.size();
  const int num_entries = nb_nodes*m_neq;
  int extracted_num_entries;
  Real* extracted_values;
  int* extracted_indices;
  cf3_assert(values.mat.rows() == num_entries);
  std::map<int, int> reverse_idx_map;
  // Convert the index vector
  for(Uint i = 0; i != nb_nodes; ++i)
  {
    const Uint local_start_idx = values.indices[i]*m_neq;
    for(int j = 0; j != m_neq; ++j)
    {
      m_converted_indices[i*m_neq+j] = m_p2m[local_start_idx+j];
      reverse_idx_map[m_p2m[local_start_idx+j]] = i*m_neq + j;
    }
  }
  // get the values
  for(Uint i = 0; i != nb_nodes; ++i)
  {
    for(int j = 0; j != m_neq; ++j)
    {
      if(m_converted_indices[i*m_neq+j] >= m_num_my_elements)
        continue;
      TRILINOS_THROW(m_mat->ExtractMyRowView(m_converted_indices[i*m_neq+j], extracted_num_entries, extracted_values, extracted_indices));
      for(int k = 0; k != extracted_num_entries; ++k)
      {
        const std::map<int,int>::const_iterator it = reverse_idx_map.find(extracted_indices[k]);
        if(it != reverse_idx_map.end())
          values.mat(i*m_neq+j, it->second) = extracted_values[k];
      }
    }
  }
}
Ejemplo n.º 3
0
void TrilinosMatrix::add_values(const BlockAccumulator& values)
{
/* TRILINOS-ADVICED
  cf3_assert(m_is_created);
  const int numblocks=values.indices.size();
  if (m_converted_indices.size()<numblocks) m_converted_indices.resize(numblocks);
  for (int i=0; i<(const int)numblocks; i++) m_converted_indices[i]=m_p2m[values.indices[i]];
  int* idxs=(int*)&m_converted_indices[0];
  for (int irow=0; irow<(const int)numblocks; irow++)
    if (idxs[irow]<m_blockrow_size)
    {
      TRILINOS_ASSERT(m_mat->BeginSumIntoMyValues(idxs[irow],numblocks,idxs));
      for (int icol=0; icol<numblocks; icol++)
        TRILINOS_ASSERT(m_mat->SubmitBlockEntry((double*)values.mat.data()+irow*m_neq+icol*m_neq*m_neq*numblocks,numblocks*m_neq,m_neq,m_neq));
      TRILINOS_ASSERT(m_mat->EndSubmitEntries());
    }
*/
/* MANUAL FILL
  cf3_assert(m_is_created);
  Epetra_SerialDenseMatrix **val;
  int* colindices;
  int blockrowsize;
  int dummyneq;
  int hits=0;
  const int numblocks=values.indices.size();
  if (m_converted_indices.size()<numblocks) m_converted_indices.resize(numblocks);
  for (int i=0; i<(const int)numblocks; i++) m_converted_indices[i]=m_p2m[values.indices[i]];
  int* idxs=(int*)&m_converted_indices[0];
  for (int irow=0; irow<(const int)numblocks; irow++)
  {
    if (idxs[irow]<m_blockrow_size)
    {
      TRILINOS_ASSERT(m_mat->ExtractMyBlockRowView(idxs[irow],dummyneq,blockrowsize,colindices,val));
      for (int j=0; j<(const int)blockrowsize; j++)
        for (int k=0; k<(const int)numblocks; k++)
          if (colindices[j]==idxs[k])
            for (int l=0; l<(const int)m_neq; l++)
              for (int m=0; m<(const int)m_neq; m++)
                val[j][0](l,m)+=values.mat(irow*m_neq+l,k*m_neq+m);
      hits++;
      if (hits==numblocks) break;
    }
  }
*/
/* FINAL OPTIMIZED */
  cf3_assert(m_is_created);
  Epetra_SerialDenseMatrix **val;
  int* colindices;
  int blockrowsize;
  int dummyneq;
  int hits=0;
  const int numblocks=values.indices.size();
  const int rowoffset=(numblocks-1)*m_neq;
  const int neqneq=m_neq*m_neq;
  if (m_converted_indices.size()<numblocks) m_converted_indices.resize(numblocks);
  for (int i=0; i<(const int)numblocks; i++) m_converted_indices[i]=m_p2m[values.indices[i]];
  int* idxs=(int*)&m_converted_indices[0];
  for (int irow=0; irow<(const int)numblocks; irow++)
  {
    if (idxs[irow]<m_blockrow_size)
    {
      hits=0;
      TRILINOS_ASSERT(m_mat->ExtractMyBlockRowView(idxs[irow],dummyneq,blockrowsize,colindices,val));
      for (int j=0; j<(const int)blockrowsize; j++)
      {
        for (int icol=0; icol<(const int)numblocks; icol++)
          if (colindices[j]==idxs[icol])
          {
            double *emv=val[j][0].A();
            double *bav=(double*)&values.mat(irow*m_neq,icol*m_neq);
            for (double* l=emv; emv<(const double*)(l+neqneq); bav+=rowoffset)
              for (double* m=emv; emv<(const double*)(m+m_neq);)
                *emv++ += *bav++;

            hits++;
            //break; // this is arguable, can be that the blockaccumulator fills to the same id more than once (repetitive same id entries in values.indices)
          }
        if (hits==numblocks) break;
      }
    }
  }
}