[petsc-users] Using MatSetValuesBlocked to build Finite Element Matrices with variable coefficients
Nidish
nb25 at rice.edu
Sun Aug 9 22:05:19 CDT 2020
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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mcs.anl.gov/pipermail/petsc-users/attachments/20200809/cf16d9bb/attachment-0001.html>
More information about the petsc-users
mailing list