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