[petsc-users] [Closed] Using MatSetValuesBlocked to build Finite Element Matrices with variable coefficients
Nidish
nb25 at rice.edu
Sun Aug 9 22:45:06 CDT 2020
Update: It was a type error (idx and idy below were declared as
PetscScalar* instead of PetscInt*), I'm sorry.
Guess I'm being punished for not paying attention to types.
Nidish
On 8/9/20 10:05 PM, Nidish wrote:
>
> Update: I had made some mistakes in the assembly in the previous
> version. They're fixed now (see below).
>
> On 8/9/20 9:13 PM, Nidish wrote:
>>
>> I'm trying to write a simple 1D finite element test case (linear
>> elasticity). It was given in the manual that using an appropriate DM
>> and calling MatSetValuesBlocked(). I'm however unable to do this for
>> cases where I want to take runtime inputs for physical constants in
>> the matrices.
>>
>> One thing that puzzles me is the use of "const PetscInt*" and "const
>> PetscScalar*" in the declaration of MatSetValuesBlocked(). I can't
>> think of why this is done (if I am to loop through the elements and
>> call this function, I don't see why the indices and/or values must be
>> constant). The declaration I found was:
>>
>> PetscErrorCode <https://www.mcs.anl.gov/petsc/petsc-3.13/docs/manualpages/Sys/PetscErrorCode.html#PetscErrorCode> MatSetValues <https://www.mcs.anl.gov/petsc/petsc-3.13/docs/manualpages/Mat/MatSetValues.html#MatSetValues>(Mat <https://www.mcs.anl.gov/petsc/petsc-3.13/docs/manualpages/Mat/Mat.html#Mat> mat,PetscInt <https://www.mcs.anl.gov/petsc/petsc-3.13/docs/manualpages/Sys/PetscInt.html#PetscInt> m,constPetscInt <https://www.mcs.anl.gov/petsc/petsc-3.13/docs/manualpages/Sys/PetscInt.html#PetscInt> idxm[],PetscInt <https://www.mcs.anl.gov/petsc/petsc-3.13/docs/manualpages/Sys/PetscInt.html#PetscInt> n,constPetscInt <https://www.mcs.anl.gov/petsc/petsc-3.13/docs/manualpages/Sys/PetscInt.html#PetscInt> idxn[],constPetscScalar <https://www.mcs.anl.gov/petsc/petsc-3.13/docs/manualpages/Sys/PetscScalar.html#PetscScalar> v[],InsertMode <https://www.mcs.anl.gov/petsc/petsc-3.13/docs/manualpages/Sys/InsertMode.html#InsertMode> addv)
>>
>> Here's the DM setup for my code:
>>
>> DM mshdm;
>> Mater steel = {1.0, 2e11, 7800, 3.0, 400.0};// A structure with
>> {Area, Modulus, Density, Length, Force} (runtime vars)
>> KSP ksp;
>>
>> DMDACreate1d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, N, 1, 1, NULL,
>> &mshdm);// N is a runtime variable
>> DMSetFromOptions(mshdm);
>> DMSetUp(mshdm);
>> DMSetApplicationContext(mshdm, &steel); /* User Context */
>>
>> KSPCreate(PETSC_COMM_WORLD, &ksp);
>> KSPSetDM(ksp, mshdm);
>> KSPSetComputeRHS(ksp, RHSFun, &steel);
>> KSPSetComputeOperators(ksp, JACFun, &steel);
>> KSPSetFromOptions(ksp);
>>
>> I have no problems with the ComputeRHS function that I wrote, it
>> seems to work fine. The ComputeOperators function on the other hand
>> is giving me an "Argument out of range error" when MatSetValues() is
>> called the second time (for e=1, discovered by debugging). Here's the
>> function definition:
>>
>> PetscErrorCode JACFun(KSP ksp, Mat J, Mat jac, void* ctx)
>> {
>> Mater* pblm = (Mater*)ctx;
>> PetscInt N, ix, n;
>> PetscScalar Le;
>> PetscErrorCode ierr;
>> MatNullSpace nullspc;
>>
>> PetscScalar idx[2], idy[2], elstiff[2][2];// idx, idy are ids
>> for MatSetValues()
>> DM mshdm;
>>
>> ierr = KSPGetDM(ksp, &mshdm);
>> ierr = DMDAGetInfo(mshdm, NULL, &N, NULL, NULL, &n, NULL, NULL,
>> NULL, NULL, NULL, NULL, NULL, NULL);
>> DMDAGetCorners(mshdm, &ix, NULL, NULL, &n, NULL, NULL);
>>
>> // Construct Element Stiffness
>> Le = pblm->L/N;
>> elstiff[0][0] = pblm->A*pblm->E/Le;
>> elstiff[0][1] = -pblm->A*pblm->E/Le;
>> elstiff[1][0] = -pblm->A*pblm->E/Le;
>> elstiff[1][1] = pblm->A*pblm->E/Le;
>>
>> PetscInt is, ie;
>> MatGetOwnershipRange(jac, &is, &ie);
>> for (int e=is; e<((ie<N-1)?ie:(N-1)); ++e) { // Only looping
>> over local elements
>> idx[0] = e; idx[1] = e+1;
>> idy[0] = e; idy[1] = e+1;
>>
>> // This is the version I want to get working, but throws an
>> argument out of range error
>> MatSetValuesBlocked(jac, 2, (const PetscInt*)idx, 2, (const
>> PetscInt*)idy,
>> (const PetscScalar*)elstiff, ADD_VALUES);
>>
>> // This version seemed to not construct the correct matrix
>> (overlapped elements were added)
>> /* MatSetValue(jac, e, e, elstiff[0][0], ADD_VALUES); */
>> /* MatSetValue(jac, e, e+1, elstiff[0][1], ADD_VALUES); */
>> /* MatSetValue(jac, e+1, e, elstiff[1][0], ADD_VALUES); */
>> /* MatSetValue(jac, e+1, e+1, elstiff[1][1], ADD_VALUES); */
>> }
>> MatAssemblyBegin(jac, MAT_FINAL_ASSEMBLY);
>> ierr = MatAssemblyEnd(jac, MAT_FINAL_ASSEMBLY);
>>
>> // I'm doing a "free-free" simulation, so constraining out the
>> nullspace
>> MatNullSpaceCreate(PETSC_COMM_WORLD, PETSC_TRUE, 0, NULL, &nullspc);
>> MatSetNullSpace(J, nullspc);
>> MatNullSpaceDestroy(&nullspc);
>> PetscFunctionReturn(0);
>> }
>>
>>
>> Thank you,
>> Nidish
> --
> Nidish
--
Nidish
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mcs.anl.gov/pipermail/petsc-users/attachments/20200809/f4d26564/attachment.html>
More information about the petsc-users
mailing list