xref: /petsc/src/ts/interface/tsrhssplit.c (revision 545aaa6f248f4d02efcfa901a11a18c680409921)
1*545aaa6fSHong Zhang #include <petsc/private/tsimpl.h>        /*I "petscts.h"  I*/
2*545aaa6fSHong Zhang 
3*545aaa6fSHong Zhang /*@C
4*545aaa6fSHong Zhang    TSRHSSplitSetIS - Set the index set for the specified split
5*545aaa6fSHong Zhang 
6*545aaa6fSHong Zhang    Logically Collective on TS
7*545aaa6fSHong Zhang 
8*545aaa6fSHong Zhang    Input Parameters:
9*545aaa6fSHong Zhang +  ts        - the TS context obtained from TSCreate()
10*545aaa6fSHong Zhang .  splitname - name of this split, if NULL the number of the split is used
11*545aaa6fSHong Zhang -  is        - the index set for part of the solution vector
12*545aaa6fSHong Zhang 
13*545aaa6fSHong Zhang    Level: intermediate
14*545aaa6fSHong Zhang 
15*545aaa6fSHong Zhang .seealso: TSRHSSplitGetIS
16*545aaa6fSHong Zhang 
17*545aaa6fSHong Zhang .keywords: TS, TSRHSSplit
18*545aaa6fSHong Zhang @*/
19*545aaa6fSHong Zhang PetscErrorCode TSRHSSplitSetIS(TS ts,const char splitname[],IS is)
20*545aaa6fSHong Zhang {
21*545aaa6fSHong Zhang   TS_RHSSplit    newsplit;
22*545aaa6fSHong Zhang   char           prefix[128];
23*545aaa6fSHong Zhang   PetscErrorCode ierr;
24*545aaa6fSHong Zhang 
25*545aaa6fSHong Zhang   PetscFunctionBegin;
26*545aaa6fSHong Zhang   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
27*545aaa6fSHong Zhang   PetscValidHeaderSpecific(is,IS_CLASSID,3);
28*545aaa6fSHong Zhang   if (ts->num_rhs_splits == MAXRHSSPLITS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"MAXIMUM number of splits reached");
29*545aaa6fSHong Zhang   ierr = PetscNew(&newsplit);CHKERRQ(ierr);
30*545aaa6fSHong Zhang   if (splitname) {
31*545aaa6fSHong Zhang     ierr = PetscStrallocpy(splitname,&newsplit->splitname);CHKERRQ(ierr);
32*545aaa6fSHong Zhang   } else {
33*545aaa6fSHong Zhang     ierr = PetscMalloc1(8,&newsplit->splitname);CHKERRQ(ierr);
34*545aaa6fSHong Zhang     ierr = PetscSNPrintf(newsplit->splitname,7,"%D",ts->num_rhs_splits);CHKERRQ(ierr);
35*545aaa6fSHong Zhang   }
36*545aaa6fSHong Zhang   ierr = PetscObjectReference((PetscObject)is);CHKERRQ(ierr);
37*545aaa6fSHong Zhang   newsplit->is = is;
38*545aaa6fSHong Zhang   ierr = TSCreate(PetscObjectComm((PetscObject)ts),&newsplit->ts);CHKERRQ(ierr);
39*545aaa6fSHong Zhang   ierr = PetscObjectIncrementTabLevel((PetscObject)newsplit->ts,(PetscObject)ts,1);CHKERRQ(ierr);
40*545aaa6fSHong Zhang   ierr = PetscLogObjectParent((PetscObject)ts,(PetscObject)newsplit->ts);CHKERRQ(ierr);
41*545aaa6fSHong Zhang   ierr = PetscSNPrintf(prefix,sizeof(prefix),"%srhsplit_%s_",((PetscObject)ts)->prefix ? ((PetscObject)ts)->prefix : "",newsplit->splitname);
42*545aaa6fSHong Zhang   ierr = TSSetOptionsPrefix(newsplit->ts,prefix);CHKERRQ(ierr);
43*545aaa6fSHong Zhang   ts->tsrhssplit[ts->num_rhs_splits++] = newsplit;
44*545aaa6fSHong Zhang   PetscFunctionReturn(0);
45*545aaa6fSHong Zhang }
46*545aaa6fSHong Zhang 
47*545aaa6fSHong Zhang /*@C
48*545aaa6fSHong Zhang    TSRHSSplitGetIS - Retrieves the elements for a split as an IS
49*545aaa6fSHong Zhang 
50*545aaa6fSHong Zhang    Logically Collective on TS
51*545aaa6fSHong Zhang 
52*545aaa6fSHong Zhang    Input Parameters:
53*545aaa6fSHong Zhang +  ts        - the TS context obtained from TSCreate()
54*545aaa6fSHong Zhang -  splitname - name of this split
55*545aaa6fSHong Zhang 
56*545aaa6fSHong Zhang    Output Parameters:
57*545aaa6fSHong Zhang -  is        - the index set for part of the solution vector
58*545aaa6fSHong Zhang 
59*545aaa6fSHong Zhang    Level: intermediate
60*545aaa6fSHong Zhang 
61*545aaa6fSHong Zhang .seealso: TSRHSSplitSetIS
62*545aaa6fSHong Zhang 
63*545aaa6fSHong Zhang .keywords: TS, TSRHSSplit
64*545aaa6fSHong Zhang @*/
65*545aaa6fSHong Zhang PetscErrorCode TSRHSSplitGetIS(TS ts,const char splitname[],IS *is)
66*545aaa6fSHong Zhang {
67*545aaa6fSHong Zhang   PetscInt       i = 0;
68*545aaa6fSHong Zhang   PetscBool      found = PETSC_FALSE;
69*545aaa6fSHong Zhang   PetscErrorCode ierr;
70*545aaa6fSHong Zhang 
71*545aaa6fSHong Zhang   PetscFunctionBegin;
72*545aaa6fSHong Zhang   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
73*545aaa6fSHong Zhang   /* look up the split */
74*545aaa6fSHong Zhang   while (i<ts->num_rhs_splits) {
75*545aaa6fSHong Zhang     ierr = PetscStrcmp(ts->tsrhssplit[i]->splitname,splitname,&found);CHKERRQ(ierr);
76*545aaa6fSHong Zhang     if (found) {
77*545aaa6fSHong Zhang       *is = ts->tsrhssplit[i]->is;
78*545aaa6fSHong Zhang       break;
79*545aaa6fSHong Zhang     }
80*545aaa6fSHong Zhang     i++;
81*545aaa6fSHong Zhang   }
82*545aaa6fSHong Zhang   PetscFunctionReturn(0);
83*545aaa6fSHong Zhang }
84*545aaa6fSHong Zhang 
85*545aaa6fSHong Zhang /*@C
86*545aaa6fSHong Zhang    TSRHSSplitSetRHSFunction - Set the split right-hand-side functions.
87*545aaa6fSHong Zhang 
88*545aaa6fSHong Zhang    Logically Collective on TS
89*545aaa6fSHong Zhang 
90*545aaa6fSHong Zhang    Input Parameters:
91*545aaa6fSHong Zhang +  ts        - the TS context obtained from TSCreate()
92*545aaa6fSHong Zhang .  splitname - name of this split
93*545aaa6fSHong Zhang .  r         - vector to hold the residual (or NULL to have it created internally)
94*545aaa6fSHong Zhang .  rhsfunc   - the RHS function evaluation routine
95*545aaa6fSHong Zhang -  ctx       - user-defined context for private data for the split function evaluation routine (may be NULL)
96*545aaa6fSHong Zhang 
97*545aaa6fSHong Zhang  Calling sequence of fun:
98*545aaa6fSHong Zhang $  rhsfunc(TS ts,PetscReal t,Vec u,Vec f,ctx);
99*545aaa6fSHong Zhang 
100*545aaa6fSHong Zhang +  t    - time at step/stage being solved
101*545aaa6fSHong Zhang .  u    - state vector
102*545aaa6fSHong Zhang .  f    - function vector
103*545aaa6fSHong Zhang -  ctx  - [optional] user-defined context for matrix evaluation routine (may be NULL)
104*545aaa6fSHong Zhang 
105*545aaa6fSHong Zhang  Level: beginner
106*545aaa6fSHong Zhang 
107*545aaa6fSHong Zhang .keywords: TS, timestep, set, ODE, Hamiltonian, Function
108*545aaa6fSHong Zhang 
109*545aaa6fSHong Zhang .seealso: TSGetRHSSplitFunction()
110*545aaa6fSHong Zhang @*/
111*545aaa6fSHong Zhang PetscErrorCode TSRHSSplitSetRHSFunction(TS ts,const char splitname[],Vec r,TSRHSFunction rhsfunc,void *ctx)
112*545aaa6fSHong Zhang {
113*545aaa6fSHong Zhang   DM             dm;
114*545aaa6fSHong Zhang   SNES           snes;
115*545aaa6fSHong Zhang   Vec            subvec,ralloc = NULL;
116*545aaa6fSHong Zhang   PetscBool      found = PETSC_FALSE;
117*545aaa6fSHong Zhang   PetscInt       i = 0;
118*545aaa6fSHong Zhang   TS             subts;
119*545aaa6fSHong Zhang   PetscErrorCode ierr;
120*545aaa6fSHong Zhang 
121*545aaa6fSHong Zhang   PetscFunctionBegin;
122*545aaa6fSHong Zhang   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
123*545aaa6fSHong Zhang   if (r) PetscValidHeaderSpecific(r,VEC_CLASSID,2);
124*545aaa6fSHong Zhang 
125*545aaa6fSHong Zhang   /* look up the split */
126*545aaa6fSHong Zhang   while (i<ts->num_rhs_splits) {
127*545aaa6fSHong Zhang      ierr = PetscStrcmp(ts->tsrhssplit[i]->splitname,splitname,&found);CHKERRQ(ierr);
128*545aaa6fSHong Zhang      if (found) break;
129*545aaa6fSHong Zhang      i++;
130*545aaa6fSHong Zhang   }
131*545aaa6fSHong Zhang   if (!found) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"The split %s is not created, check the split name or call TSRHSSplitSetIS() to create one",splitname);
132*545aaa6fSHong Zhang 
133*545aaa6fSHong Zhang   subts = ts->tsrhssplit[i]->ts;
134*545aaa6fSHong Zhang 
135*545aaa6fSHong Zhang   ierr = TSGetDM(subts,&dm);CHKERRQ(ierr);
136*545aaa6fSHong Zhang   ierr = DMTSSetRHSFunction(dm,rhsfunc,ctx);CHKERRQ(ierr);
137*545aaa6fSHong Zhang 
138*545aaa6fSHong Zhang   ierr = TSGetSNES(subts,&snes);CHKERRQ(ierr);
139*545aaa6fSHong Zhang   if (!r && !subts->dm && ts->vec_sol) {
140*545aaa6fSHong Zhang     ierr = VecGetSubVector(ts->vec_sol,ts->tsrhssplit[i]->is,&subvec);CHKERRQ(ierr);
141*545aaa6fSHong Zhang     ierr = VecDuplicate(subvec,&ralloc);CHKERRQ(ierr);
142*545aaa6fSHong Zhang     r = ralloc;
143*545aaa6fSHong Zhang     ierr = VecRestoreSubVector(ts->vec_sol,ts->tsrhssplit[i]->is,&subvec);CHKERRQ(ierr);
144*545aaa6fSHong Zhang   }
145*545aaa6fSHong Zhang   ierr = SNESSetFunction(snes,r,SNESTSFormFunction,subts);CHKERRQ(ierr);
146*545aaa6fSHong Zhang   ierr = VecDestroy(&ralloc);CHKERRQ(ierr);
147*545aaa6fSHong Zhang   PetscFunctionReturn(0);
148*545aaa6fSHong Zhang }
149*545aaa6fSHong Zhang 
150*545aaa6fSHong Zhang /*@C
151*545aaa6fSHong Zhang    TSRHSSplitGetSubTS - Get the split right-hand-side functions.
152*545aaa6fSHong Zhang 
153*545aaa6fSHong Zhang    Logically Collective on TS
154*545aaa6fSHong Zhang 
155*545aaa6fSHong Zhang    Output Parameters:
156*545aaa6fSHong Zhang +  n - the number of splits
157*545aaa6fSHong Zhang -  subksp - the array of TS contexts
158*545aaa6fSHong Zhang 
159*545aaa6fSHong Zhang    Note:
160*545aaa6fSHong Zhang    After TSRHSSplitGetSubTS() the array of TSs is to be freed by the user with PetscFree()
161*545aaa6fSHong Zhang    (not the TS just the array that contains them).
162*545aaa6fSHong Zhang 
163*545aaa6fSHong Zhang    Level: advanced
164*545aaa6fSHong Zhang 
165*545aaa6fSHong Zhang .seealso: TSGetRHSSplitFunction()
166*545aaa6fSHong Zhang @*/
167*545aaa6fSHong Zhang PetscErrorCode TSRHSSplitGetSubTS(TS ts,PetscInt *n,TS **subts)
168*545aaa6fSHong Zhang {
169*545aaa6fSHong Zhang   PetscInt       i = 0;
170*545aaa6fSHong Zhang   PetscErrorCode ierr;
171*545aaa6fSHong Zhang 
172*545aaa6fSHong Zhang   PetscFunctionBegin;
173*545aaa6fSHong Zhang   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
174*545aaa6fSHong Zhang   if (subts) {
175*545aaa6fSHong Zhang     ierr = PetscMalloc1(ts->num_rhs_splits,subts);CHKERRQ(ierr);
176*545aaa6fSHong Zhang     while (i<ts->num_rhs_splits) {
177*545aaa6fSHong Zhang       (*subts)[i] = ts->tsrhssplit[i]->ts;
178*545aaa6fSHong Zhang       i++;
179*545aaa6fSHong Zhang     }
180*545aaa6fSHong Zhang   }
181*545aaa6fSHong Zhang   if (n) *n = ts->num_rhs_splits;
182*545aaa6fSHong Zhang   PetscFunctionReturn(0);
183*545aaa6fSHong Zhang }
184*545aaa6fSHong Zhang 
185*545aaa6fSHong Zhang 
186