static PetscErrorCode TSAdaptChoose_Basic(TSAdapt adapt,TS ts,PetscReal h,PetscInt *next_sc,PetscReal *next_h,PetscBool *accept,PetscReal *wlte) { TSAdapt_Basic *basic = (TSAdapt_Basic*)adapt->data; PetscErrorCode ierr; Vec X,Y; PetscReal enorm,hfac_lte,h_lte,safety; PetscInt order,stepno; PetscFunctionBegin; ierr = TSGetTimeStepNumber(ts,&stepno);CHKERRQ(ierr); ierr = TSGetSolution(ts,&X);CHKERRQ(ierr); if (!basic->Y) {ierr = VecDuplicate(X,&basic->Y);CHKERRQ(ierr);} Y = basic->Y; order = adapt->candidates.order[0]; ierr = TSEvaluateStep(ts,order-1,Y,NULL);CHKERRQ(ierr); safety = basic->safety; ierr = TSErrorNormWRMS(ts,Y,&enorm);CHKERRQ(ierr); if (enorm > 1.) { if (!*accept) safety *= basic->reject_safety; /* The last attempt also failed, shorten more aggressively */ if (h < (1 + PETSC_SQRT_MACHINE_EPSILON)*adapt->dt_min) { ierr = PetscInfo2(adapt,"Estimated scaled local truncation error %g, accepting because step size %g is at minimum\n",(double)enorm,(double)h);CHKERRQ(ierr); *accept = PETSC_TRUE; } else if (basic->always_accept) { ierr = PetscInfo2(adapt,"Estimated scaled local truncation error %g, accepting step of size %g because always_accept is set\n",(double)enorm,(double)h);CHKERRQ(ierr); *accept = PETSC_TRUE; } else { ierr = PetscInfo2(adapt,"Estimated scaled local truncation error %g, rejecting step of size %g\n",(double)enorm,(double)h);CHKERRQ(ierr); *accept = PETSC_FALSE; } } else { ierr = PetscInfo2(adapt,"Estimated scaled local truncation error %g, accepting step of size %g\n",(double)enorm,(double)h);CHKERRQ(ierr); *accept = PETSC_TRUE; } /* The optimal new step based purely on local truncation error for this step. */ hfac_lte = safety * PetscRealPart(PetscPowScalar((PetscScalar)enorm,(PetscReal)(-1./order))); h_lte = h * PetscClipInterval(hfac_lte,basic->clip[0],basic->clip[1]); *next_sc = 0; *next_h = PetscClipInterval(h_lte,adapt->dt_min,adapt->dt_max); *wlte = enorm; PetscFunctionReturn(0); }
void PETSC_STDCALL tserrornormwrms_(TS ts,Vec Y,PetscReal *norm, int *__ierr ){ *__ierr = TSErrorNormWRMS( (TS)PetscToPointer((ts) ), (Vec)PetscToPointer((Y) ),norm); }
static PetscErrorCode TSStep_EIMEX(TS ts) { TS_EIMEX *ext = (TS_EIMEX*)ts->data; const PetscInt ns = ext->nstages; Vec *T=ext->T, Y=ext->Y; SNES snes; PetscInt i,j; PetscBool accept = PETSC_FALSE; PetscErrorCode ierr; PetscReal alpha,local_error; PetscFunctionBegin; ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); ierr = SNESSetType(snes,"ksponly"); CHKERRQ(ierr); ext->status = TS_STEP_INCOMPLETE; ierr = VecCopy(ts->vec_sol,ext->VecSolPrev);CHKERRQ(ierr); /* Apply n_j steps of the base method to obtain solutions of T(j,1),1<=j<=s*/ for(j=0; j<ns; j++){ ierr = TSStage_EIMEX(ts,j);CHKERRQ(ierr); ierr = VecCopy(Y,T[j]); CHKERRQ(ierr); } for(i=1;i<ns;i++){ for(j=i;j<ns;j++){ alpha = -(PetscReal)ext->N[j]/ext->N[j-i]; ierr = VecAXPBYPCZ(T[Map(j,i,ns)],alpha,1.0,0,T[Map(j,i-1,ns)],T[Map(j-1,i-1,ns)]);/*T[j][i]=alpha*T[j][i-1]+T[j-1][i-1]*/ alpha = 1.0/(1.0 + alpha); ierr = VecScale(T[Map(j,i,ns)],alpha);CHKERRQ(ierr); } } ierr = TSEvaluateStep(ts,ns,ts->vec_sol,NULL);CHKERRQ(ierr);/*update ts solution */ if(ext->ord_adapt && ext->nstages < ext->max_rows){ accept = PETSC_FALSE; while(!accept && ext->nstages < ext->max_rows){ ierr = TSErrorNormWRMS(ts,T[Map(ext->nstages-1,ext->nstages-2,ext->nstages)],&local_error);CHKERRQ(ierr); accept = (local_error < 1.0)? PETSC_TRUE : PETSC_FALSE; if(!accept){/* add one more stage*/ ierr = TSStage_EIMEX(ts,ext->nstages);CHKERRQ(ierr); ext->nstages++; ext->row_ind++; ext->col_ind++; /*T table need to be recycled*/ ierr = VecDuplicateVecs(ts->vec_sol,(1+ext->nstages)*ext->nstages/2,&ext->T);CHKERRQ(ierr); for(i=0; i<ext->nstages-1; i++){ for(j=0; j<=i; j++){ ierr = VecCopy(T[Map(i,j,ext->nstages-1)],ext->T[Map(i,j,ext->nstages)]);CHKERRQ(ierr); } } ierr = VecDestroyVecs(ext->nstages*(ext->nstages-1)/2,&T);CHKERRQ(ierr); T = ext->T; /*reset the pointer*/ /*recycling finished, store the new solution*/ ierr = VecCopy(Y,T[ext->nstages-1]); CHKERRQ(ierr); /*extrapolation for the newly added stage*/ for(i=1;i<ext->nstages;i++){ alpha = -(PetscReal)ext->N[ext->nstages-1]/ext->N[ext->nstages-1-i]; ierr = VecAXPBYPCZ(T[Map(ext->nstages-1,i,ext->nstages)],alpha,1.0,0,T[Map(ext->nstages-1,i-1,ext->nstages)],T[Map(ext->nstages-1-1,i-1,ext->nstages)]);/*T[ext->nstages-1][i]=alpha*T[ext->nstages-1][i-1]+T[ext->nstages-1-1][i-1]*/ alpha = 1.0/(1.0 + alpha); ierr = VecScale(T[Map(ext->nstages-1,i,ext->nstages)],alpha);CHKERRQ(ierr); } /*update ts solution */ ierr = TSEvaluateStep(ts,ext->nstages,ts->vec_sol,NULL);CHKERRQ(ierr); }/*end if !accept*/ }/*end while*/ if(ext->nstages == ext->max_rows){ ierr = PetscInfo(ts,"Max number of rows has been used\n");CHKERRQ(ierr); } }/*end if ext->ord_adapt*/ ts->ptime += ts->time_step; ts->steps++; ext->status = TS_STEP_COMPLETE; if (ext->status != TS_STEP_COMPLETE && !ts->reason) ts->reason = TS_DIVERGED_STEP_REJECTED; PetscFunctionReturn(0); }