{"action":"created","comment":{"url":"https://api.github.com/repos/IBAMR/IBAMR/pulls/comments/29448738","id":29448738,"diff_hunk":"@@ -806,10 +596,731 @@ void PETScMatUtilities::constructPatchLevelSCInterpOp(Mat& mat,\n     return;\n } // constructPatchLevelSCInterpOp\n \n+void PETScMatUtilities::constructProlongationOp(Mat& mat,\n+                                                int dof_index_idx,\n+                                                const std::vector<int>& num_fine_dofs_per_proc,\n+                                                const std::vector<int>& num_coarse_dofs_per_proc,\n+                                                Pointer<PatchLevel<NDIM> > fine_patch_level,\n+                                                Pointer<PatchLevel<NDIM> > coarse_patch_level,\n+                                                const AO& coarse_level_ao,\n+                                                const int coarse_ao_offset)\n+{\n+    // Determine the data-centering type.\n+    VariableDatabase<NDIM>* var_db = VariableDatabase<NDIM>::getDatabase();\n+    Pointer<Variable<NDIM> > dof_index_var;\n+    var_db->mapIndexToVariable(dof_index_idx, dof_index_var);\n+    Pointer<CellVariable<NDIM, int> > dof_index_cc_var = dof_index_var;\n+    Pointer<SideVariable<NDIM, int> > dof_index_sc_var = dof_index_var;\n+    if (dof_index_cc_var)\n+    {\n+        constructProlongationOp_cell(mat, dof_index_idx, num_fine_dofs_per_proc, num_coarse_dofs_per_proc,\n+                                     fine_patch_level, coarse_patch_level, coarse_level_ao, coarse_ao_offset);\n+    }\n+    else if (dof_index_sc_var)\n+    {\n+        constructProlongationOp_side(mat, dof_index_idx, num_fine_dofs_per_proc, num_coarse_dofs_per_proc,\n+                                     fine_patch_level, coarse_patch_level, coarse_level_ao, coarse_ao_offset);\n+    }\n+    else\n+    {\n+        TBOX_ERROR(\"PETScVecUtilities::constructPatchLevelProlongationOp():\\n\"\n+                   << \"  unsupported data centering type for variable \" << dof_index_var->getName() << \"\\n\");\n+    }\n+\n+} // constructPatchLevelProlongationOp\n+\n+void PETScMatUtilities::constructRestrictionScalingOp(Mat& P, Vec& L)\n+{\n+    // Note that enteries of P are positive, so we will use column norm-1 function\n+    // of PETSc which appears to be faster than row sum call from the documentation.\n+    // We might have a column of all zeros for some DOFs (say pressure for combined\n+    // u-p vec, if we are only prolongating u). Therefore, care should be taken for\n+    // this case.\n+\n+    int ierr;\n+    PetscInt M, N;\n+    ierr = MatGetSize(P, &M, &N);\n+    IBTK_CHKERRQ(ierr);\n+    std::vector<double> column_sum_inv(N);\n+    ierr = MatGetColumnNorms(P, NORM_1, &column_sum_inv[0]);\n+    IBTK_CHKERRQ(ierr);\n+\n+    for (int k = 0; k < N; ++k)\n+    {\n+        const double sum = column_sum_inv[k];\n+        if (!MathUtilities<double>::equalEps(sum, 0.0))\n+        {\n+            column_sum_inv[k] = 1.0 / sum;\n+        }\n+        else\n+        {\n+            column_sum_inv[k] = 0.0;\n+        }\n+    }\n+\n+    // Get the right vector of P, which becomes the left-vector of R.\n+    if (L)\n+    {\n+        ierr = VecDestroy(&L);\n+        IBTK_CHKERRQ(ierr);\n+    }\n+    ierr = MatGetVecs(P, &L, PETSC_NULL);\n+    IBTK_CHKERRQ(ierr);\n+    PetscInt ilower, iupper, num_elems;\n+    ierr = VecGetOwnershipRange(L, &ilower, &iupper);\n+    IBTK_CHKERRQ(ierr);\n+    num_elems = iupper - ilower;\n+\n+    if (num_elems != 0)\n+    {\n+        std::vector<PetscScalar> L_vals(num_elems);\n+        std::vector<PetscInt> L_idxs(num_elems);\n+        for (int k = ilower; k < iupper; ++k)\n+        {\n+            L_idxs[k - ilower] = k;\n+            L_vals[k - ilower] = column_sum_inv[k];\n+        }\n+        ierr = VecSetValues(L, num_elems, &L_idxs[0], &L_vals[0], INSERT_VALUES);\n+        IBTK_CHKERRQ(ierr);\n+    }\n+    // Assemble the diagonal matrix\n+    ierr = VecAssemblyBegin(L);\n+    IBTK_CHKERRQ(ierr);\n+    ierr = VecAssemblyEnd(L);\n+    IBTK_CHKERRQ(ierr);\n+\n+    return;\n+} // constructRestrictionScalingOp\n+\n+void PETScMatUtilities::constructPatchLevelASMSubdomains(IS** is_overlap,\n+                                                         IS** is_nonoverlap,\n+                                                         int& n_subdomains,\n+                                                         const IntVector<NDIM>& box_size,\n+                                                         const IntVector<NDIM>& overlap_size,\n+                                                         const std::vector<int>& num_dofs_per_proc,\n+                                                         int dof_index_idx,\n+                                                         Pointer<PatchLevel<NDIM> > patch_level)\n+{\n+    // Determine the data-centering type.\n+    VariableDatabase<NDIM>* var_db = VariableDatabase<NDIM>::getDatabase();\n+    Pointer<Variable<NDIM> > dof_index_var;\n+    var_db->mapIndexToVariable(dof_index_idx, dof_index_var);\n+    Pointer<CellVariable<NDIM, int> > dof_index_cc_var = dof_index_var;\n+    Pointer<SideVariable<NDIM, int> > dof_index_sc_var = dof_index_var;\n+    if (dof_index_cc_var)\n+    {\n+        constructPatchLevelASMSubdomains_cell(is_overlap, is_nonoverlap, n_subdomains, box_size, overlap_size,\n+                                              num_dofs_per_proc, dof_index_idx, patch_level);\n+    }\n+    else if (dof_index_sc_var)\n+    {\n+        constructPatchLevelASMSubdomains_side(is_overlap, is_nonoverlap, n_subdomains, box_size, overlap_size,\n+                                              num_dofs_per_proc, dof_index_idx, patch_level);\n+    }\n+    else\n+    {\n+        TBOX_ERROR(\"PETScVecUtilities::constructPatchLevelASMSubdomains():\\n\"\n+                   << \"  unsupported data centering type for variable \" << dof_index_var->getName() << \"\\n\");\n+    }\n+\n+    return;\n+\n+} // constructPatchLevelASMSubdomains\n+\n /////////////////////////////// PROTECTED ////////////////////////////////////\n \n /////////////////////////////// PRIVATE //////////////////////////////////////\n \n+void PETScMatUtilities::constructProlongationOp_cell(Mat& mat,\n+                                                     int dof_index_idx,\n+                                                     const std::vector<int>& num_fine_dofs_per_proc,\n+                                                     const std::vector<int>& num_coarse_dofs_per_proc,\n+                                                     Pointer<PatchLevel<NDIM> > fine_patch_level,\n+                                                     Pointer<PatchLevel<NDIM> > coarse_patch_level,\n+                                                     const AO& coarse_level_ao,\n+                                                     const int coarse_ao_offset)\n+{\n+    int ierr;\n+    if (mat)\n+    {\n+        ierr = MatDestroy(&mat);\n+        IBTK_CHKERRQ(ierr);\n+    }\n+\n+    // Determine the grid and data extents for the coarse level.\n+    const BoxArray<NDIM>& coarse_domain_boxes = coarse_patch_level->getPhysicalDomain();\n+#if !defined(NDEBUG)\n+    TBOX_ASSERT(coarse_domain_boxes.size() == 1);\n+#endif\n+    const Index<NDIM>& coarse_domain_lower = coarse_domain_boxes[0].lower();\n+    const Index<NDIM>& coarse_domain_upper = coarse_domain_boxes[0].upper();\n+    Index<NDIM> coarse_num_cells = 1;\n+    coarse_num_cells += coarse_domain_upper - coarse_domain_lower;\n+\n+    // Ratio between fine and coarse levels.\n+    const IntVector<NDIM>& coarse_ratio = coarse_patch_level->getRatio();\n+    const IntVector<NDIM>& fine_ratio = fine_patch_level->getRatio();\n+    const IntVector<NDIM> fine_coarse_ratio = fine_ratio / coarse_ratio;\n+\n+    // Determine the matrix dimensions and index ranges.\n+    const int mpi_rank = SAMRAI_MPI::getRank();\n+    const int m_local = num_fine_dofs_per_proc[mpi_rank];\n+    const int n_local = num_coarse_dofs_per_proc[mpi_rank];\n+    const int i_fine_lower =\n+        std::accumulate(num_fine_dofs_per_proc.begin(), num_fine_dofs_per_proc.begin() + mpi_rank, 0);\n+    const int i_fine_upper = i_fine_lower + m_local;\n+    const int j_coarse_lower =\n+        std::accumulate(num_coarse_dofs_per_proc.begin(), num_coarse_dofs_per_proc.begin() + mpi_rank, 0);\n+    const int j_coarse_upper = j_coarse_lower + n_local;\n+\n+    // Determine the non-zero matrix structure for constant refine.\n+    std::vector<int> d_nnz(m_local, 0), o_nnz(m_local, 0);\n+    for (PatchLevel<NDIM>::Iterator p(fine_patch_level); p; p++)\n+    {\n+        Pointer<Patch<NDIM> > fine_patch = fine_patch_level->getPatch(p());\n+        const Box<NDIM>& fine_patch_box = fine_patch->getBox();\n+        Pointer<CellData<NDIM, int> > dof_fine_data = fine_patch->getPatchData(dof_index_idx);\n+        const unsigned depth = dof_fine_data->getDepth();\n+        std::vector<int> samrai_petsc_map(depth), local_row(depth);\n+\n+        for (Box<NDIM>::Iterator b(CellGeometry<NDIM>::toCellBox(fine_patch_box)); b; b++)\n+        {\n+            const CellIndex<NDIM>& i_fine = b();\n+            for (unsigned d = 0; d < depth; ++d)\n+            {\n+                local_row[d] = (*dof_fine_data)(i_fine, d);\n+#if !defined(NDEBUG)\n+                TBOX_ASSERT(local_row[d] >= i_fine_lower && local_row[d] < i_fine_upper);\n+#endif\n+                local_row[d] -= i_fine_lower;\n+            }\n+\n+            const CellIndex<NDIM> i_coarse = IndexUtilities::coarsen(i_fine, fine_coarse_ratio);\n+            for (unsigned d = 0; d < depth; ++d)\n+            {\n+                samrai_petsc_map[d] = IndexUtilities::mapIndexToInteger(i_coarse, coarse_domain_lower, coarse_num_cells,\n+                                                                        d, coarse_ao_offset);\n+            }\n+            AOApplicationToPetsc(coarse_level_ao, depth, &samrai_petsc_map[0]);\n+\n+            for (unsigned d = 0; d < depth; ++d)\n+            {\n+\n+                if (samrai_petsc_map[d] >= j_coarse_lower && samrai_petsc_map[d] < j_coarse_upper)\n+                {\n+                    d_nnz[local_row[d]] = 1;\n+                }\n+                else\n+                {\n+                    o_nnz[local_row[d]] = 1;\n+                }\n+            }\n+        }\n+    }\n+\n+    // Create an empty matrix.\n+    ierr = MatCreateAIJ(PETSC_COMM_WORLD, m_local, n_local, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_DEFAULT, &d_nnz[0],\n+                        PETSC_DEFAULT, &o_nnz[0], &mat);\n+    IBTK_CHKERRQ(ierr);\n+\n+    // Determine matrix-coefficients\n+    for (PatchLevel<NDIM>::Iterator p(fine_patch_level); p; p++)\n+    {\n+        Pointer<Patch<NDIM> > fine_patch = fine_patch_level->getPatch(p());\n+        const Box<NDIM>& fine_patch_box = fine_patch->getBox();\n+        Pointer<CellData<NDIM, int> > dof_fine_data = fine_patch->getPatchData(dof_index_idx);\n+        const unsigned depth = dof_fine_data->getDepth();\n+        std::vector<int> samrai_petsc_map(depth);\n+\n+        for (Box<NDIM>::Iterator b(CellGeometry<NDIM>::toCellBox(fine_patch_box)); b; b++)\n+        {\n+            const CellIndex<NDIM>& i_fine = b();\n+            const CellIndex<NDIM> i_coarse = IndexUtilities::coarsen(i_fine, fine_coarse_ratio);\n+\n+            for (unsigned d = 0; d < depth; ++d)\n+            {\n+                samrai_petsc_map[d] = IndexUtilities::mapIndexToInteger(i_coarse, coarse_domain_lower, coarse_num_cells,\n+                                                                        d, coarse_ao_offset);\n+            }\n+            AOApplicationToPetsc(coarse_level_ao, depth, &samrai_petsc_map[0]);\n+            for (unsigned d = 0; d < depth; ++d)\n+            {\n+                int row = (*dof_fine_data)(i_fine, d);\n+                int col = samrai_petsc_map[d];\n+                PetscScalar val = 1.0;\n+                ierr = MatSetValues(mat, 1, &row, 1, &col, &val, INSERT_VALUES);\n+                IBTK_CHKERRQ(ierr);\n+            }\n+        }\n+    }\n+\n+    // Assemble the matrix.\n+    ierr = MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY);\n+    IBTK_CHKERRQ(ierr);\n+    ierr = MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY);\n+    IBTK_CHKERRQ(ierr);\n+    return;\n+\n+} // constructProlongationOp_cell\n+\n+void PETScMatUtilities::constructProlongationOp_side(Mat& mat,\n+                                                     int dof_index_idx,\n+                                                     const std::vector<int>& num_fine_dofs_per_proc,\n+                                                     const std::vector<int>& num_coarse_dofs_per_proc,\n+                                                     Pointer<PatchLevel<NDIM> > fine_patch_level,\n+                                                     Pointer<PatchLevel<NDIM> > coarse_patch_level,\n+                                                     const AO& coarse_level_ao,\n+                                                     const int coarse_ao_offset)\n+{\n+    int ierr;\n+    if (mat)\n+    {\n+        ierr = MatDestroy(&mat);\n+        IBTK_CHKERRQ(ierr);\n+    }\n+\n+    // Determine the grid and data extents for the coarse level and fine levels.\n+    const BoxArray<NDIM>& coarse_domain_boxes = coarse_patch_level->getPhysicalDomain();\n+#if !defined(NDEBUG)\n+    TBOX_ASSERT(coarse_domain_boxes.size() == 1);\n+#endif\n+    const Index<NDIM>& coarse_domain_lower = coarse_domain_boxes[0].lower();\n+    const Index<NDIM>& coarse_domain_upper = coarse_domain_boxes[0].upper();\n+\n+    const BoxArray<NDIM>& fine_domain_boxes = fine_patch_level->getPhysicalDomain();\n+#if !defined(NDEBUG)\n+    TBOX_ASSERT(fine_domain_boxes.size() == 1);\n+#endif\n+    const Index<NDIM>& fine_domain_lower = fine_domain_boxes[0].lower();\n+    const Index<NDIM>& fine_domain_upper = fine_domain_boxes[0].upper();\n+\n+    boost::array<Index<NDIM>, NDIM> coarse_num_cells, fine_num_cells;\n+    for (unsigned d = 0; d < NDIM; ++d)\n+    {\n+        Index<NDIM> offset = 1;\n+        offset(d) = 2;\n+        coarse_num_cells[d] = coarse_domain_upper - coarse_domain_lower + offset;\n+        fine_num_cells[d] = fine_domain_upper - fine_domain_lower + offset;\n+    }\n+\n+    // Ratio between fine and coarse levels.\n+    const IntVector<NDIM>& coarse_ratio = coarse_patch_level->getRatio();\n+    const IntVector<NDIM>& fine_ratio = fine_patch_level->getRatio();\n+    const IntVector<NDIM> fine_coarse_ratio = fine_ratio / coarse_ratio;\n+\n+    // Determine the matrix dimensions and index ranges.\n+    const int mpi_rank = SAMRAI_MPI::getRank();\n+    const int m_local = num_fine_dofs_per_proc[mpi_rank];\n+    const int n_local = num_coarse_dofs_per_proc[mpi_rank];\n+    const int i_fine_lower =\n+        std::accumulate(num_fine_dofs_per_proc.begin(), num_fine_dofs_per_proc.begin() + mpi_rank, 0);\n+    const int i_fine_upper = i_fine_lower + m_local;\n+    const int j_coarse_lower =\n+        std::accumulate(num_coarse_dofs_per_proc.begin(), num_coarse_dofs_per_proc.begin() + mpi_rank, 0);\n+    const int j_coarse_upper = j_coarse_lower + n_local;\n+\n+    // Determine the non-zero matrix structure for the refine operator.\n+    std::vector<int> d_nnz(m_local, 0), o_nnz(m_local, 0);\n+    for (PatchLevel<NDIM>::Iterator p(fine_patch_level); p; p++)\n+    {\n+        Pointer<Patch<NDIM> > fine_patch = fine_patch_level->getPatch(p());\n+        const Box<NDIM>& fine_patch_box = fine_patch->getBox();\n+        Pointer<SideData<NDIM, int> > fine_dof_data = fine_patch->getPatchData(dof_index_idx);\n+        const unsigned depth = fine_dof_data->getDepth();\n+        std::vector<int> samrai_petsc_map(2 * depth), local_row(depth);\n+\n+        for (int axis = 0; axis < NDIM; ++axis)\n+        {\n+            IntVector<NDIM> offset = 0;\n+            offset(axis) = 1;\n+\n+            int data_offset = 0;\n+            for (int side = 0; side < axis; ++side)\n+            {\n+                int side_offset = depth;\n+                for (unsigned d = 0; d < NDIM; ++d) side_offset *= coarse_num_cells[side](d);\n+                data_offset += side_offset;\n+            }\n+\n+            for (Box<NDIM>::Iterator b(SideGeometry<NDIM>::toSideBox(fine_patch_box, axis)); b; b++)\n+            {\n+                const CellIndex<NDIM>& i = b();\n+                const SideIndex<NDIM> i_s(i, axis, SideIndex<NDIM>::Lower);\n+                bool on_proc_fine_loc = true;\n+                for (unsigned d = 0; d < depth; ++d)\n+                {\n+                    local_row[d] = (*fine_dof_data)(i_s, d);\n+\n+                    on_proc_fine_loc = on_proc_fine_loc && local_row[d] >= i_fine_lower && local_row[d] < i_fine_upper;\n+\n+                    local_row[d] -= i_fine_lower;\n+                }\n+                if (!on_proc_fine_loc) continue;\n+\n+                const CellIndex<NDIM> I = IndexUtilities::coarsen(i, fine_coarse_ratio);\n+                const CellIndex<NDIM>& I_L = I;\n+                const CellIndex<NDIM> I_U = I_L + offset;\n+                for (unsigned d = 0; d < depth; ++d)\n+                {\n+                    samrai_petsc_map[d] = IndexUtilities::mapIndexToInteger(\n+                        I_L, coarse_domain_lower, coarse_num_cells[axis], d, coarse_ao_offset + data_offset);\n+                    samrai_petsc_map[depth + d] = IndexUtilities::mapIndexToInteger(\n+                        I_U, coarse_domain_lower, coarse_num_cells[axis], d, coarse_ao_offset + data_offset);\n+                }\n+                AOApplicationToPetsc(coarse_level_ao, 2 * depth, &samrai_petsc_map[0]);\n+\n+                for (unsigned d = 0; d < depth; ++d)\n+                {\n+                    if (samrai_petsc_map[d] >= j_coarse_lower && samrai_petsc_map[d] < j_coarse_upper)\n+                    {\n+                        d_nnz[local_row[d]] = 1;\n+                    }\n+                    else\n+                    {\n+                        o_nnz[local_row[d]] = 1;\n+                    }\n+\n+                    if (samrai_petsc_map[depth + d] >= j_coarse_lower && samrai_petsc_map[depth + d] < j_coarse_upper)\n+                    {\n+                        d_nnz[local_row[d]] += 1;\n+                    }\n+                    else\n+                    {\n+                        o_nnz[local_row[d]] += 1;\n+                    }\n+                }\n+            }\n+        }\n+    }\n+\n+    // Create an empty matrix.\n+    ierr = MatCreateAIJ(PETSC_COMM_WORLD, m_local, n_local, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_DEFAULT, &d_nnz[0],\n+                        PETSC_DEFAULT, &o_nnz[0], &mat);\n+    IBTK_CHKERRQ(ierr);\n+\n+    // Determine the matrix-coefficients\n+    for (PatchLevel<NDIM>::Iterator p(fine_patch_level); p; p++)\n+    {\n+        Pointer<Patch<NDIM> > fine_patch = fine_patch_level->getPatch(p());\n+        const Box<NDIM>& fine_patch_box = fine_patch->getBox();\n+        Pointer<SideData<NDIM, int> > fine_dof_data = fine_patch->getPatchData(dof_index_idx);\n+        const unsigned depth = fine_dof_data->getDepth();\n+        std::vector<int> samrai_petsc_map(2 * depth);\n+\n+        for (int axis = 0; axis < NDIM; ++axis)\n+        {\n+            IntVector<NDIM> offset = 0;\n+            offset(axis) = 1;\n+\n+            int data_offset = 0;\n+            for (int side = 0; side < axis; ++side)\n+            {\n+                int side_offset = depth;\n+                for (unsigned d = 0; d < NDIM; ++d) side_offset *= coarse_num_cells[side](d);\n+                data_offset += side_offset;\n+            }\n+\n+            for (Box<NDIM>::Iterator b(SideGeometry<NDIM>::toSideBox(fine_patch_box, axis)); b; b++)\n+            {\n+                const CellIndex<NDIM>& i = b();\n+                const SideIndex<NDIM> i_s(i, axis, SideIndex<NDIM>::Lower);\n+                bool on_proc_fine_loc = true;\n+                for (unsigned d = 0; d < depth; ++d)\n+                {\n+                    const int fine_dof_idx = (*fine_dof_data)(i_s, d);\n+                    on_proc_fine_loc = on_proc_fine_loc && fine_dof_idx >= i_fine_lower && fine_dof_idx < i_fine_upper;\n+                }\n+                if (!on_proc_fine_loc) continue;\n+\n+                const CellIndex<NDIM> I = IndexUtilities::coarsen(i, fine_coarse_ratio);\n+                const CellIndex<NDIM>& I_L = I;\n+                const CellIndex<NDIM> I_U = I_L + offset;\n+                for (unsigned d = 0; d < depth; ++d)\n+                {\n+                    samrai_petsc_map[d] = IndexUtilities::mapIndexToInteger(\n+                        I_L, coarse_domain_lower, coarse_num_cells[axis], d, coarse_ao_offset + data_offset);\n+                    samrai_petsc_map[depth + d] = IndexUtilities::mapIndexToInteger(\n+                        I_U, coarse_domain_lower, coarse_num_cells[axis], d, coarse_ao_offset + data_offset);\n+                }\n+                AOApplicationToPetsc(coarse_level_ao, 2 * depth, &samrai_petsc_map[0]);\n+\n+                for (unsigned d = 0; d < depth; ++d)\n+                {\n+                    int row = (*fine_dof_data)(i_s, d);\n+                    int col[2] = { samrai_petsc_map[d], samrai_petsc_map[depth + d] };\n+\n+                    // w_L = 1 - [i(axis) - refine(I_L,ratio)(axis)]/ratio(axis)\n+                    double w_L = 1.0 -\n+                                 (static_cast<double>(i(axis)) -\n+                                  static_cast<double>(IndexUtilities::refine(I_L, fine_coarse_ratio)(axis))) /\n+                                     static_cast<double>(fine_coarse_ratio(axis));\n+\n+                    double col_val[2] = { w_L, 1.0 - w_L };\n+                    ierr = MatSetValues(mat, 1, &row, 2, col, col_val, INSERT_VALUES);\n+                }\n+            }\n+        }\n+    }\n+\n+    // Assemble the matrix.\n+    ierr = MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY);\n+    IBTK_CHKERRQ(ierr);\n+    ierr = MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY);\n+    IBTK_CHKERRQ(ierr);\n+\n+    return;\n+\n+} // constructProlongationOp_side\n+\n+void PETScMatUtilities::constructPatchLevelASMSubdomains_cell(IS** is_overlap,\n+                                                              IS** is_nonoverlap,\n+                                                              int& n_subdomains,\n+                                                              const IntVector<NDIM>& box_size,\n+                                                              const IntVector<NDIM>& overlap_size,\n+                                                              const std::vector<int>& num_dofs_per_proc,\n+                                                              int dof_index_idx,\n+                                                              Pointer<PatchLevel<NDIM> > patch_level)\n+{\n+    // Determine the DOF index range on this processor.\n+    const int mpi_rank = SAMRAI_MPI::getRank();\n+    const int dofs_local = num_dofs_per_proc[mpi_rank];\n+    const int dof_lower = std::accumulate(num_dofs_per_proc.begin(), num_dofs_per_proc.begin() + mpi_rank, 0);\n+    const int dof_upper = dof_lower + dofs_local;\n+\n+    // Determine the total nonoverlapping subdomains on this processor.\n+    n_subdomains = 0;\n+    for (PatchLevel<NDIM>::Iterator p(patch_level); p; p++)\n+    {\n+        Pointer<Patch<NDIM> > patch = patch_level->getPatch(p());\n+        const Box<NDIM>& patch_box = patch->getBox();\n+        const IntVector<NDIM>& patch_lower = patch_box.lower();\n+        const IntVector<NDIM>& patch_upper = patch_box.upper();\n+\n+        // Compute number of nonoverlapping subdomains\n+        IntVector<NDIM> cells = 1;\n+        cells += patch_upper - patch_lower;\n+        IntVector<NDIM> subdomains = cells / box_size;\n+        int n_patch_subdomains = 1;\n+        for (int d = 0; d < NDIM; ++d)\n+        {\n+            // If box size is bigger than patch size, we still account for it.\n+            if (subdomains(d) == 0)\n+            {\n+                subdomains(d) = 1;\n+            }\n+            n_patch_subdomains *= subdomains(d);\n+        }\n+        n_subdomains += n_patch_subdomains;\n+    }\n+    *is_overlap = new IS[n_subdomains];\n+    *is_nonoverlap = new IS[n_subdomains];\n+\n+    // Fill in the IS'es\n+    int counter = 0;\n+    bool there_is_overlap = overlap_size.min();\n+    for (PatchLevel<NDIM>::Iterator p(patch_level); p; p++)\n+    {\n+        Pointer<Patch<NDIM> > patch = patch_level->getPatch(p());\n+        const Box<NDIM>& patch_box = patch->getBox();\n+        const IntVector<NDIM>& patch_lower = patch_box.lower();\n+        const IntVector<NDIM>& patch_upper = patch_box.upper();\n+        Pointer<CellData<NDIM, int> > dof_data = patch->getPatchData(dof_index_idx);\n+        const int data_depth = dof_data->getDepth();\n+\n+        // Compute number of nonoverlapping subdomains\n+        IntVector<NDIM> cells = 1;\n+        cells += patch_upper - patch_lower;\n+        IntVector<NDIM> subdomains = cells / box_size;\n+        for (int d = 0; d < NDIM; ++d)\n+        {\n+            if (subdomains(d) == 0)\n+            {\n+                subdomains(d) = 1;\n+            }\n+        }\n+\n+#if (NDIM == 2)\n+        const int Nx = subdomains(0);\n+        const int Ny = subdomains(1);\n+\n+        int j_lower = patch_lower(1);\n+        for (int J = 1; J <= Ny; ++J)\n+        {\n+            const int height = (cells(1) / box_size(1) ? box_size(1) : 0) + (J == Ny ? cells(1) % box_size(1) : 0);\n+\n+            int i_lower = patch_lower(0);\n+            for (int I = 1; I <= Nx; ++I)\n+            {\n+                const int width = (cells(0) / box_size(0) ? box_size(0) : 0) + (I == Nx ? cells(0) % box_size(0) : 0);\n+\n+                // Create a box to iterate over for the nonoverlapping subdomain\n+                IntVector<NDIM> box_lower(i_lower, j_lower);\n+                IntVector<NDIM> box_upper(i_lower + width - 1, j_lower + height - 1);\n+                Box<NDIM> box_local(box_lower, box_upper);\n+\n+                std::vector<int> box_local_dofs;\n+                box_local_dofs.reserve(height * width * data_depth);\n+                for (Box<NDIM>::Iterator b(box_local); b; b++)\n+                {\n+                    const CellIndex<NDIM>& i = b();\n+                    for (int d = 0; d < data_depth; ++d)\n+                    {\n+                        const int dof_idx = (*dof_data)(i, d);\n+#if !defined(NDEBUG)\n+                        TBOX_ASSERT(dof_idx >= dof_lower && dof_idx < dof_upper);\n+#endif\n+                        box_local_dofs.push_back(dof_idx);\n+                    }\n+                }\n+                const int n_idx = static_cast<int>(box_local_dofs.size());\n+                ISCreateGeneral(PETSC_COMM_SELF, n_idx, &box_local_dofs[0], PETSC_COPY_VALUES,\n+                                &is_nonoverlap[0][counter]);\n+\n+                // Fill IS'es for overlap subdomain\n+                if (!there_is_overlap)\n+                {\n+                    PetscObjectReference((PetscObject)is_nonoverlap[0][counter]);\n+                    is_overlap[0][counter] = is_nonoverlap[0][counter];\n+                }\n+                else\n+                {\n+                    // Create a box to iterate over overlapping subdomain\n+                    const int gcwx = overlap_size(0);\n+                    const int gcwy = overlap_size(1);\n+                    IntVector<NDIM> box_lower(i_lower - gcwx, j_lower - gcwy);\n+                    IntVector<NDIM> box_upper(i_lower + width + gcwx - 1, j_lower + height + gcwy - 1);\n+                    Box<NDIM> box_overlap(box_lower, box_upper);\n+\n+                    std::vector<int> box_overlap_dofs;\n+                    const int max_size = (height + 2 * gcwx) * (width + 2 * gcwy) * data_depth;\n+                    box_overlap_dofs.reserve(max_size);\n+                    for (Box<NDIM>::Iterator b(box_overlap); b; b++)\n+                    {\n+                        const CellIndex<NDIM>& i = b();\n+                        for (int d = 0; d < data_depth; ++d)\n+                        {\n+                            const int dof_idx = (*dof_data)(i, d);\n+\n+                            // If keep only the DOFs that are inside the\n+                            // physical domain. Some of the DOFs will be on\n+                            // other processors.\n+                            if (dof_idx >= 0)\n+                            {\n+                                box_local_dofs.push_back(dof_idx);\n+                            }\n+                        }\n+                    }\n+                    const int n_idx = static_cast<int>(box_overlap_dofs.size());\n+                    ISCreateGeneral(PETSC_COMM_SELF, n_idx, &box_overlap_dofs[0], PETSC_COPY_VALUES,\n+                                    &is_overlap[0][counter]);\n+                }\n+                ++counter;\n+                i_lower += width;\n+            }\n+            j_lower += height;\n+        }\n+\n+#elif(NDIM == 3)\n+\n+        const int Nx = subdomains(0);\n+        const int Ny = subdomains(1);\n+        const int Nz = subdomains(2);\n+\n+        int k_lower = patch_lower(2);\n+        for (int K = 1; K <= Nz; ++K)\n+        {\n+            const int depth = (cells(2) / box_size(2) ? box_size(2) : 0) + (K == Nz ? cells(2) % box_size(2) : 0);\n+\n+            int j_lower = patch_lower(1);\n+            for (int J = 1; J <= Ny; ++J)\n+            {\n+                const int height = (cells(1) / box_size(1) ? box_size(1) : 0) + (J == Ny ? cells(1) % box_size(1) : 0);\n+\n+                int i_lower = patch_lower(0);\n+                for (int I = 1; I <= Nx; ++I)\n+                {\n+                    const int width =\n+                        (cells(0) / box_size(0) ? box_size(0) : 0) + (I == Nx ? cells(0) % box_size(0) : 0);\n+\n+                    // Create a box to iterate over for the nonoverlapping subdomain\n+                    IntVector<NDIM> box_lower(i_lower, j_lower, k_lower);\n+                    IntVector<NDIM> box_upper(i_lower + width - 1, j_lower + height - 1, k_lower + depth - 1);\n+                    Box<NDIM> box_local(box_lower, box_upper);\n+\n+                    std::vector<int> box_local_dofs;\n+                    box_local_dofs.reserve(height * width * depth * data_depth);\n+                    for (Box<NDIM>::Iterator b(box_local); b; b++)\n+                    {\n+                        const CellIndex<NDIM>& i = b();\n+                        for (int d = 0; d < data_depth; ++d)\n+                        {\n+                            const int dof_idx = (*dof_data)(i, d);\n+#if !defined(NDEBUG)\n+                            TBOX_ASSERT(dof_idx >= dof_lower && dof_idx < dof_upper);\n+#endif\n+                            box_local_dofs.push_back(dof_idx);\n+                        }\n+                    }\n+                    const int n_idx = static_cast<int>(box_local_dofs.size());\n+                    ISCreateGeneral(PETSC_COMM_SELF, n_idx, &box_local_dofs[0], PETSC_COPY_VALUES,\n+                                    &is_nonoverlap[0][counter]);\n+\n+                    // Fill IS'es for overlap subdomain\n+                    if (!there_is_overlap)\n+                    {\n+                        PetscObjectReference((PetscObject)is_nonoverlap[0][counter]);\n+                        is_overlap[0][counter] = is_nonoverlap[0][counter];\n+                    }\n+                    else\n+                    {\n+                        // Create a box to iterate over overlapping subdomain\n+                        const int gcwx = overlap_size(0);\n+                        const int gcwy = overlap_size(1);\n+                        const int gcwz = overlap_size(2);\n+                        IntVector<NDIM> box_lower(i_lower - gcwx, j_lower - gcwy, k_lower - gcwz);\n+                        IntVector<NDIM> box_upper(i_lower + width + gcwx - 1, j_lower + height + gcwy - 1,\n+                                                  k_lower + depth + gcwz - 1);\n+                        Box<NDIM> box_overlap(box_lower, box_upper);\n+\n+                        std::vector<int> box_overlap_dofs;\n+                        const int max_size = (height + 2 * gcwx) * (width + 2 * gcwy) * (depth + 2 * gcwz) * data_depth;\n+                        box_overlap_dofs.reserve(max_size);\n+                        for (Box<NDIM>::Iterator b(box_overlap); b; b++)\n+                        {\n+                            const CellIndex<NDIM>& i = b();\n+                            for (int d = 0; d < data_depth; ++d)\n+                            {\n+                                const int dof_idx = (*dof_data)(i, d);\n+\n+                                // If keep only the DOFs that are inside the\n+                                // physical domain. Some of the DOFs will be on\n+                                // other processors.\n+                                if (dof_idx >= 0)\n+                                {\n+                                    box_local_dofs.push_back(dof_idx);\n+                                }\n+                            }\n+                        }\n+                        const int n_idx = static_cast<int>(box_overlap_dofs.size());\n+                        ISCreateGeneral(PETSC_COMM_SELF, n_idx, &box_overlap_dofs[0], PETSC_COPY_VALUES,\n+                                        &is_overlap[0][counter]);\n+                    }\n+                    ++counter;\n+                    i_lower += width;\n+                }\n+                j_lower += height;\n+            }\n+            k_lower += depth;\n+        }\n+#endif\n+    }\n+\n+#if !defined(NDEBUG)\n+    TBOX_ASSERT(counter == n_subdomains);\n+#endif\n+    return;\n+} // constructPatchLevelASMSubdomains_cell\n+","path":"ibtk/src/math/PETScMatUtilities.cpp","position":1028,"original_position":1028,"commit_id":"9bd22854b238ea9777cc0dbf85ba1a589535d5ea","original_commit_id":"9bd22854b238ea9777cc0dbf85ba1a589535d5ea","user":{"login":"boyceg","id":4389897,"avatar_url":"https://avatars.githubusercontent.com/u/4389897?v=3","gravatar_id":"","url":"https://api.github.com/users/boyceg","html_url":"https://github.com/boyceg","followers_url":"https://api.github.com/users/boyceg/followers","following_url":"https://api.github.com/users/boyceg/following{/other_user}","gists_url":"https://api.github.com/users/boyceg/gists{/gist_id}","starred_url":"https://api.github.com/users/boyceg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/boyceg/subscriptions","organizations_url":"https://api.github.com/users/boyceg/orgs","repos_url":"https://api.github.com/users/boyceg/repos","events_url":"https://api.github.com/users/boyceg/events{/privacy}","received_events_url":"https://api.github.com/users/boyceg/received_events","type":"User","site_admin":false},"body":"DOF indices are set to -1 in the physical boundary and c-f interface ghost cell regions.","created_at":"2015-04-30T17:08:24Z","updated_at":"2015-04-30T17:08:24Z","html_url":"https://github.com/IBAMR/IBAMR/pull/6#discussion_r29448738","pull_request_url":"https://api.github.com/repos/IBAMR/IBAMR/pulls/6","_links":{"self":{"href":"https://api.github.com/repos/IBAMR/IBAMR/pulls/comments/29448738"},"html":{"href":"https://github.com/IBAMR/IBAMR/pull/6#discussion_r29448738"},"pull_request":{"href":"https://api.github.com/repos/IBAMR/IBAMR/pulls/6"}}},"pull_request":{"url":"https://api.github.com/repos/IBAMR/IBAMR/pulls/6","id":33771494,"html_url":"https://github.com/IBAMR/IBAMR/pull/6","diff_url":"https://github.com/IBAMR/IBAMR/pull/6.diff","patch_url":"https://github.com/IBAMR/IBAMR/pull/6.patch","issue_url":"https://api.github.com/repos/IBAMR/IBAMR/issues/6","number":6,"state":"open","locked":false,"title":"Enhanced multigrid solvers, including for Stokes-IB","user":{"login":"boyceg","id":4389897,"avatar_url":"https://avatars.githubusercontent.com/u/4389897?v=3","gravatar_id":"","url":"https://api.github.com/users/boyceg","html_url":"https://github.com/boyceg","followers_url":"https://api.github.com/users/boyceg/followers","following_url":"https://api.github.com/users/boyceg/following{/other_user}","gists_url":"https://api.github.com/users/boyceg/gists{/gist_id}","starred_url":"https://api.github.com/users/boyceg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/boyceg/subscriptions","organizations_url":"https://api.github.com/users/boyceg/orgs","repos_url":"https://api.github.com/users/boyceg/repos","events_url":"https://api.github.com/users/boyceg/events{/privacy}","received_events_url":"https://api.github.com/users/boyceg/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-04-21T15:13:38Z","updated_at":"2015-04-30T17:08:24Z","closed_at":null,"merged_at":null,"merge_commit_sha":"411e0110c16dde3b8ee2b93d0b6c3079accd1c13","assignee":{"login":"amneetb","id":7378152,"avatar_url":"https://avatars.githubusercontent.com/u/7378152?v=3","gravatar_id":"","url":"https://api.github.com/users/amneetb","html_url":"https://github.com/amneetb","followers_url":"https://api.github.com/users/amneetb/followers","following_url":"https://api.github.com/users/amneetb/following{/other_user}","gists_url":"https://api.github.com/users/amneetb/gists{/gist_id}","starred_url":"https://api.github.com/users/amneetb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/amneetb/subscriptions","organizations_url":"https://api.github.com/users/amneetb/orgs","repos_url":"https://api.github.com/users/amneetb/repos","events_url":"https://api.github.com/users/amneetb/events{/privacy}","received_events_url":"https://api.github.com/users/amneetb/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/IBAMR/IBAMR/pulls/6/commits","review_comments_url":"https://api.github.com/repos/IBAMR/IBAMR/pulls/6/comments","review_comment_url":"https://api.github.com/repos/IBAMR/IBAMR/pulls/comments{/number}","comments_url":"https://api.github.com/repos/IBAMR/IBAMR/issues/6/comments","statuses_url":"https://api.github.com/repos/IBAMR/IBAMR/statuses/9bd22854b238ea9777cc0dbf85ba1a589535d5ea","head":{"label":"IBAMR:boyceg/MG-smoothers","ref":"boyceg/MG-smoothers","sha":"9bd22854b238ea9777cc0dbf85ba1a589535d5ea","user":{"login":"IBAMR","id":7332761,"avatar_url":"https://avatars.githubusercontent.com/u/7332761?v=3","gravatar_id":"","url":"https://api.github.com/users/IBAMR","html_url":"https://github.com/IBAMR","followers_url":"https://api.github.com/users/IBAMR/followers","following_url":"https://api.github.com/users/IBAMR/following{/other_user}","gists_url":"https://api.github.com/users/IBAMR/gists{/gist_id}","starred_url":"https://api.github.com/users/IBAMR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/IBAMR/subscriptions","organizations_url":"https://api.github.com/users/IBAMR/orgs","repos_url":"https://api.github.com/users/IBAMR/repos","events_url":"https://api.github.com/users/IBAMR/events{/privacy}","received_events_url":"https://api.github.com/users/IBAMR/received_events","type":"Organization","site_admin":false},"repo":{"id":18901909,"name":"IBAMR","full_name":"IBAMR/IBAMR","owner":{"login":"IBAMR","id":7332761,"avatar_url":"https://avatars.githubusercontent.com/u/7332761?v=3","gravatar_id":"","url":"https://api.github.com/users/IBAMR","html_url":"https://github.com/IBAMR","followers_url":"https://api.github.com/users/IBAMR/followers","following_url":"https://api.github.com/users/IBAMR/following{/other_user}","gists_url":"https://api.github.com/users/IBAMR/gists{/gist_id}","starred_url":"https://api.github.com/users/IBAMR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/IBAMR/subscriptions","organizations_url":"https://api.github.com/users/IBAMR/orgs","repos_url":"https://api.github.com/users/IBAMR/repos","events_url":"https://api.github.com/users/IBAMR/events{/privacy}","received_events_url":"https://api.github.com/users/IBAMR/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/IBAMR/IBAMR","description":"An adaptive and distributed-memory parallel implementation of the immersed boundary (IB) method","fork":false,"url":"https://api.github.com/repos/IBAMR/IBAMR","forks_url":"https://api.github.com/repos/IBAMR/IBAMR/forks","keys_url":"https://api.github.com/repos/IBAMR/IBAMR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/IBAMR/IBAMR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/IBAMR/IBAMR/teams","hooks_url":"https://api.github.com/repos/IBAMR/IBAMR/hooks","issue_events_url":"https://api.github.com/repos/IBAMR/IBAMR/issues/events{/number}","events_url":"https://api.github.com/repos/IBAMR/IBAMR/events","assignees_url":"https://api.github.com/repos/IBAMR/IBAMR/assignees{/user}","branches_url":"https://api.github.com/repos/IBAMR/IBAMR/branches{/branch}","tags_url":"https://api.github.com/repos/IBAMR/IBAMR/tags","blobs_url":"https://api.github.com/repos/IBAMR/IBAMR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/IBAMR/IBAMR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/IBAMR/IBAMR/git/refs{/sha}","trees_url":"https://api.github.com/repos/IBAMR/IBAMR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/IBAMR/IBAMR/statuses/{sha}","languages_url":"https://api.github.com/repos/IBAMR/IBAMR/languages","stargazers_url":"https://api.github.com/repos/IBAMR/IBAMR/stargazers","contributors_url":"https://api.github.com/repos/IBAMR/IBAMR/contributors","subscribers_url":"https://api.github.com/repos/IBAMR/IBAMR/subscribers","subscription_url":"https://api.github.com/repos/IBAMR/IBAMR/subscription","commits_url":"https://api.github.com/repos/IBAMR/IBAMR/commits{/sha}","git_commits_url":"https://api.github.com/repos/IBAMR/IBAMR/git/commits{/sha}","comments_url":"https://api.github.com/repos/IBAMR/IBAMR/comments{/number}","issue_comment_url":"https://api.github.com/repos/IBAMR/IBAMR/issues/comments{/number}","contents_url":"https://api.github.com/repos/IBAMR/IBAMR/contents/{+path}","compare_url":"https://api.github.com/repos/IBAMR/IBAMR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/IBAMR/IBAMR/merges","archive_url":"https://api.github.com/repos/IBAMR/IBAMR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/IBAMR/IBAMR/downloads","issues_url":"https://api.github.com/repos/IBAMR/IBAMR/issues{/number}","pulls_url":"https://api.github.com/repos/IBAMR/IBAMR/pulls{/number}","milestones_url":"https://api.github.com/repos/IBAMR/IBAMR/milestones{/number}","notifications_url":"https://api.github.com/repos/IBAMR/IBAMR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/IBAMR/IBAMR/labels{/name}","releases_url":"https://api.github.com/repos/IBAMR/IBAMR/releases{/id}","created_at":"2014-04-18T03:50:44Z","updated_at":"2015-04-27T05:47:55Z","pushed_at":"2015-04-30T16:45:37Z","git_url":"git://github.com/IBAMR/IBAMR.git","ssh_url":"git@github.com:IBAMR/IBAMR.git","clone_url":"https://github.com/IBAMR/IBAMR.git","svn_url":"https://github.com/IBAMR/IBAMR","homepage":null,"size":93421,"stargazers_count":19,"watchers_count":19,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":9,"mirror_url":null,"open_issues_count":9,"forks":9,"open_issues":9,"watchers":19,"default_branch":"master"}},"base":{"label":"IBAMR:master","ref":"master","sha":"b985699288f2b7c491fb6f763f2efae91bc7005e","user":{"login":"IBAMR","id":7332761,"avatar_url":"https://avatars.githubusercontent.com/u/7332761?v=3","gravatar_id":"","url":"https://api.github.com/users/IBAMR","html_url":"https://github.com/IBAMR","followers_url":"https://api.github.com/users/IBAMR/followers","following_url":"https://api.github.com/users/IBAMR/following{/other_user}","gists_url":"https://api.github.com/users/IBAMR/gists{/gist_id}","starred_url":"https://api.github.com/users/IBAMR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/IBAMR/subscriptions","organizations_url":"https://api.github.com/users/IBAMR/orgs","repos_url":"https://api.github.com/users/IBAMR/repos","events_url":"https://api.github.com/users/IBAMR/events{/privacy}","received_events_url":"https://api.github.com/users/IBAMR/received_events","type":"Organization","site_admin":false},"repo":{"id":18901909,"name":"IBAMR","full_name":"IBAMR/IBAMR","owner":{"login":"IBAMR","id":7332761,"avatar_url":"https://avatars.githubusercontent.com/u/7332761?v=3","gravatar_id":"","url":"https://api.github.com/users/IBAMR","html_url":"https://github.com/IBAMR","followers_url":"https://api.github.com/users/IBAMR/followers","following_url":"https://api.github.com/users/IBAMR/following{/other_user}","gists_url":"https://api.github.com/users/IBAMR/gists{/gist_id}","starred_url":"https://api.github.com/users/IBAMR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/IBAMR/subscriptions","organizations_url":"https://api.github.com/users/IBAMR/orgs","repos_url":"https://api.github.com/users/IBAMR/repos","events_url":"https://api.github.com/users/IBAMR/events{/privacy}","received_events_url":"https://api.github.com/users/IBAMR/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/IBAMR/IBAMR","description":"An adaptive and distributed-memory parallel implementation of the immersed boundary (IB) method","fork":false,"url":"https://api.github.com/repos/IBAMR/IBAMR","forks_url":"https://api.github.com/repos/IBAMR/IBAMR/forks","keys_url":"https://api.github.com/repos/IBAMR/IBAMR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/IBAMR/IBAMR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/IBAMR/IBAMR/teams","hooks_url":"https://api.github.com/repos/IBAMR/IBAMR/hooks","issue_events_url":"https://api.github.com/repos/IBAMR/IBAMR/issues/events{/number}","events_url":"https://api.github.com/repos/IBAMR/IBAMR/events","assignees_url":"https://api.github.com/repos/IBAMR/IBAMR/assignees{/user}","branches_url":"https://api.github.com/repos/IBAMR/IBAMR/branches{/branch}","tags_url":"https://api.github.com/repos/IBAMR/IBAMR/tags","blobs_url":"https://api.github.com/repos/IBAMR/IBAMR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/IBAMR/IBAMR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/IBAMR/IBAMR/git/refs{/sha}","trees_url":"https://api.github.com/repos/IBAMR/IBAMR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/IBAMR/IBAMR/statuses/{sha}","languages_url":"https://api.github.com/repos/IBAMR/IBAMR/languages","stargazers_url":"https://api.github.com/repos/IBAMR/IBAMR/stargazers","contributors_url":"https://api.github.com/repos/IBAMR/IBAMR/contributors","subscribers_url":"https://api.github.com/repos/IBAMR/IBAMR/subscribers","subscription_url":"https://api.github.com/repos/IBAMR/IBAMR/subscription","commits_url":"https://api.github.com/repos/IBAMR/IBAMR/commits{/sha}","git_commits_url":"https://api.github.com/repos/IBAMR/IBAMR/git/commits{/sha}","comments_url":"https://api.github.com/repos/IBAMR/IBAMR/comments{/number}","issue_comment_url":"https://api.github.com/repos/IBAMR/IBAMR/issues/comments{/number}","contents_url":"https://api.github.com/repos/IBAMR/IBAMR/contents/{+path}","compare_url":"https://api.github.com/repos/IBAMR/IBAMR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/IBAMR/IBAMR/merges","archive_url":"https://api.github.com/repos/IBAMR/IBAMR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/IBAMR/IBAMR/downloads","issues_url":"https://api.github.com/repos/IBAMR/IBAMR/issues{/number}","pulls_url":"https://api.github.com/repos/IBAMR/IBAMR/pulls{/number}","milestones_url":"https://api.github.com/repos/IBAMR/IBAMR/milestones{/number}","notifications_url":"https://api.github.com/repos/IBAMR/IBAMR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/IBAMR/IBAMR/labels{/name}","releases_url":"https://api.github.com/repos/IBAMR/IBAMR/releases{/id}","created_at":"2014-04-18T03:50:44Z","updated_at":"2015-04-27T05:47:55Z","pushed_at":"2015-04-30T16:45:37Z","git_url":"git://github.com/IBAMR/IBAMR.git","ssh_url":"git@github.com:IBAMR/IBAMR.git","clone_url":"https://github.com/IBAMR/IBAMR.git","svn_url":"https://github.com/IBAMR/IBAMR","homepage":null,"size":93421,"stargazers_count":19,"watchers_count":19,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":9,"mirror_url":null,"open_issues_count":9,"forks":9,"open_issues":9,"watchers":19,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/IBAMR/IBAMR/pulls/6"},"html":{"href":"https://github.com/IBAMR/IBAMR/pull/6"},"issue":{"href":"https://api.github.com/repos/IBAMR/IBAMR/issues/6"},"comments":{"href":"https://api.github.com/repos/IBAMR/IBAMR/issues/6/comments"},"review_comments":{"href":"https://api.github.com/repos/IBAMR/IBAMR/pulls/6/comments"},"review_comment":{"href":"https://api.github.com/repos/IBAMR/IBAMR/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/IBAMR/IBAMR/pulls/6/commits"},"statuses":{"href":"https://api.github.com/repos/IBAMR/IBAMR/statuses/9bd22854b238ea9777cc0dbf85ba1a589535d5ea"}}}}