[petsc-users] Construct Matrix based on row and column values
Jed Brown
jed at jedbrown.org
Wed Apr 8 11:26:13 CDT 2020
Elias Karabelas <karabelaselias at gmail.com> writes:
> Dear Jed,
>
> I'm done implementing my FCT-Solver and it works fairly well on a small
> amount of MPI-Procs. Additionally to your little snippet I have used a
> VecScatterToAll.
Can you share the code including that VecScatterToAll?
There more local ways to get that information.
> Reason is that the flux correction f_i takes the form Sum_{j} alpha_ij
> r_ij where r_ij is defined on the sparsity pattern of my FEM Matrix and
> alpha_ij is based on two vectors Rp and Rm. So basically I need
> off-process values of these vectors to construct alpha which I made with
> a VecScatterToAll. However I guess this will slow down my overall
> program quite significant. Any Ideas?
>
> Best regards
>
> Elias
>
> On 23/03/2020 15:53, Jed Brown wrote:
>> Thanks; please don't drop the list.
>>
>> I'd be curious whether this operation is common enough that we should
>> add it to PETSc. My hesitance has been that people may want many
>> different variants when working with systems of equations, for example.
>>
>> Elias Karabelas <karabelaselias at gmail.com> writes:
>>
>>> Dear Jed,
>>>
>>> Yes the Matrix A comes from assembling a FEM-convection-diffusion
>>> operator over a tetrahedral mesh. So my matrix graph should be
>>> symmetric. Thanks for the snippet
>>>
>>> On 23/03/2020 15:42, Jed Brown wrote:
>>>> Elias Karabelas <karabelaselias at gmail.com> writes:
>>>>
>>>>> Dear Users,
>>>>>
>>>>> I want to implement a FCT (flux corrected transport) scheme with PETSc.
>>>>> To this end I have amongst other things create a Matrix whose entries
>>>>> are given by
>>>>>
>>>>> L_ij = -max(0, A_ij, A_ji) for i neq j
>>>>>
>>>>> L_ii = Sum_{j=0,..n, j neq i} L_ij
>>>>>
>>>>> where Mat A is an (non-symmetric) Input Matrix created beforehand.
>>>>>
>>>>> I was wondering how to do this. My first search brought me to
>>>>> https://www.mcs.anl.gov/petsc/petsc-current/src/mat/examples/tutorials/ex16.c.html
>>>>>
>>>>>
>>>>> but this just goes over the rows of one matrix to set new values and now
>>>>> I would need to run over the rows and columns of the matrix. My Idea was
>>>>> to just create a transpose of A and do the same but then the row-layout
>>>>> will be different and I can't use the same for loop for A and AT and
>>>>> thus also won't be able to calculate the max's above.
>>>> Does your matrix have symmetric nonzero structure? (It's typical for
>>>> finite element methods.)
>>>>
>>>> If so, all the indices will match up so I think you can do something like:
>>>>
>>>> for (row=rowstart; row<rowend; row++) {
>>>> PetscScalar Lvals[MAX_LEN];
>>>> PetscInt diag;
>>>> MatGetRow(A, row, &ncols, &cols, &vals);
>>>> MatGetRow(At, row, &ncolst, &colst, &valst);
>>>> assert(ncols == ncolst); // symmetric structure
>>>> PetscScalar sum = 0;
>>>> for (c=0; c<ncols; c++) {
>>>> assert(cols[c] == colst[c]); // symmetric structure
>>>> if (cols[c] == row) diag = c;
>>>> else sum -= (Lvals[c] = -max(0, vals[c], valst[c]));
>>>> }
>>>> Lvals[diag] = sum;
>>>> MatSetValues(L, 1, &row, ncols, cols, Lvals, INSERT_VALUES);
>>>> MatRestoreRow(A, row, &ncols, &cols, &vals);
>>>> MatRestoreRow(At, row, &ncolst, &colst, &valst);
>>>> }
More information about the petsc-users
mailing list