MFEM v2.0
pbilinearform.cpp
Go to the documentation of this file.
00001 // Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
00002 // the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
00003 // reserved. See file COPYRIGHT for details.
00004 //
00005 // This file is part of the MFEM library. For more information and source code
00006 // availability see http://mfem.googlecode.com.
00007 //
00008 // MFEM is free software; you can redistribute it and/or modify it under the
00009 // terms of the GNU Lesser General Public License (as published by the Free
00010 // Software Foundation) version 2.1 dated February 1999.
00011 
00012 #ifdef MFEM_USE_MPI
00013 
00014 #include "fem.hpp"
00015 
00016 HypreParMatrix *ParBilinearForm::ParallelAssemble(SparseMatrix *m)
00017 {
00018    if (m == NULL)
00019       return NULL;
00020 
00021    // construct a parallel block-diagonal wrapper matrix A based on m
00022    HypreParMatrix *A = new HypreParMatrix(pfes->GlobalVSize(),
00023                                           pfes->GetDofOffsets(), m);
00024 
00025    HypreParMatrix *rap = RAP(A, pfes->Dof_TrueDof_Matrix());
00026 
00027    delete A;
00028 
00029    return rap;
00030 }
00031 
00032 HypreParMatrix *ParDiscreteLinearOperator::ParallelAssemble(SparseMatrix *m)
00033 {
00034    if (m == NULL)
00035       return NULL;
00036 
00037    int *I = m->GetI();
00038    int *J = m->GetJ();
00039    double *data = m->GetData();
00040 
00041    // remap to tdof local row and tdof global column indices
00042    SparseMatrix local(range_fes->TrueVSize(), domain_fes->GlobalTrueVSize());
00043    for (int i = 0; i < m->Size(); i++)
00044    {
00045       int lti = range_fes->GetLocalTDofNumber(i);
00046       if (lti >= 0)
00047          for (int j = I[i]; j < I[i+1]; j++)
00048             local.Set(lti, domain_fes->GetGlobalTDofNumber(J[j]), data[j]);
00049    }
00050    local.Finalize();
00051 
00052    // construct and return a global ParCSR matrix by splitting the local matrix
00053    // into diag and offd parts
00054    return new HypreParMatrix(range_fes->GetComm(),
00055                              range_fes->TrueVSize(),
00056                              range_fes->GlobalTrueVSize(),
00057                              domain_fes->GlobalTrueVSize(),
00058                              local.GetI(), local.GetJ(), local.GetData(),
00059                              range_fes->GetTrueDofOffsets(),
00060                              domain_fes->GetTrueDofOffsets());
00061 }
00062 
00063 void ParDiscreteLinearOperator::GetParBlocks(Array2D<HypreParMatrix *> &blocks) const
00064 {
00065    int rdim = range_fes->GetVDim();
00066    int ddim = domain_fes->GetVDim();
00067 
00068    blocks.SetSize(rdim, ddim);
00069 
00070    int i, j, n;
00071 
00072    // construct the scalar versions of the row/coll offset arrays
00073    int *row_starts, *col_starts;
00074    if (HYPRE_AssumedPartitionCheck())
00075       n = 2;
00076    else
00077       n = range_fes->GetNRanks()+1;
00078    row_starts = new int[n];
00079    col_starts = new int[n];
00080    for (i = 0; i < n; i++)
00081    {
00082       row_starts[i] = (range_fes->GetTrueDofOffsets())[i] / rdim;
00083       col_starts[i] = (domain_fes->GetTrueDofOffsets())[i] / ddim;
00084    }
00085 
00086    Array2D<SparseMatrix *> lblocks;
00087    GetBlocks(lblocks);
00088 
00089    for (int bi = 0; bi < rdim; bi++)
00090       for (int bj = 0; bj < ddim; bj++)
00091       {
00092          int *I = lblocks(bi,bj)->GetI();
00093          int *J = lblocks(bi,bj)->GetJ();
00094          double *data = lblocks(bi,bj)->GetData();
00095 
00096          // remap to tdof local row and tdof global column indices
00097          SparseMatrix local(range_fes->TrueVSize()/rdim,
00098                             domain_fes->GlobalTrueVSize()/ddim);
00099          for (i = 0; i < lblocks(bi,bj)->Size(); i++)
00100          {
00101             int lti = range_fes->GetLocalTDofNumber(i);
00102             if (lti >= 0)
00103                for (j = I[i]; j < I[i+1]; j++)
00104                   local.Set(lti,
00105                             domain_fes->GetGlobalScalarTDofNumber(J[j]),
00106                             data[j]);
00107          }
00108          local.Finalize();
00109 
00110          delete lblocks(bi,bj);
00111 
00112          // construct and return a global ParCSR matrix by splitting the local
00113          // matrix into diag and offd parts
00114          blocks(bi,bj) = new HypreParMatrix(range_fes->GetComm(),
00115                                             range_fes->TrueVSize()/rdim,
00116                                             range_fes->GlobalTrueVSize()/rdim,
00117                                             domain_fes->GlobalTrueVSize()/ddim,
00118                                             local.GetI(), local.GetJ(), local.GetData(),
00119                                             row_starts, col_starts);
00120       }
00121 
00122    delete row_starts;
00123    delete col_starts;
00124 }
00125 
00126 #endif
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines