MFEM v2.0
|
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