コード例 #1
0
ファイル: ex14.cpp プロジェクト: rainiscold/trilinos
    TridiagonalCrsMatrix(
        const Epetra_Map & Map,
        double a,
        double diag,
        double c
    ) :
        Epetra_CrsMatrix(Copy,Map,3)
    {
        // global number of rows
        int NumGlobalElements = Map.NumGlobalElements();
        // local number of rows
        int NumMyElements = Map.NumMyElements();
        // get update list
        int * MyGlobalElements = new int [NumMyElements];
        Map.MyGlobalElements( MyGlobalElements );

        // Add  rows one-at-a-time
        // Need some vectors to help
        // Off diagonal Values will always be -1

        double *Values = new double[2];
        Values[0] = a;
        Values[1] = c;
        int *Indices = new int[2];
        int NumEntries;

        for( int i=0 ; i<NumMyElements; ++i ) {
            if (MyGlobalElements[i]==0) {
                Indices[0] = 1;
                NumEntries = 1;
            } else if (MyGlobalElements[i] == NumGlobalElements-1) {
                Indices[0] = NumGlobalElements-2;
                NumEntries = 1;
            } else {
                Indices[0] = MyGlobalElements[i]-1;
                Indices[1] = MyGlobalElements[i]+1;
                NumEntries = 2;
            }
            InsertGlobalValues(MyGlobalElements[i], NumEntries, Values, Indices);
            // Put in the diagonal entry
            InsertGlobalValues(MyGlobalElements[i], 1, &diag, MyGlobalElements+i);
        }

        // Finish up
        FillComplete();

        delete [] MyGlobalElements;
        delete [] Values;
        delete [] Indices;
    }
コード例 #2
0
int Epetra_FEVbrMatrix::GlobalAssemble(bool callFillComplete) 
{
  if(Map().Comm().NumProc() < 2 || ignoreNonLocalEntries_) {
    if(callFillComplete) {
      EPETRA_CHK_ERR(FillComplete());
    }

    return(0);
  }

  int i;

  //In this method we need to gather all the non-local (overlapping) data
  //that's been input on each processor, into the
  //non-overlapping distribution defined by the map that 'this' matrix was
  //constructed with.

  //Need to build a map that describes our nonlocal data.

  //First, create a list of the sizes (point-rows per block-row) of the
  //nonlocal rows we're holding.
  int* pointRowsPerNonlocalBlockRow = numNonlocalBlockRows_>0 ?
    new int[numNonlocalBlockRows_] : NULL;

  for(i=0; i<numNonlocalBlockRows_; ++i) {
    pointRowsPerNonlocalBlockRow[i] = nonlocalCoefs_[i][0]->M();
  }

  //We'll use the arbitrary distribution constructor of BlockMap.

  Epetra_BlockMap sourceMap(-1, numNonlocalBlockRows_, nonlocalBlockRows_, // CJ TODO FIXME long long
          pointRowsPerNonlocalBlockRow,
          RowMap().IndexBase(), RowMap().Comm());

  delete [] pointRowsPerNonlocalBlockRow;

  //If sourceMap has global size 0, then no nonlocal data exists and we can
  //skip most of this function.
  if(sourceMap.NumGlobalElements64() < 1) {
    if(callFillComplete) {
      EPETRA_CHK_ERR(FillComplete());
    }
    return(0);
  }

  //We also need to build a column-map, containing the columns in our
  //nonlocal data. To do that, create a list of all column-indices that
  //occur in our nonlocal rows.

  int numCols = 0, allocLen = 0;
  int* cols = NULL;
  int* pointColsPerBlockCol = NULL;
  int ptColAllocLen = 0;
  int insertPoint = -1;

  for(i=0; i<numNonlocalBlockRows_; ++i) {
    for(int j=0; j<nonlocalBlockRowLengths_[i]; ++j) {
      int col = nonlocalBlockCols_[i][j];
      int offset = Epetra_Util_binary_search(col, cols, numCols, insertPoint);
      if (offset < 0) {
  EPETRA_CHK_ERR( Epetra_Util_insert(col, insertPoint, cols,
             numCols, allocLen) );
  int tmpNumCols = numCols-1;
  EPETRA_CHK_ERR( Epetra_Util_insert(nonlocalCoefs_[i][j]->N(),
             insertPoint,
             pointColsPerBlockCol,
             tmpNumCols, ptColAllocLen) );
      }
    }
  }

  Epetra_BlockMap colMap(-1, numCols, cols, // CJ TODO FIXME long long
       pointColsPerBlockCol,
       RowMap().IndexBase(), RowMap().Comm());

  delete [] cols;
  delete [] pointColsPerBlockCol;
  numCols = 0;
  allocLen = 0;

  //now we need to create a matrix with sourceMap and colMap, and fill it with
  //our nonlocal data so we can then export it to the correct owning
  //processors.

  Epetra_VbrMatrix tempMat(Copy, sourceMap, colMap, nonlocalBlockRowLengths_);


  //Next we need to make sure the 'indices-are-global' attribute of tempMat's
  //graph is set to true, in case this processor doesn't end up calling the
  //InsertGlobalValues method...

  const Epetra_CrsGraph& graph = tempMat.Graph();
  Epetra_CrsGraph& nonconst_graph = const_cast<Epetra_CrsGraph&>(graph);
  nonconst_graph.SetIndicesAreGlobal(true);

  for(i=0; i<numNonlocalBlockRows_; ++i) {
    EPETRA_CHK_ERR( tempMat.BeginInsertGlobalValues(nonlocalBlockRows_[i],
                nonlocalBlockRowLengths_[i],
                nonlocalBlockCols_[i]) );

    for(int j=0; j<nonlocalBlockRowLengths_[i]; ++j) {
      Epetra_SerialDenseMatrix& subblock = *(nonlocalCoefs_[i][j]);

      EPETRA_CHK_ERR( tempMat.SubmitBlockEntry(subblock.A(),
                 subblock.LDA(),
                 subblock.M(),
                 subblock.N()) );
    }

    EPETRA_CHK_ERR( tempMat.EndSubmitEntries() );
  }

  //Now we need to call FillComplete on our temp matrix. We need to
  //pass a DomainMap and RangeMap, which are not the same as the RowMap
  //and ColMap that we constructed the matrix with.
  EPETRA_CHK_ERR(tempMat.FillComplete(RowMap(), sourceMap));

  //Finally, we're ready to create the exporter and export non-local data to
  //the appropriate owning processors.

  Epetra_Export exporter(sourceMap, RowMap());

  EPETRA_CHK_ERR( Export(tempMat, exporter, Add) );

  if(callFillComplete) {
    EPETRA_CHK_ERR(FillComplete());
  }

  destroyNonlocalData();

  return(0);
}
コード例 #3
0
int Epetra_FECrsMatrix::GlobalAssemble(const Epetra_Map& domain_map,
                                       const Epetra_Map& range_map,
                                       bool callFillComplete,
                                       Epetra_CombineMode combineMode,
                                       bool save_off_and_reuse_map_exporter)
{
  if (Map().Comm().NumProc() < 2 || ignoreNonLocalEntries_) {
    if (callFillComplete) {
      EPETRA_CHK_ERR( FillComplete(domain_map, range_map) );
    }
    return(0);
  }

  std::vector<int_type>& nonlocalRows_var = nonlocalRows<int_type>();
  std::vector<std::vector<int_type> >& nonlocalCols_var = nonlocalCols<int_type>();

  if (useNonlocalMatrix_) {
    tempMat_ = nonlocalMatrix_;
  }
  else {
    //In this method we need to gather all the non-local (overlapping) data
    //that's been input on each processor, into the
    //non-overlapping distribution defined by the map that 'this' matrix was
    //constructed with.

    //First build a map that describes our nonlocal data.
    //We'll use the arbitrary distribution constructor of Map.

    int_type* nlr_ptr = nonlocalRows_var.size() > 0 ? &nonlocalRows_var[0] : 0;
    if (sourceMap_ == NULL)
      sourceMap_ = new Epetra_Map((int_type) -1, (int) nonlocalRows_var.size(), nlr_ptr,
            (int_type) Map().IndexBase64(), Map().Comm());

    //If sourceMap has global size 0, then no nonlocal data exists and we can
    //skip most of this function.
    if (sourceMap_->NumGlobalElements64() < 1) {
      if (callFillComplete) {
        EPETRA_CHK_ERR( FillComplete(domain_map, range_map) );
      }
      if (!save_off_and_reuse_map_exporter) {
        delete sourceMap_;
        sourceMap_ = NULL;
      }
      return(0);
    }

    //We also need to build a column-map, containing the columns in our
    //nonlocal data. To do that, create a list of all column-indices that
    //occur in our nonlocal rows.
    bool first_time=!save_off_and_reuse_map_exporter;
    if ( colMap_ == NULL ) {
      first_time = true;
      std::vector<int_type> cols;

      for(size_t i=0; i<nonlocalRows_var.size(); ++i) {
        for(size_t j=0; j<nonlocalCols_var[i].size(); ++j) {
          int_type col = nonlocalCols_var[i][j];
          typename std::vector<int_type>::iterator it =
            std::lower_bound(cols.begin(), cols.end(), col);
          if (it == cols.end() || *it != col) {
            cols.insert(it, col);
          }
        }
      }

      int_type* cols_ptr = cols.size() > 0 ? &cols[0] : 0;

      colMap_ = new Epetra_Map((int_type) -1, (int) cols.size(), cols_ptr,
                               (int_type) Map().IndexBase64(), Map().Comm());
    }
    //now we need to create a matrix with sourceMap and colMap, and fill it with
    //our nonlocal data so we can then export it to the correct owning processors.

    std::vector<int> nonlocalRowLengths(nonlocalRows_var.size());
    for(size_t i=0; i<nonlocalRows_var.size(); ++i) {
      nonlocalRowLengths[i] = (int) nonlocalCols_var[i].size();
    }

    int* nlRLptr = nonlocalRowLengths.size()>0 ? &nonlocalRowLengths[0] : NULL;
    if ( first_time && tempMat_ == NULL )
      tempMat_ = new Epetra_CrsMatrix(Copy, *sourceMap_, *colMap_, nlRLptr);
    else
      tempMat_->PutScalar(0.);

    for(size_t i=0; i<nonlocalRows_var.size(); ++i) {
      if ( first_time ) {
        EPETRA_CHK_ERR( tempMat_->InsertGlobalValues(nonlocalRows_var[i],
                                                    (int) nonlocalCols_var[i].size(),
                                                    &nonlocalCoefs_[i][0],
                                                    &nonlocalCols_var[i][0]) );
      } else {
        EPETRA_CHK_ERR( tempMat_->SumIntoGlobalValues(nonlocalRows_var[i],
                                                     (int) nonlocalCols_var[i].size(),
                                                     &nonlocalCoefs_[i][0],
                                                     &nonlocalCols_var[i][0]) );
      }
    }

    if (!save_off_and_reuse_map_exporter) {
      delete sourceMap_;
      delete colMap_;
      sourceMap_ = colMap_ = NULL;
    }

    //Next we need to make sure the 'indices-are-global' attribute of tempMat's
    //graph is set to true, in case this processor doesn't end up calling the
    //InsertGlobalValues method...

    if (first_time) {
      const Epetra_CrsGraph& graph = tempMat_->Graph();
      Epetra_CrsGraph& nonconst_graph = const_cast<Epetra_CrsGraph&>(graph);
      nonconst_graph.SetIndicesAreGlobal(true);
	}
	}
      //Now we need to call FillComplete on our temp matrix. We need to
      //pass a DomainMap and RangeMap, which are not the same as the RowMap
      //and ColMap that we constructed the matrix with.
      EPETRA_CHK_ERR(tempMat_->FillComplete(domain_map, range_map));

    if (exporter_ == NULL)
      exporter_ = new Epetra_Export(tempMat_->RowMap(), RowMap());

    EPETRA_CHK_ERR(Export(*tempMat_, *exporter_, combineMode));

    if(callFillComplete) {
      EPETRA_CHK_ERR(FillComplete(domain_map, range_map));
    }

    //now reset the values in our nonlocal data
    if (!useNonlocalMatrix_) {
      for(size_t i=0; i<nonlocalRows_var.size(); ++i) {
        nonlocalCols_var[i].resize(0);
        nonlocalCoefs_[i].resize(0);
      }
    }

  if (!save_off_and_reuse_map_exporter) {
    delete exporter_;
    exporter_ = NULL;
    if (!useNonlocalMatrix_)
      delete tempMat_;
    tempMat_ = NULL;
  }
  return(0);
}