xref: /petsc/src/ts/interface/tsrhssplit.c (revision 1cc06b555e92f8ec64db10330b8bbd830e5bc876)
1545aaa6fSHong Zhang #include <petsc/private/tsimpl.h> /*I "petscts.h"  I*/
2424fc49dSJoe Pusztay #include <petscdm.h>
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 
18545aaa6fSHong Zhang /*@C
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 
30*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `IS`, `TSRHSSplitGetIS()`
31545aaa6fSHong Zhang @*/
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 
64545aaa6fSHong Zhang /*@C
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 
78*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `IS`, `TSRHSSplitSetIS()`
79545aaa6fSHong Zhang @*/
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  Calling sequence of `rhsfun`:
10620f4b53cSBarry Smith $  PetscErrorCode rhsfunc(TS ts, PetscReal t, Vec u, Vec f,ctx)
10720f4b53cSBarry Smith +  ts  - the `TS` context obtained from `TSCreate()`
10820f4b53cSBarry Smith .  t    - time at step/stage being solved
109545aaa6fSHong Zhang .  u    - state vector
110545aaa6fSHong Zhang .  f    - function vector
11120f4b53cSBarry Smith -  ctx  - [optional] user-defined context for matrix evaluation routine (may be `NULL`)
112545aaa6fSHong Zhang 
11320f4b53cSBarry Smith  Level: intermediate
114545aaa6fSHong Zhang 
115*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSRHSFunction`, `IS`, `TSRHSSplitSetIS()`
116545aaa6fSHong Zhang @*/
117d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRHSSplitSetRHSFunction(TS ts, const char splitname[], Vec r, TSRHSFunction rhsfunc, void *ctx)
118d71ae5a4SJacob Faibussowitsch {
1191d06f6b3SHong Zhang   TS_RHSSplitLink isplit;
120424fc49dSJoe Pusztay   DM              dmc;
121545aaa6fSHong Zhang   Vec             subvec, ralloc = NULL;
122545aaa6fSHong Zhang 
123545aaa6fSHong Zhang   PetscFunctionBegin;
124545aaa6fSHong Zhang   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
125064a246eSJacob Faibussowitsch   if (r) PetscValidHeaderSpecific(r, VEC_CLASSID, 3);
126545aaa6fSHong Zhang 
127545aaa6fSHong Zhang   /* look up the split */
1289566063dSJacob Faibussowitsch   PetscCall(TSRHSSplitGetRHSSplit(ts, splitname, &isplit));
1293c633725SBarry 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);
130545aaa6fSHong Zhang 
1311d06f6b3SHong Zhang   if (!r && ts->vec_sol) {
1329566063dSJacob Faibussowitsch     PetscCall(VecGetSubVector(ts->vec_sol, isplit->is, &subvec));
1339566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(subvec, &ralloc));
134545aaa6fSHong Zhang     r = ralloc;
1359566063dSJacob Faibussowitsch     PetscCall(VecRestoreSubVector(ts->vec_sol, isplit->is, &subvec));
136545aaa6fSHong Zhang   }
137424fc49dSJoe Pusztay 
138424fc49dSJoe Pusztay   if (ts->dm) {
139424fc49dSJoe Pusztay     PetscInt dim;
140424fc49dSJoe Pusztay 
1419566063dSJacob Faibussowitsch     PetscCall(DMGetDimension(ts->dm, &dim));
142424fc49dSJoe Pusztay     if (dim != -1) {
1439566063dSJacob Faibussowitsch       PetscCall(DMClone(ts->dm, &dmc));
1449566063dSJacob Faibussowitsch       PetscCall(TSSetDM(isplit->ts, dmc));
1459566063dSJacob Faibussowitsch       PetscCall(DMDestroy(&dmc));
146424fc49dSJoe Pusztay     }
147424fc49dSJoe Pusztay   }
148424fc49dSJoe Pusztay 
1499566063dSJacob Faibussowitsch   PetscCall(TSSetRHSFunction(isplit->ts, r, rhsfunc, ctx));
1509566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ralloc));
1513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
152545aaa6fSHong Zhang }
153545aaa6fSHong Zhang 
154545aaa6fSHong Zhang /*@C
155bcf0153eSBarry Smith    TSRHSSplitGetSubTS - Get the sub-`TS` by split name.
1561d06f6b3SHong Zhang 
157c3339decSBarry Smith    Logically Collective
1581d06f6b3SHong Zhang 
1596b867d5aSJose E. Roman    Input Parameter:
160bcf0153eSBarry Smith .  ts - the `TS` context obtained from `TSCreate()`
1616b867d5aSJose E. Roman 
1621d06f6b3SHong Zhang    Output Parameters:
1631d06f6b3SHong Zhang +  splitname - the number of the split
16420f4b53cSBarry Smith -  subts - the sub-`TS`
1651d06f6b3SHong Zhang 
1661d06f6b3SHong Zhang    Level: advanced
1671d06f6b3SHong Zhang 
168*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `IS`, `TSGetRHSSplitFunction()`
1691d06f6b3SHong Zhang @*/
170d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRHSSplitGetSubTS(TS ts, const char splitname[], TS *subts)
171d71ae5a4SJacob Faibussowitsch {
1721d06f6b3SHong Zhang   TS_RHSSplitLink isplit;
1731d06f6b3SHong Zhang 
1741d06f6b3SHong Zhang   PetscFunctionBegin;
1751d06f6b3SHong Zhang   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1761d06f6b3SHong Zhang   PetscValidPointer(subts, 3);
1771d06f6b3SHong Zhang   *subts = NULL;
1781d06f6b3SHong Zhang   /* look up the split */
1799566063dSJacob Faibussowitsch   PetscCall(TSRHSSplitGetRHSSplit(ts, splitname, &isplit));
1801d06f6b3SHong Zhang   if (isplit) *subts = isplit->ts;
1813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1821d06f6b3SHong Zhang }
1831d06f6b3SHong Zhang 
1841d06f6b3SHong Zhang /*@C
185bcf0153eSBarry Smith    TSRHSSplitGetSubTSs - Get an array of all sub-`TS` contexts.
186545aaa6fSHong Zhang 
187c3339decSBarry Smith    Logically Collective
188545aaa6fSHong Zhang 
1896b867d5aSJose E. Roman    Input Parameter:
190bcf0153eSBarry Smith .  ts - the `TS` context obtained from `TSCreate()`
1916b867d5aSJose E. Roman 
192545aaa6fSHong Zhang    Output Parameters:
193545aaa6fSHong Zhang +  n - the number of splits
194bcf0153eSBarry Smith -  subksp - the array of `TS` contexts
195545aaa6fSHong Zhang 
196545aaa6fSHong Zhang    Level: advanced
197545aaa6fSHong Zhang 
198bcf0153eSBarry Smith    Note:
199bcf0153eSBarry Smith    After `TSRHSSplitGetSubTS()` the array of `TS`s is to be freed by the user with `PetscFree()`
20020f4b53cSBarry Smith    (not the `TS` in the array just the array that contains them).
201bcf0153eSBarry Smith 
202*1cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `IS`, `TSGetRHSSplitFunction()`
203545aaa6fSHong Zhang @*/
204d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRHSSplitGetSubTSs(TS ts, PetscInt *n, TS *subts[])
205d71ae5a4SJacob Faibussowitsch {
2061d06f6b3SHong Zhang   TS_RHSSplitLink ilink = ts->tsrhssplit;
207545aaa6fSHong Zhang   PetscInt        i     = 0;
208545aaa6fSHong Zhang 
209545aaa6fSHong Zhang   PetscFunctionBegin;
210545aaa6fSHong Zhang   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
211545aaa6fSHong Zhang   if (subts) {
2129566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(ts->num_rhs_splits, subts));
2131d06f6b3SHong Zhang     while (ilink) {
2141d06f6b3SHong Zhang       (*subts)[i++] = ilink->ts;
2151d06f6b3SHong Zhang       ilink         = ilink->next;
216545aaa6fSHong Zhang     }
217545aaa6fSHong Zhang   }
218545aaa6fSHong Zhang   if (n) *n = ts->num_rhs_splits;
2193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
220545aaa6fSHong Zhang }
221