1 /* 2 used by SEQAIJ, BAIJ and SBAIJ to reduce code duplication 3 4 define TYPE to AIJ BAIJ or SBAIJ 5 TYPE_BS_ON for BAIJ and SBAIJ and bs > 1 6 TYPE_SBAIJ for SBAIJ 7 8 */ 9 static PetscErrorCode PetscConcat(MatSetValues_Seq_Hash, TYPE_BS)(Mat A, PetscInt m, const PetscInt *rows, PetscInt n, const PetscInt *cols, const PetscScalar *values, InsertMode addv) 10 { 11 PetscConcat(Mat_Seq, TYPE) *a = (PetscConcat(Mat_Seq, TYPE) *)A->data; 12 #if defined(TYPE_BS_ON) 13 const PetscInt bs = A->rmap->bs; 14 #endif 15 const PetscBool ignorezeroentries = a->ignorezeroentries; 16 17 PetscFunctionBegin; 18 for (PetscInt r = 0; r < m; ++r) { 19 PetscHashIJKey key; 20 PetscBool missing; 21 PetscScalar value; 22 #if defined(TYPE_BS_ON) 23 PetscHashIJKey bkey; 24 #endif 25 26 key.i = rows[r]; 27 #if defined(TYPE_BS_ON) 28 bkey.i = key.i / bs; 29 #endif 30 if (key.i < 0) continue; 31 for (PetscInt c = 0; c < n; ++c) { 32 key.j = cols[c]; 33 #if defined(TYPE_BS_ON) 34 bkey.j = key.j / bs; 35 #if defined(TYPE_SBAIJ) 36 if (bkey.j < bkey.i) continue; 37 #else 38 if (key.j < 0) continue; 39 #endif 40 #else 41 #if defined(TYPE_SBAIJ) 42 if (key.j < key.i) continue; 43 #else 44 if (key.j < 0) continue; 45 #endif 46 #endif 47 value = values ? (a->roworiented ? values[r * n + c] : values[r + m * c]) : 0; 48 if (ignorezeroentries && value == 0.0 && key.i != key.j) continue; 49 switch (addv) { 50 case INSERT_VALUES: 51 PetscCall(PetscHMapIJVQuerySet(a->ht, key, value, &missing)); 52 break; 53 case ADD_VALUES: 54 PetscCall(PetscHMapIJVQueryAdd(a->ht, key, value, &missing)); 55 break; 56 default: 57 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "InsertMode not supported"); 58 } 59 if (missing) ++a->dnz[key.i]; 60 #if defined(TYPE_BS_ON) 61 PetscCall(PetscHSetIJQueryAdd(a->bht, bkey, &missing)); 62 if (missing) ++a->bdnz[bkey.i]; 63 #endif 64 } 65 } 66 PetscFunctionReturn(PETSC_SUCCESS); 67 } 68