1545aaa6fSHong Zhang #include <petsc/private/tsimpl.h> /*I "petscts.h" I*/
2424fc49dSJoe Pusztay #include <petscdm.h>
TSRHSSplitGetRHSSplit(TS ts,const char splitname[],TS_RHSSplitLink * isplit)3d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRHSSplitGetRHSSplit(TS ts, const char splitname[], TS_RHSSplitLink *isplit)
4d71ae5a4SJacob Faibussowitsch {
51d06f6b3SHong Zhang PetscBool found = PETSC_FALSE;
61d06f6b3SHong Zhang
71d06f6b3SHong Zhang PetscFunctionBegin;
81d06f6b3SHong Zhang *isplit = ts->tsrhssplit;
91d06f6b3SHong Zhang /* look up the split */
101d06f6b3SHong Zhang while (*isplit) {
119566063dSJacob Faibussowitsch PetscCall(PetscStrcmp((*isplit)->splitname, splitname, &found));
121d06f6b3SHong Zhang if (found) break;
131d06f6b3SHong Zhang *isplit = (*isplit)->next;
141d06f6b3SHong Zhang }
153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
161d06f6b3SHong Zhang }
171d06f6b3SHong Zhang
18cc4c1da9SBarry Smith /*@
19545aaa6fSHong Zhang TSRHSSplitSetIS - Set the index set for the specified split
20545aaa6fSHong Zhang
21c3339decSBarry Smith Logically Collective
22545aaa6fSHong Zhang
23545aaa6fSHong Zhang Input Parameters:
24bcf0153eSBarry Smith + ts - the `TS` context obtained from `TSCreate()`
2520f4b53cSBarry Smith . splitname - name of this split, if `NULL` the number of the split is used
26545aaa6fSHong Zhang - is - the index set for part of the solution vector
27545aaa6fSHong Zhang
28545aaa6fSHong Zhang Level: intermediate
29545aaa6fSHong Zhang
30efa39862SBarry Smith .seealso: [](ch_ts), `TS`, `IS`, `TSRHSSplitGetIS()`, `TSARKIMEXSetFastSlowSplit()`
31545aaa6fSHong Zhang @*/
TSRHSSplitSetIS(TS ts,const char splitname[],IS is)32d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRHSSplitSetIS(TS ts, const char splitname[], IS is)
33d71ae5a4SJacob Faibussowitsch {
341d06f6b3SHong Zhang TS_RHSSplitLink newsplit, next = ts->tsrhssplit;
35545aaa6fSHong Zhang char prefix[128];
36545aaa6fSHong Zhang
37545aaa6fSHong Zhang PetscFunctionBegin;
38545aaa6fSHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
39545aaa6fSHong Zhang PetscValidHeaderSpecific(is, IS_CLASSID, 3);
401d06f6b3SHong Zhang
419566063dSJacob Faibussowitsch PetscCall(PetscNew(&newsplit));
42545aaa6fSHong Zhang if (splitname) {
439566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(splitname, &newsplit->splitname));
44545aaa6fSHong Zhang } else {
459566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(8, &newsplit->splitname));
4663a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(newsplit->splitname, 7, "%" PetscInt_FMT, ts->num_rhs_splits));
47545aaa6fSHong Zhang }
489566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)is));
49545aaa6fSHong Zhang newsplit->is = is;
509566063dSJacob Faibussowitsch PetscCall(TSCreate(PetscObjectComm((PetscObject)ts), &newsplit->ts));
51109dc152SHong Zhang
529566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject)newsplit->ts, (PetscObject)ts, 1));
539566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(prefix, sizeof(prefix), "%srhsplit_%s_", ((PetscObject)ts)->prefix ? ((PetscObject)ts)->prefix : "", newsplit->splitname));
549566063dSJacob Faibussowitsch PetscCall(TSSetOptionsPrefix(newsplit->ts, prefix));
551d06f6b3SHong Zhang if (!next) ts->tsrhssplit = newsplit;
561d06f6b3SHong Zhang else {
571d06f6b3SHong Zhang while (next->next) next = next->next;
581d06f6b3SHong Zhang next->next = newsplit;
591d06f6b3SHong Zhang }
601d06f6b3SHong Zhang ts->num_rhs_splits++;
613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
62545aaa6fSHong Zhang }
63545aaa6fSHong Zhang
64cc4c1da9SBarry Smith /*@
65bcf0153eSBarry Smith TSRHSSplitGetIS - Retrieves the elements for a split as an `IS`
66545aaa6fSHong Zhang
67c3339decSBarry Smith Logically Collective
68545aaa6fSHong Zhang
69545aaa6fSHong Zhang Input Parameters:
70bcf0153eSBarry Smith + ts - the `TS` context obtained from `TSCreate()`
71545aaa6fSHong Zhang - splitname - name of this split
72545aaa6fSHong Zhang
732fe279fdSBarry Smith Output Parameter:
742fe279fdSBarry Smith . is - the index set for part of the solution vector
75545aaa6fSHong Zhang
76545aaa6fSHong Zhang Level: intermediate
77545aaa6fSHong Zhang
781cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `IS`, `TSRHSSplitSetIS()`
79545aaa6fSHong Zhang @*/
TSRHSSplitGetIS(TS ts,const char splitname[],IS * is)80d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRHSSplitGetIS(TS ts, const char splitname[], IS *is)
81d71ae5a4SJacob Faibussowitsch {
821d06f6b3SHong Zhang TS_RHSSplitLink isplit;
83545aaa6fSHong Zhang
84545aaa6fSHong Zhang PetscFunctionBegin;
85545aaa6fSHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
861d06f6b3SHong Zhang *is = NULL;
87545aaa6fSHong Zhang /* look up the split */
889566063dSJacob Faibussowitsch PetscCall(TSRHSSplitGetRHSSplit(ts, splitname, &isplit));
891d06f6b3SHong Zhang if (isplit) *is = isplit->is;
903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
91545aaa6fSHong Zhang }
92545aaa6fSHong Zhang
93545aaa6fSHong Zhang /*@C
94545aaa6fSHong Zhang TSRHSSplitSetRHSFunction - Set the split right-hand-side functions.
95545aaa6fSHong Zhang
96c3339decSBarry Smith Logically Collective
97545aaa6fSHong Zhang
98545aaa6fSHong Zhang Input Parameters:
99bcf0153eSBarry Smith + ts - the `TS` context obtained from `TSCreate()`
100545aaa6fSHong Zhang . splitname - name of this split
10120f4b53cSBarry Smith . r - vector to hold the residual (or `NULL` to have it created internally)
102545aaa6fSHong Zhang . rhsfunc - the RHS function evaluation routine
10320f4b53cSBarry Smith - ctx - user-defined context for private data for the split function evaluation routine (may be `NULL`)
104545aaa6fSHong Zhang
10520f4b53cSBarry Smith Level: intermediate
106545aaa6fSHong Zhang
1078434afd1SBarry Smith .seealso: [](ch_ts), `TS`, `TSRHSFunctionFn`, `IS`, `TSRHSSplitSetIS()`
108545aaa6fSHong Zhang @*/
TSRHSSplitSetRHSFunction(TS ts,const char splitname[],Vec r,TSRHSFunctionFn * rhsfunc,PetscCtx ctx)109*2a8381b2SBarry Smith PetscErrorCode TSRHSSplitSetRHSFunction(TS ts, const char splitname[], Vec r, TSRHSFunctionFn *rhsfunc, PetscCtx ctx)
110d71ae5a4SJacob Faibussowitsch {
1111d06f6b3SHong Zhang TS_RHSSplitLink isplit;
112424fc49dSJoe Pusztay DM dmc;
113545aaa6fSHong Zhang Vec subvec, ralloc = NULL;
114545aaa6fSHong Zhang
115545aaa6fSHong Zhang PetscFunctionBegin;
116545aaa6fSHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
117064a246eSJacob Faibussowitsch if (r) PetscValidHeaderSpecific(r, VEC_CLASSID, 3);
118545aaa6fSHong Zhang
119545aaa6fSHong Zhang /* look up the split */
1209566063dSJacob Faibussowitsch PetscCall(TSRHSSplitGetRHSSplit(ts, splitname, &isplit));
1213c633725SBarry Smith PetscCheck(isplit, PETSC_COMM_SELF, PETSC_ERR_USER, "The split %s is not created, check the split name or call TSRHSSplitSetIS() to create one", splitname);
122545aaa6fSHong Zhang
1231d06f6b3SHong Zhang if (!r && ts->vec_sol) {
1249566063dSJacob Faibussowitsch PetscCall(VecGetSubVector(ts->vec_sol, isplit->is, &subvec));
1259566063dSJacob Faibussowitsch PetscCall(VecDuplicate(subvec, &ralloc));
126545aaa6fSHong Zhang r = ralloc;
1279566063dSJacob Faibussowitsch PetscCall(VecRestoreSubVector(ts->vec_sol, isplit->is, &subvec));
128545aaa6fSHong Zhang }
129424fc49dSJoe Pusztay
130424fc49dSJoe Pusztay if (ts->dm) {
131424fc49dSJoe Pusztay PetscInt dim;
132424fc49dSJoe Pusztay
1339566063dSJacob Faibussowitsch PetscCall(DMGetDimension(ts->dm, &dim));
134424fc49dSJoe Pusztay if (dim != -1) {
1359566063dSJacob Faibussowitsch PetscCall(DMClone(ts->dm, &dmc));
1369566063dSJacob Faibussowitsch PetscCall(TSSetDM(isplit->ts, dmc));
1379566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dmc));
138424fc49dSJoe Pusztay }
139424fc49dSJoe Pusztay }
140424fc49dSJoe Pusztay
1419566063dSJacob Faibussowitsch PetscCall(TSSetRHSFunction(isplit->ts, r, rhsfunc, ctx));
1429566063dSJacob Faibussowitsch PetscCall(VecDestroy(&ralloc));
1433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
144545aaa6fSHong Zhang }
145545aaa6fSHong Zhang
1463a2a065fSHong Zhang /*@C
1473a2a065fSHong Zhang TSRHSSplitSetIFunction - Set the split implicit function for `TSARKIMEX`
1483a2a065fSHong Zhang
1493a2a065fSHong Zhang Logically Collective
1503a2a065fSHong Zhang
1513a2a065fSHong Zhang Input Parameters:
1523a2a065fSHong Zhang + ts - the `TS` context obtained from `TSCreate()`
1533a2a065fSHong Zhang . splitname - name of this split
1543a2a065fSHong Zhang . r - vector to hold the residual (or `NULL` to have it created internally)
1553a2a065fSHong Zhang . ifunc - the implicit function evaluation routine
1563a2a065fSHong Zhang - ctx - user-defined context for private data for the split function evaluation routine (may be `NULL`)
1573a2a065fSHong Zhang
1583a2a065fSHong Zhang Level: intermediate
1593a2a065fSHong Zhang
160efa39862SBarry Smith .seealso: [](ch_ts), `TS`, `TSIFunctionFn`, `IS`, `TSRHSSplitSetIS()`, `TSARKIMEX`, `TSARKIMEXSetFastSlowSplit()`
1613a2a065fSHong Zhang @*/
TSRHSSplitSetIFunction(TS ts,const char splitname[],Vec r,TSIFunctionFn * ifunc,PetscCtx ctx)162*2a8381b2SBarry Smith PetscErrorCode TSRHSSplitSetIFunction(TS ts, const char splitname[], Vec r, TSIFunctionFn *ifunc, PetscCtx ctx)
1633a2a065fSHong Zhang {
1643a2a065fSHong Zhang TS_RHSSplitLink isplit;
1653a2a065fSHong Zhang DM dmc;
1663a2a065fSHong Zhang Vec subvec, ralloc = NULL;
1673a2a065fSHong Zhang
1683a2a065fSHong Zhang PetscFunctionBegin;
1693a2a065fSHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1703a2a065fSHong Zhang if (r) PetscValidHeaderSpecific(r, VEC_CLASSID, 3);
1713a2a065fSHong Zhang
1723a2a065fSHong Zhang /* look up the split */
1733a2a065fSHong Zhang PetscCall(TSRHSSplitGetRHSSplit(ts, splitname, &isplit));
1743a2a065fSHong Zhang PetscCheck(isplit, PETSC_COMM_SELF, PETSC_ERR_USER, "The split %s is not created, check the split name or call TSRHSSplitSetIS() to create one", splitname);
1753a2a065fSHong Zhang
1763a2a065fSHong Zhang if (!r && ts->vec_sol) {
1773a2a065fSHong Zhang PetscCall(VecGetSubVector(ts->vec_sol, isplit->is, &subvec));
1783a2a065fSHong Zhang PetscCall(VecDuplicate(subvec, &ralloc));
1793a2a065fSHong Zhang r = ralloc;
1803a2a065fSHong Zhang PetscCall(VecRestoreSubVector(ts->vec_sol, isplit->is, &subvec));
1813a2a065fSHong Zhang }
1823a2a065fSHong Zhang
1833a2a065fSHong Zhang if (ts->dm) {
1843a2a065fSHong Zhang PetscInt dim;
1853a2a065fSHong Zhang
1863a2a065fSHong Zhang PetscCall(DMGetDimension(ts->dm, &dim));
1873a2a065fSHong Zhang if (dim != -1) {
1883a2a065fSHong Zhang PetscCall(DMClone(ts->dm, &dmc));
1893a2a065fSHong Zhang PetscCall(TSSetDM(isplit->ts, dmc));
1903a2a065fSHong Zhang PetscCall(DMDestroy(&dmc));
1913a2a065fSHong Zhang }
1923a2a065fSHong Zhang }
1933a2a065fSHong Zhang
1943a2a065fSHong Zhang PetscCall(TSSetIFunction(isplit->ts, r, ifunc, ctx));
1953a2a065fSHong Zhang PetscCall(VecDestroy(&ralloc));
1963a2a065fSHong Zhang PetscFunctionReturn(PETSC_SUCCESS);
1973a2a065fSHong Zhang }
1983a2a065fSHong Zhang
1993a2a065fSHong Zhang /*@C
2003a2a065fSHong Zhang TSRHSSplitSetIJacobian - Set the Jacobian for the split implicit function with `TSARKIMEX`
2013a2a065fSHong Zhang
2023a2a065fSHong Zhang Logically Collective
2033a2a065fSHong Zhang
2043a2a065fSHong Zhang Input Parameters:
2053a2a065fSHong Zhang + ts - the `TS` context obtained from `TSCreate()`
2063a2a065fSHong Zhang . splitname - name of this split
2073a2a065fSHong Zhang . Amat - (approximate) matrix to store Jacobian entries computed by `f`
2083a2a065fSHong Zhang . Pmat - matrix used to compute preconditioner (usually the same as `Amat`)
2093a2a065fSHong Zhang . ijac - the Jacobian evaluation routine
2103a2a065fSHong Zhang - ctx - user-defined context for private data for the split function evaluation routine (may be `NULL`)
2113a2a065fSHong Zhang
2123a2a065fSHong Zhang Level: intermediate
2133a2a065fSHong Zhang
214efa39862SBarry Smith .seealso: [](ch_ts), `TS`, `TSRHSSplitSetIFunction`, `TSIJacobianFn`, `IS`, `TSRHSSplitSetIS()`, `TSARKIMEXSetFastSlowSplit()`
2153a2a065fSHong Zhang @*/
TSRHSSplitSetIJacobian(TS ts,const char splitname[],Mat Amat,Mat Pmat,TSIJacobianFn * ijac,PetscCtx ctx)216*2a8381b2SBarry Smith PetscErrorCode TSRHSSplitSetIJacobian(TS ts, const char splitname[], Mat Amat, Mat Pmat, TSIJacobianFn *ijac, PetscCtx ctx)
2173a2a065fSHong Zhang {
2183a2a065fSHong Zhang TS_RHSSplitLink isplit;
2193a2a065fSHong Zhang DM dmc;
2203a2a065fSHong Zhang
2213a2a065fSHong Zhang PetscFunctionBegin;
2223a2a065fSHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2233a2a065fSHong Zhang if (Amat) PetscValidHeaderSpecific(Amat, MAT_CLASSID, 3);
2243a2a065fSHong Zhang if (Pmat) PetscValidHeaderSpecific(Pmat, MAT_CLASSID, 4);
2253a2a065fSHong Zhang if (Amat) PetscCheckSameComm(ts, 1, Amat, 3);
2263a2a065fSHong Zhang if (Pmat) PetscCheckSameComm(ts, 1, Pmat, 4);
2273a2a065fSHong Zhang
2283a2a065fSHong Zhang /* look up the split */
2293a2a065fSHong Zhang PetscCall(TSRHSSplitGetRHSSplit(ts, splitname, &isplit));
2303a2a065fSHong Zhang PetscCheck(isplit, PETSC_COMM_SELF, PETSC_ERR_USER, "The split %s is not created, check the split name or call TSRHSSplitSetIS() to create one", splitname);
2313a2a065fSHong Zhang
2323a2a065fSHong Zhang if (ts->dm) {
2333a2a065fSHong Zhang PetscInt dim;
2343a2a065fSHong Zhang
2353a2a065fSHong Zhang PetscCall(DMGetDimension(ts->dm, &dim));
2363a2a065fSHong Zhang if (dim != -1) {
2373a2a065fSHong Zhang PetscCall(DMClone(ts->dm, &dmc));
2383a2a065fSHong Zhang PetscCall(TSSetDM(isplit->ts, dmc));
2393a2a065fSHong Zhang PetscCall(DMDestroy(&dmc));
2403a2a065fSHong Zhang }
2413a2a065fSHong Zhang }
2423a2a065fSHong Zhang
2433a2a065fSHong Zhang PetscCall(TSSetIJacobian(isplit->ts, Amat, Pmat, ijac, ctx));
2443a2a065fSHong Zhang PetscFunctionReturn(PETSC_SUCCESS);
2453a2a065fSHong Zhang }
2463a2a065fSHong Zhang
2473a2a065fSHong Zhang /*@C
248bcf0153eSBarry Smith TSRHSSplitGetSubTS - Get the sub-`TS` by split name.
2491d06f6b3SHong Zhang
250c3339decSBarry Smith Logically Collective
2511d06f6b3SHong Zhang
2526b867d5aSJose E. Roman Input Parameter:
253bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()`
2546b867d5aSJose E. Roman
2551d06f6b3SHong Zhang Output Parameters:
2561d06f6b3SHong Zhang + splitname - the number of the split
25720f4b53cSBarry Smith - subts - the sub-`TS`
2581d06f6b3SHong Zhang
2591d06f6b3SHong Zhang Level: advanced
2601d06f6b3SHong Zhang
2611cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `IS`, `TSGetRHSSplitFunction()`
2621d06f6b3SHong Zhang @*/
TSRHSSplitGetSubTS(TS ts,const char splitname[],TS * subts)263d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRHSSplitGetSubTS(TS ts, const char splitname[], TS *subts)
264d71ae5a4SJacob Faibussowitsch {
2651d06f6b3SHong Zhang TS_RHSSplitLink isplit;
2661d06f6b3SHong Zhang
2671d06f6b3SHong Zhang PetscFunctionBegin;
2681d06f6b3SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2694f572ea9SToby Isaac PetscAssertPointer(subts, 3);
2701d06f6b3SHong Zhang *subts = NULL;
2711d06f6b3SHong Zhang /* look up the split */
2729566063dSJacob Faibussowitsch PetscCall(TSRHSSplitGetRHSSplit(ts, splitname, &isplit));
2731d06f6b3SHong Zhang if (isplit) *subts = isplit->ts;
2743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2751d06f6b3SHong Zhang }
2761d06f6b3SHong Zhang
2771d06f6b3SHong Zhang /*@C
278bcf0153eSBarry Smith TSRHSSplitGetSubTSs - Get an array of all sub-`TS` contexts.
279545aaa6fSHong Zhang
280c3339decSBarry Smith Logically Collective
281545aaa6fSHong Zhang
2826b867d5aSJose E. Roman Input Parameter:
283bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()`
2846b867d5aSJose E. Roman
285545aaa6fSHong Zhang Output Parameters:
286545aaa6fSHong Zhang + n - the number of splits
287b43aa488SJacob Faibussowitsch - subts - the array of `TS` contexts
288545aaa6fSHong Zhang
289545aaa6fSHong Zhang Level: advanced
290545aaa6fSHong Zhang
291bcf0153eSBarry Smith Note:
292bcf0153eSBarry Smith After `TSRHSSplitGetSubTS()` the array of `TS`s is to be freed by the user with `PetscFree()`
29320f4b53cSBarry Smith (not the `TS` in the array just the array that contains them).
294bcf0153eSBarry Smith
2951cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `IS`, `TSGetRHSSplitFunction()`
296545aaa6fSHong Zhang @*/
TSRHSSplitGetSubTSs(TS ts,PetscInt * n,TS * subts[])297d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRHSSplitGetSubTSs(TS ts, PetscInt *n, TS *subts[])
298d71ae5a4SJacob Faibussowitsch {
2991d06f6b3SHong Zhang TS_RHSSplitLink ilink = ts->tsrhssplit;
300545aaa6fSHong Zhang PetscInt i = 0;
301545aaa6fSHong Zhang
302545aaa6fSHong Zhang PetscFunctionBegin;
303545aaa6fSHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
304545aaa6fSHong Zhang if (subts) {
3059566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(ts->num_rhs_splits, subts));
3061d06f6b3SHong Zhang while (ilink) {
3071d06f6b3SHong Zhang (*subts)[i++] = ilink->ts;
3081d06f6b3SHong Zhang ilink = ilink->next;
309545aaa6fSHong Zhang }
310545aaa6fSHong Zhang }
311545aaa6fSHong Zhang if (n) *n = ts->num_rhs_splits;
3123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
313545aaa6fSHong Zhang }
3144bd3aaa3SHong Zhang
3154bd3aaa3SHong Zhang /*@
3164bd3aaa3SHong Zhang TSRHSSplitGetSNES - Returns the `SNES` (nonlinear solver) associated with
3174bd3aaa3SHong Zhang a `TS` (timestepper) context when RHS splits are used.
3184bd3aaa3SHong Zhang
319efa39862SBarry Smith Not Collective, but `snes` is parallel if `ts` is parallel
3204bd3aaa3SHong Zhang
3214bd3aaa3SHong Zhang Input Parameter:
3224bd3aaa3SHong Zhang . ts - the `TS` context obtained from `TSCreate()`
3234bd3aaa3SHong Zhang
3244bd3aaa3SHong Zhang Output Parameter:
3254bd3aaa3SHong Zhang . snes - the nonlinear solver context
3264bd3aaa3SHong Zhang
3274bd3aaa3SHong Zhang Level: intermediate
3284bd3aaa3SHong Zhang
3294bd3aaa3SHong Zhang Note:
3304bd3aaa3SHong Zhang The returned `SNES` may have a different `DM` with the `TS` `DM`.
3314bd3aaa3SHong Zhang
3324bd3aaa3SHong Zhang .seealso: [](ch_ts), `TS`, `SNES`, `TSCreate()`, `TSRHSSplitSetSNES()`
3334bd3aaa3SHong Zhang @*/
TSRHSSplitGetSNES(TS ts,SNES * snes)3344bd3aaa3SHong Zhang PetscErrorCode TSRHSSplitGetSNES(TS ts, SNES *snes)
3354bd3aaa3SHong Zhang {
3364bd3aaa3SHong Zhang PetscFunctionBegin;
3374bd3aaa3SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3384bd3aaa3SHong Zhang PetscAssertPointer(snes, 2);
3394bd3aaa3SHong Zhang if (!ts->snesrhssplit) {
3404bd3aaa3SHong Zhang PetscCall(SNESCreate(PetscObjectComm((PetscObject)ts), &ts->snesrhssplit));
3414bd3aaa3SHong Zhang PetscCall(PetscObjectSetOptions((PetscObject)ts->snesrhssplit, ((PetscObject)ts)->options));
3424bd3aaa3SHong Zhang PetscCall(SNESSetFunction(ts->snesrhssplit, NULL, SNESTSFormFunction, ts));
3434bd3aaa3SHong Zhang PetscCall(PetscObjectIncrementTabLevel((PetscObject)ts->snesrhssplit, (PetscObject)ts, 1));
3444bd3aaa3SHong Zhang if (ts->problem_type == TS_LINEAR) PetscCall(SNESSetType(ts->snesrhssplit, SNESKSPONLY));
3454bd3aaa3SHong Zhang }
3464bd3aaa3SHong Zhang *snes = ts->snesrhssplit;
3474bd3aaa3SHong Zhang PetscFunctionReturn(PETSC_SUCCESS);
3484bd3aaa3SHong Zhang }
3494bd3aaa3SHong Zhang
3504bd3aaa3SHong Zhang /*@
3514bd3aaa3SHong Zhang TSRHSSplitSetSNES - Set the `SNES` (nonlinear solver) to be used by the
3524bd3aaa3SHong Zhang timestepping context when RHS splits are used.
3534bd3aaa3SHong Zhang
3544bd3aaa3SHong Zhang Collective
3554bd3aaa3SHong Zhang
3564bd3aaa3SHong Zhang Input Parameters:
3574bd3aaa3SHong Zhang + ts - the `TS` context obtained from `TSCreate()`
3584bd3aaa3SHong Zhang - snes - the nonlinear solver context
3594bd3aaa3SHong Zhang
3604bd3aaa3SHong Zhang Level: intermediate
3614bd3aaa3SHong Zhang
3624bd3aaa3SHong Zhang Note:
3634bd3aaa3SHong Zhang Most users should have the `TS` created by calling `TSRHSSplitGetSNES()`
3644bd3aaa3SHong Zhang
3654bd3aaa3SHong Zhang .seealso: [](ch_ts), `TS`, `SNES`, `TSCreate()`, `TSRHSSplitGetSNES()`
3664bd3aaa3SHong Zhang @*/
TSRHSSplitSetSNES(TS ts,SNES snes)3674bd3aaa3SHong Zhang PetscErrorCode TSRHSSplitSetSNES(TS ts, SNES snes)
3684bd3aaa3SHong Zhang {
3694bd3aaa3SHong Zhang PetscErrorCode (*func)(SNES, Vec, Mat, Mat, void *);
3704bd3aaa3SHong Zhang
3714bd3aaa3SHong Zhang PetscFunctionBegin;
3724bd3aaa3SHong Zhang PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3734bd3aaa3SHong Zhang PetscValidHeaderSpecific(snes, SNES_CLASSID, 2);
3744bd3aaa3SHong Zhang PetscCall(PetscObjectReference((PetscObject)snes));
3754bd3aaa3SHong Zhang PetscCall(SNESDestroy(&ts->snesrhssplit));
3764bd3aaa3SHong Zhang
3774bd3aaa3SHong Zhang ts->snesrhssplit = snes;
3784bd3aaa3SHong Zhang
3794bd3aaa3SHong Zhang PetscCall(SNESSetFunction(ts->snesrhssplit, NULL, SNESTSFormFunction, ts));
3804bd3aaa3SHong Zhang PetscCall(SNESGetJacobian(ts->snesrhssplit, NULL, NULL, &func, NULL));
3814bd3aaa3SHong Zhang if (func == SNESTSFormJacobian) PetscCall(SNESSetJacobian(ts->snesrhssplit, NULL, NULL, SNESTSFormJacobian, ts));
3824bd3aaa3SHong Zhang PetscFunctionReturn(PETSC_SUCCESS);
3834bd3aaa3SHong Zhang }
384