18a381b04SJed Brown /* 28a381b04SJed Brown Code for timestepping with additive Runge-Kutta IMEX method 38a381b04SJed Brown 48a381b04SJed Brown Notes: 58a381b04SJed Brown The general system is written as 68a381b04SJed Brown 78a381b04SJed Brown F(t,X,Xdot) = G(t,X) 88a381b04SJed Brown 98a381b04SJed Brown where F represents the stiff part of the physics and G represents the non-stiff part. 108a381b04SJed Brown 118a381b04SJed Brown */ 128a381b04SJed Brown #include <private/tsimpl.h> /*I "petscts.h" I*/ 138a381b04SJed Brown 148a381b04SJed Brown static const TSARKIMEXType TSARKIMEXDefault = TSARKIMEX2D; 158a381b04SJed Brown static PetscBool TSARKIMEXRegisterAllCalled; 168a381b04SJed Brown static PetscBool TSARKIMEXPackageInitialized; 178a381b04SJed Brown 188a381b04SJed Brown typedef struct _ARKTableau *ARKTableau; 198a381b04SJed Brown struct _ARKTableau { 208a381b04SJed Brown char *name; 218a381b04SJed Brown PetscInt order; 228a381b04SJed Brown PetscInt s; 238a381b04SJed Brown PetscReal *At,*bt,*ct; 248a381b04SJed Brown PetscReal *A,*b,*c; /* Non-stiff tableau */ 25*cd652676SJed Brown PetscReal *binterpt,*binterp; /* Dense output formula */ 268a381b04SJed Brown }; 278a381b04SJed Brown typedef struct _ARKTableauLink *ARKTableauLink; 288a381b04SJed Brown struct _ARKTableauLink { 298a381b04SJed Brown struct _ARKTableau tab; 308a381b04SJed Brown ARKTableauLink next; 318a381b04SJed Brown }; 328a381b04SJed Brown static ARKTableauLink ARKTableauList; 338a381b04SJed Brown 348a381b04SJed Brown typedef struct { 358a381b04SJed Brown ARKTableau tableau; 368a381b04SJed Brown Vec *Y; /* States computed during the step */ 378a381b04SJed Brown Vec *YdotI; /* Time derivatives for the stiff part */ 388a381b04SJed Brown Vec *YdotRHS; /* Function evaluations for the non-stiff part */ 398a381b04SJed Brown Vec Ydot; /* Work vector holding Ydot during residual evaluation */ 408a381b04SJed Brown Vec Work; /* Generic work vector */ 418a381b04SJed Brown Vec Z; /* Ydot = shift(Y-Z) */ 428a381b04SJed Brown PetscScalar *work; /* Scalar work */ 438a381b04SJed Brown PetscReal shift; 448a381b04SJed Brown PetscReal stage_time; 458a381b04SJed Brown } TS_ARKIMEX; 468a381b04SJed Brown 478a381b04SJed Brown #undef __FUNCT__ 488a381b04SJed Brown #define __FUNCT__ "TSARKIMEXRegisterAll" 498a381b04SJed Brown /*@C 508a381b04SJed Brown TSARKIMEXRegisterAll - Registers all of the additive Runge-Kutta implicit-explicit methods in TSARKIMEX 518a381b04SJed Brown 52fca742c7SJed Brown Not Collective, but should be called by all processes which will need the schemes to be registered 538a381b04SJed Brown 548a381b04SJed Brown Level: advanced 558a381b04SJed Brown 568a381b04SJed Brown .keywords: TS, TSARKIMEX, register, all 578a381b04SJed Brown 588a381b04SJed Brown .seealso: TSARKIMEXRegisterDestroy() 598a381b04SJed Brown @*/ 608a381b04SJed Brown PetscErrorCode TSARKIMEXRegisterAll(void) 618a381b04SJed Brown { 628a381b04SJed Brown PetscErrorCode ierr; 638a381b04SJed Brown 648a381b04SJed Brown PetscFunctionBegin; 658a381b04SJed Brown if (TSARKIMEXRegisterAllCalled) PetscFunctionReturn(0); 668a381b04SJed Brown TSARKIMEXRegisterAllCalled = PETSC_TRUE; 678a381b04SJed Brown 688a381b04SJed Brown { 698a381b04SJed Brown const PetscReal 708a381b04SJed Brown A[3][3] = {{0,0,0}, 718a381b04SJed Brown {0.41421356237309504880,0,0}, 728a381b04SJed Brown {0.75,0.25,0}}, 738a381b04SJed Brown At[3][3] = {{0,0,0}, 748a381b04SJed Brown {0.12132034355964257320,0.29289321881345247560,0}, 758a381b04SJed Brown {0.20710678118654752440,0.50000000000000000000,0.29289321881345247560}}; 76*cd652676SJed Brown ierr = TSARKIMEXRegister(TSARKIMEX2D,2,3,&At[0][0],PETSC_NULL,PETSC_NULL,&A[0][0],PETSC_NULL,PETSC_NULL,0,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 778a381b04SJed Brown } 78a3a57f36SJed Brown { 79a3a57f36SJed Brown const PetscReal s2 = sqrt(2), 80a3a57f36SJed Brown A[3][3] = {{0,0,0}, 81a3a57f36SJed Brown {2-s2,0,0}, 82a3a57f36SJed Brown {(3-2*s2)/6,(3+2*s2)/6,0}}, 83a3a57f36SJed Brown At[3][3] = {{0,0,0}, 84a3a57f36SJed Brown {1-1/s2,1-1/s2,0}, 85*cd652676SJed Brown {1/(2*s2),1/(2*s2),1-1/s2}}, 86*cd652676SJed Brown binterpt[3][2] = {{1,-0.5},{0,0},{0,0.5}}; 87*cd652676SJed Brown ierr = TSARKIMEXRegister(TSARKIMEX2E,2,3,&At[0][0],PETSC_NULL,PETSC_NULL,&A[0][0],PETSC_NULL,PETSC_NULL,2,binterpt[0],PETSC_NULL);CHKERRQ(ierr); 88a3a57f36SJed Brown } 89a3a57f36SJed Brown { 90a3a57f36SJed Brown const PetscReal 91a3a57f36SJed Brown A[4][4] = {{0,0,0,0}, 92a3a57f36SJed Brown {1767732205903./2027836641118,0,0,0}, 93a3a57f36SJed Brown {5535828885825./10492691773637,788022342437./10882634858940,0,0}, 94a3a57f36SJed Brown {6485989280629./16251701735622,-4246266847089./9704473918619,10755448449292./10357097424841,0}}, 95a3a57f36SJed Brown At[4][4] = {{0,0,0,0}, 96a3a57f36SJed Brown {1767732205903./4055673282236,1767732205903./4055673282236,0,0}, 97a3a57f36SJed Brown {2746238789719./10658868560708,-640167445237./6845629431997,1767732205903./4055673282236,0}, 98*cd652676SJed Brown {1471266399579./7840856788654,-4482444167858./7529755066697,11266239266428./11593286722821,1767732205903./4055673282236}}, 99*cd652676SJed Brown binterpt[4][2] = {{4655552711362./22874653954995, -215264564351./13552729205753}, 100*cd652676SJed Brown {-18682724506714./9892148508045,17870216137069./13817060693119}, 101*cd652676SJed Brown {34259539580243./13192909600954,-28141676662227./17317692491321}, 102*cd652676SJed Brown {584795268549./6622622206610, 2508943948391./7218656332882}}; 103*cd652676SJed Brown ierr = TSARKIMEXRegister(TSARKIMEX3,3,4,&At[0][0],PETSC_NULL,PETSC_NULL,&A[0][0],PETSC_NULL,PETSC_NULL,2,binterpt[0],PETSC_NULL);CHKERRQ(ierr); 104a3a57f36SJed Brown } 105a3a57f36SJed Brown { 106a3a57f36SJed Brown const PetscReal 107a3a57f36SJed Brown A[6][6] = {{0,0,0,0,0,0}, 108a3a57f36SJed Brown {1./2,0,0,0,0,0}, 109a3a57f36SJed Brown {13861./62500,6889./62500,0,0,0,0}, 110a3a57f36SJed Brown {-116923316275./2393684061468,-2731218467317./15368042101831,9408046702089./11113171139209,0,0,0}, 111a3a57f36SJed Brown {-451086348788./2902428689909,-2682348792572./7519795681897,12662868775082./11960479115383,3355817975965./11060851509271,0,0}, 112a3a57f36SJed Brown {647845179188./3216320057751,73281519250./8382639484533,552539513391./3454668386233,3354512671639./8306763924573,4040./17871,0}}, 113a3a57f36SJed Brown At[6][6] = {{0,0,0,0,0,0}, 114a3a57f36SJed Brown {1./4,1./4,0,0,0,0}, 115a3a57f36SJed Brown {8611./62500,-1743./31250,1./4,0,0,0}, 116a3a57f36SJed Brown {5012029./34652500,-654441./2922500,174375./388108,1./4,0,0}, 117a3a57f36SJed Brown {15267082809./155376265600,-71443401./120774400,730878875./902184768,2285395./8070912,1./4,0}, 118*cd652676SJed Brown {82889./524892,0,15625./83664,69875./102672,-2260./8211,1./4}}, 119*cd652676SJed Brown binterpt[6][3] = {{6943876665148./7220017795957,-54480133./30881146,6818779379841./7100303317025}, 120*cd652676SJed Brown {0,0,0}, 121*cd652676SJed Brown {7640104374378./9702883013639,-11436875./14766696,2173542590792./12501825683035}, 122*cd652676SJed Brown {-20649996744609./7521556579894,174696575./18121608,-31592104683404./5083833661969}, 123*cd652676SJed Brown {8854892464581./2390941311638,-12120380./966161,61146701046299./7138195549469}, 124*cd652676SJed Brown {-11397109935349./6675773540249,3843./706,-17219254887155./4939391667607}}; 125*cd652676SJed Brown ierr = TSARKIMEXRegister(TSARKIMEX4,4,6,&At[0][0],PETSC_NULL,PETSC_NULL,&A[0][0],PETSC_NULL,PETSC_NULL,3,binterpt[0],PETSC_NULL);CHKERRQ(ierr); 126a3a57f36SJed Brown } 127a3a57f36SJed Brown { 128a3a57f36SJed Brown const PetscReal 129a3a57f36SJed Brown A[8][8] = {{0,0,0,0,0,0,0,0}, 130a3a57f36SJed Brown {41./100,0,0,0,0,0,0,0}, 131a3a57f36SJed Brown {367902744464./2072280473677,677623207551./8224143866563,0,0,0,0,0,0}, 132a3a57f36SJed Brown {1268023523408./10340822734521,0,1029933939417./13636558850479,0,0,0,0,0}, 133a3a57f36SJed Brown {14463281900351./6315353703477,0,66114435211212./5879490589093,-54053170152839./4284798021562,0,0,0,0}, 134a3a57f36SJed Brown {14090043504691./34967701212078,0,15191511035443./11219624916014,-18461159152457./12425892160975,-281667163811./9011619295870,0,0,0}, 135a3a57f36SJed Brown {19230459214898./13134317526959,0,21275331358303./2942455364971,-38145345988419./4862620318723,-1./8,-1./8,0,0}, 136a3a57f36SJed Brown {-19977161125411./11928030595625,0,-40795976796054./6384907823539,177454434618887./12078138498510,782672205425./8267701900261,-69563011059811./9646580694205,7356628210526./4942186776405,0}}, 137a3a57f36SJed Brown At[8][8] = {{0,0,0,0,0,0,0,0}, 138a3a57f36SJed Brown {41./200,41./200,0,0,0,0,0,0}, 139a3a57f36SJed Brown {41./400,-567603406766./11931857230679,41./200,0,0,0,0,0}, 140a3a57f36SJed Brown {683785636431./9252920307686,0,-110385047103./1367015193373,41./200,0,0,0,0}, 141a3a57f36SJed Brown {3016520224154./10081342136671,0,30586259806659./12414158314087,-22760509404356./11113319521817,41./200,0,0,0}, 142a3a57f36SJed Brown {218866479029./1489978393911,0,638256894668./5436446318841,-1179710474555./5321154724896,-60928119172./8023461067671,41./200,0,0}, 143a3a57f36SJed Brown {1020004230633./5715676835656,0,25762820946817./25263940353407,-2161375909145./9755907335909,-211217309593./5846859502534,-4269925059573./7827059040749,41./200,0}, 144*cd652676SJed Brown {-872700587467./9133579230613,0,0,22348218063261./9555858737531,-1143369518992./8141816002931,-39379526789629./19018526304540,32727382324388./42900044865799,41./200}}, 145*cd652676SJed Brown binterpt[8][3] = {{-17674230611817./10670229744614 , 43486358583215./12773830924787 , -9257016797708./5021505065439}, 146*cd652676SJed Brown {0 , 0 , 0 }, 147*cd652676SJed Brown {0 , 0 , 0 }, 148*cd652676SJed Brown {65168852399939./7868540260826 , -91478233927265./11067650958493, 26096422576131./11239449250142}, 149*cd652676SJed Brown {15494834004392./5936557850923 , -79368583304911./10890268929626, 92396832856987./20362823103730}, 150*cd652676SJed Brown {-99329723586156./26959484932159 , -12239297817655./9152339842473 , 30029262896817./10175596800299}, 151*cd652676SJed Brown {-19024464361622./5461577185407 , 115839755401235./10719374521269, -26136350496073./3983972220547}, 152*cd652676SJed Brown {-6511271360970./6095937251113 , 5843115559534./2180450260947 , -5289405421727./3760307252460 }}; 153*cd652676SJed Brown ierr = TSARKIMEXRegister(TSARKIMEX5,5,8,&At[0][0],PETSC_NULL,PETSC_NULL,&A[0][0],PETSC_NULL,PETSC_NULL,3,binterpt[0],PETSC_NULL);CHKERRQ(ierr); 154a3a57f36SJed Brown } 155a3a57f36SJed Brown 1568a381b04SJed Brown PetscFunctionReturn(0); 1578a381b04SJed Brown } 1588a381b04SJed Brown 1598a381b04SJed Brown #undef __FUNCT__ 1608a381b04SJed Brown #define __FUNCT__ "TSARKIMEXRegisterDestroy" 1618a381b04SJed Brown /*@C 1628a381b04SJed Brown TSARKIMEXRegisterDestroy - Frees the list of schemes that were registered by TSARKIMEXRegister(). 1638a381b04SJed Brown 1648a381b04SJed Brown Not Collective 1658a381b04SJed Brown 1668a381b04SJed Brown Level: advanced 1678a381b04SJed Brown 1688a381b04SJed Brown .keywords: TSARKIMEX, register, destroy 1698a381b04SJed Brown .seealso: TSARKIMEXRegister(), TSARKIMEXRegisterAll(), TSARKIMEXRegisterDynamic() 1708a381b04SJed Brown @*/ 1718a381b04SJed Brown PetscErrorCode TSARKIMEXRegisterDestroy(void) 1728a381b04SJed Brown { 1738a381b04SJed Brown PetscErrorCode ierr; 1748a381b04SJed Brown ARKTableauLink link; 1758a381b04SJed Brown 1768a381b04SJed Brown PetscFunctionBegin; 1778a381b04SJed Brown while ((link = ARKTableauList)) { 1788a381b04SJed Brown ARKTableau t = &link->tab; 1798a381b04SJed Brown ARKTableauList = link->next; 1808a381b04SJed Brown ierr = PetscFree6(t->At,t->bt,t->ct,t->A,t->b,t->c);CHKERRQ(ierr); 181*cd652676SJed Brown ierr = PetscFree2(t->binterpt,t->binterp);CHKERRQ(ierr); 1828a381b04SJed Brown ierr = PetscFree(t->name);CHKERRQ(ierr); 1838a381b04SJed Brown ierr = PetscFree(link);CHKERRQ(ierr); 1848a381b04SJed Brown } 1858a381b04SJed Brown TSARKIMEXRegisterAllCalled = PETSC_FALSE; 1868a381b04SJed Brown PetscFunctionReturn(0); 1878a381b04SJed Brown } 1888a381b04SJed Brown 1898a381b04SJed Brown #undef __FUNCT__ 1908a381b04SJed Brown #define __FUNCT__ "TSARKIMEXInitializePackage" 1918a381b04SJed Brown /*@C 1928a381b04SJed Brown TSARKIMEXInitializePackage - This function initializes everything in the TSARKIMEX package. It is called 1938a381b04SJed Brown from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to TSCreate_ARKIMEX() 1948a381b04SJed Brown when using static libraries. 1958a381b04SJed Brown 1968a381b04SJed Brown Input Parameter: 1978a381b04SJed Brown path - The dynamic library path, or PETSC_NULL 1988a381b04SJed Brown 1998a381b04SJed Brown Level: developer 2008a381b04SJed Brown 2018a381b04SJed Brown .keywords: TS, TSARKIMEX, initialize, package 2028a381b04SJed Brown .seealso: PetscInitialize() 2038a381b04SJed Brown @*/ 2048a381b04SJed Brown PetscErrorCode TSARKIMEXInitializePackage(const char path[]) 2058a381b04SJed Brown { 2068a381b04SJed Brown PetscErrorCode ierr; 2078a381b04SJed Brown 2088a381b04SJed Brown PetscFunctionBegin; 2098a381b04SJed Brown if (TSARKIMEXPackageInitialized) PetscFunctionReturn(0); 2108a381b04SJed Brown TSARKIMEXPackageInitialized = PETSC_TRUE; 2118a381b04SJed Brown ierr = TSARKIMEXRegisterAll();CHKERRQ(ierr); 2128a381b04SJed Brown ierr = PetscRegisterFinalize(TSARKIMEXFinalizePackage);CHKERRQ(ierr); 2138a381b04SJed Brown PetscFunctionReturn(0); 2148a381b04SJed Brown } 2158a381b04SJed Brown 2168a381b04SJed Brown #undef __FUNCT__ 2178a381b04SJed Brown #define __FUNCT__ "TSARKIMEXFinalizePackage" 2188a381b04SJed Brown /*@C 2198a381b04SJed Brown TSARKIMEXFinalizePackage - This function destroys everything in the TSARKIMEX package. It is 2208a381b04SJed Brown called from PetscFinalize(). 2218a381b04SJed Brown 2228a381b04SJed Brown Level: developer 2238a381b04SJed Brown 2248a381b04SJed Brown .keywords: Petsc, destroy, package 2258a381b04SJed Brown .seealso: PetscFinalize() 2268a381b04SJed Brown @*/ 2278a381b04SJed Brown PetscErrorCode TSARKIMEXFinalizePackage(void) 2288a381b04SJed Brown { 2298a381b04SJed Brown PetscErrorCode ierr; 2308a381b04SJed Brown 2318a381b04SJed Brown PetscFunctionBegin; 2328a381b04SJed Brown TSARKIMEXPackageInitialized = PETSC_FALSE; 2338a381b04SJed Brown ierr = TSARKIMEXRegisterDestroy();CHKERRQ(ierr); 2348a381b04SJed Brown PetscFunctionReturn(0); 2358a381b04SJed Brown } 2368a381b04SJed Brown 2378a381b04SJed Brown #undef __FUNCT__ 2388a381b04SJed Brown #define __FUNCT__ "TSARKIMEXRegister" 239*cd652676SJed Brown /*@C 240*cd652676SJed Brown TSARKIMEXRegister - register an ARK IMEX scheme by providing the entries in the Butcher tableau and optionally embedded approximations and interpolation 241*cd652676SJed Brown 242*cd652676SJed Brown Not Collective, but the same schemes should be registered on all processes on which they will be used 243*cd652676SJed Brown 244*cd652676SJed Brown Input Parameters: 245*cd652676SJed Brown + name - identifier for method 246*cd652676SJed Brown . order - approximation order of method 247*cd652676SJed Brown . s - number of stages, this is the dimension of the matrices below 248*cd652676SJed Brown . At - Butcher table of stage coefficients for stiff part (dimension s*s, row-major) 249*cd652676SJed Brown . bt - Butcher table for completing the stiff part of the step (dimension s; PETSC_NULL to use the last row of At) 250*cd652676SJed Brown . ct - Abscissa of each stiff stage (dimension s, PETSC_NULL to use row sums of At) 251*cd652676SJed Brown . A - Non-stiff stage coefficients (dimension s*s, row-major) 252*cd652676SJed Brown . b - Non-stiff step completion table (dimension s; PETSC_NULL to use last row of At) 253*cd652676SJed Brown . c - Non-stiff abscissa (dimension s; PETSC_NULL to use row sums of A) 254*cd652676SJed Brown . pinterp - Order of the interpolation scheme, equal to the number of columns of binterpt and binterp 255*cd652676SJed Brown . binterpt - Coefficients of the interpolation formula for the stiff part (dimension s*pinterp) 256*cd652676SJed Brown - binterp - Coefficients of the interpolation formula for the non-stiff part (dimension s*pinterp; PETSC_NULL to reuse binterpt) 257*cd652676SJed Brown 258*cd652676SJed Brown Notes: 259*cd652676SJed Brown Several ARK IMEX methods are provided, this function is only needed to create new methods. 260*cd652676SJed Brown 261*cd652676SJed Brown Level: advanced 262*cd652676SJed Brown 263*cd652676SJed Brown .keywords: TS, register 264*cd652676SJed Brown 265*cd652676SJed Brown .seealso: TSARKIMEX 266*cd652676SJed Brown @*/ 2678a381b04SJed Brown PetscErrorCode TSARKIMEXRegister(const TSARKIMEXType name,PetscInt order,PetscInt s, 2688a381b04SJed Brown const PetscReal At[],const PetscReal bt[],const PetscReal ct[], 269*cd652676SJed Brown const PetscReal A[],const PetscReal b[],const PetscReal c[], 270*cd652676SJed Brown PetscInt pinterp,const PetscReal binterpt[],const PetscReal binterp[]) 2718a381b04SJed Brown { 2728a381b04SJed Brown PetscErrorCode ierr; 2738a381b04SJed Brown ARKTableauLink link; 2748a381b04SJed Brown ARKTableau t; 2758a381b04SJed Brown PetscInt i,j; 2768a381b04SJed Brown 2778a381b04SJed Brown PetscFunctionBegin; 2788a381b04SJed Brown ierr = PetscMalloc(sizeof(*link),&link);CHKERRQ(ierr); 279*cd652676SJed Brown ierr = PetscMemzero(link,sizeof(*link));CHKERRQ(ierr); 2808a381b04SJed Brown t = &link->tab; 2818a381b04SJed Brown ierr = PetscStrallocpy(name,&t->name);CHKERRQ(ierr); 2828a381b04SJed Brown t->order = order; 2838a381b04SJed Brown t->s = s; 2848a381b04SJed Brown ierr = PetscMalloc6(s*s,PetscReal,&t->At,s,PetscReal,&t->bt,s,PetscReal,&t->ct,s*s,PetscReal,&t->A,s,PetscReal,&t->b,s,PetscReal,&t->c);CHKERRQ(ierr); 2858a381b04SJed Brown ierr = PetscMemcpy(t->At,At,s*s*sizeof(At[0]));CHKERRQ(ierr); 2868a381b04SJed Brown ierr = PetscMemcpy(t->A,A,s*s*sizeof(A[0]));CHKERRQ(ierr); 2878a381b04SJed Brown if (bt) {ierr = PetscMemcpy(t->bt,bt,s*sizeof(bt[0]));CHKERRQ(ierr);} 2888a381b04SJed Brown else for (i=0; i<s; i++) t->bt[i] = At[(s-1)*s+i]; 2898a381b04SJed Brown if (b) {ierr = PetscMemcpy(t->b,b,s*sizeof(b[0]));CHKERRQ(ierr);} 2908a381b04SJed Brown else for (i=0; i<s; i++) t->b[i] = At[(s-1)*s+i]; 2918a381b04SJed Brown if (ct) {ierr = PetscMemcpy(t->ct,ct,s*sizeof(ct[0]));CHKERRQ(ierr);} 2928a381b04SJed Brown else for (i=0; i<s; i++) for (j=0,t->ct[i]=0; j<s; j++) t->ct[i] += At[i*s+j]; 2938a381b04SJed Brown if (c) {ierr = PetscMemcpy(t->c,c,s*sizeof(c[0]));CHKERRQ(ierr);} 2948a381b04SJed Brown else for (i=0; i<s; i++) for (j=0,t->c[i]=0; j<s; j++) t->c[i] += A[i*s+j]; 295*cd652676SJed Brown ierr = PetscMalloc2(s*pinterp,PetscReal,&t->binterpt,s*pinterp,PetscReal,&t->binterp);CHKERRQ(ierr); 296*cd652676SJed Brown ierr = PetscMemcpy(t->binterpt,binterpt,s*pinterp*sizeof(binterpt[0]));CHKERRQ(ierr); 297*cd652676SJed Brown ierr = PetscMemcpy(t->binterp,binterp?binterp:binterpt,s*pinterp*sizeof(binterpt[0]));CHKERRQ(ierr); 2988a381b04SJed Brown link->next = ARKTableauList; 2998a381b04SJed Brown ARKTableauList = link; 3008a381b04SJed Brown PetscFunctionReturn(0); 3018a381b04SJed Brown } 3028a381b04SJed Brown 3038a381b04SJed Brown #undef __FUNCT__ 3048a381b04SJed Brown #define __FUNCT__ "TSStep_ARKIMEX" 3058a381b04SJed Brown static PetscErrorCode TSStep_ARKIMEX(TS ts) 3068a381b04SJed Brown { 3078a381b04SJed Brown TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 3088a381b04SJed Brown ARKTableau tab = ark->tableau; 3098a381b04SJed Brown const PetscInt s = tab->s; 3108a381b04SJed Brown const PetscReal *At = tab->At,*A = tab->A,*bt = tab->bt,*b = tab->b,*ct = tab->ct,*c = tab->c; 311406d0ec2SJed Brown PetscScalar *w = ark->work; 3128a381b04SJed Brown Vec *Y = ark->Y,*YdotI = ark->YdotI,*YdotRHS = ark->YdotRHS,Ydot = ark->Ydot,W = ark->Work,Z = ark->Z; 3138a381b04SJed Brown SNES snes; 3148a381b04SJed Brown PetscInt i,j,its,lits; 3158a381b04SJed Brown PetscReal h,t; 3168a381b04SJed Brown PetscErrorCode ierr; 3178a381b04SJed Brown 3188a381b04SJed Brown PetscFunctionBegin; 3198a381b04SJed Brown ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 3208a381b04SJed Brown h = ts->time_step = ts->next_time_step; 3218a381b04SJed Brown t = ts->ptime; 3228a381b04SJed Brown 3238a381b04SJed Brown for (i=0; i<s; i++) { 3248a381b04SJed Brown if (At[i*s+i] == 0) { /* This stage is explicit */ 3258a381b04SJed Brown ierr = VecCopy(ts->vec_sol,Y[i]);CHKERRQ(ierr); 3268a381b04SJed Brown for (j=0; j<i; j++) w[j] = -h*At[i*s+j]; 3278a381b04SJed Brown ierr = VecMAXPY(Y[i],i,w,YdotI);CHKERRQ(ierr); 3288a381b04SJed Brown for (j=0; j<i; j++) w[j] = h*A[i*s+j]; 3298a381b04SJed Brown ierr = VecMAXPY(Y[i],i,w,YdotRHS);CHKERRQ(ierr); 3308a381b04SJed Brown } else { 3318a381b04SJed Brown ark->stage_time = t + h*ct[i]; 3328a381b04SJed Brown ark->shift = 1./(h*At[i*s+i]); 3338a381b04SJed Brown /* Affine part */ 3348a381b04SJed Brown ierr = VecZeroEntries(W);CHKERRQ(ierr); 3358a381b04SJed Brown for (j=0; j<i; j++) w[j] = h*A[i*s+j]; 3368a381b04SJed Brown ierr = VecMAXPY(W,i,w,YdotRHS);CHKERRQ(ierr); 3378a381b04SJed Brown /* Ydot = shift*(Y-Z) */ 3388a381b04SJed Brown ierr = VecCopy(ts->vec_sol,Z);CHKERRQ(ierr); 3398a381b04SJed Brown for (j=0; j<i; j++) w[j] = h*At[i*s+j]; 3408a381b04SJed Brown ierr = VecMAXPY(Z,i,w,YdotRHS);CHKERRQ(ierr); 3418a381b04SJed Brown /* Initial guess taken from last stage */ 3428a381b04SJed Brown ierr = VecCopy(i>0?Y[i-1]:ts->vec_sol,Y[i]);CHKERRQ(ierr); 3438a381b04SJed Brown ierr = SNESSolve(snes,W,Y[i]);CHKERRQ(ierr); 3448a381b04SJed Brown ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); 3458a381b04SJed Brown ierr = SNESGetLinearSolveIterations(snes,&lits);CHKERRQ(ierr); 3468a381b04SJed Brown ts->nonlinear_its += its; ts->linear_its += lits; 3478a381b04SJed Brown } 3488a381b04SJed Brown ierr = VecZeroEntries(Ydot);CHKERRQ(ierr); 3498a381b04SJed Brown ierr = TSComputeIFunction(ts,t+h*ct[i],Y[i],Ydot,YdotI[i],PETSC_TRUE);CHKERRQ(ierr); 3508a381b04SJed Brown ierr = TSComputeRHSFunction(ts,t+h*c[i],Y[i],YdotRHS[i]);CHKERRQ(ierr); 3518a381b04SJed Brown } 352a17b68daSJed Brown for (j=0; j<s; j++) w[j] = -h*bt[j]; 3538a381b04SJed Brown ierr = VecMAXPY(ts->vec_sol,s,w,YdotI);CHKERRQ(ierr); 3548a381b04SJed Brown for (j=0; j<s; j++) w[j] = h*b[j]; 3558a381b04SJed Brown ierr = VecMAXPY(ts->vec_sol,s,w,YdotRHS);CHKERRQ(ierr); 3568a381b04SJed Brown 3578a381b04SJed Brown ts->ptime += ts->time_step; 3588a381b04SJed Brown ts->next_time_step = ts->time_step; 3598a381b04SJed Brown ts->steps++; 3608a381b04SJed Brown PetscFunctionReturn(0); 3618a381b04SJed Brown } 3628a381b04SJed Brown 363*cd652676SJed Brown #undef __FUNCT__ 364*cd652676SJed Brown #define __FUNCT__ "TSInterpolate_ARKIMEX" 365*cd652676SJed Brown static PetscErrorCode TSInterpolate_ARKIMEX(TS ts,PetscReal itime,Vec X) 366*cd652676SJed Brown { 367*cd652676SJed Brown TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 368*cd652676SJed Brown PetscInt s = ark->tableau->s,i,j; 369*cd652676SJed Brown PetscReal tt,t = (itime - ts->ptime)/ts->time_step - 1; /* In the interval [0,1] */ 370*cd652676SJed Brown PetscScalar *bt,*b; 371*cd652676SJed Brown const PetscReal *Bt = ark->tableau->binterpt,*B = ark->tableau->binterp; 372*cd652676SJed Brown PetscErrorCode ierr; 373*cd652676SJed Brown 374*cd652676SJed Brown PetscFunctionBegin; 375*cd652676SJed Brown if (!Bt || !B) SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_SUP,"TSARKIMEX %s does not have an interpolation formula",ark->tableau->name); 376*cd652676SJed Brown ierr = PetscMalloc2(s,PetscScalar,&bt,s,PetscScalar,&b);CHKERRQ(ierr); 377*cd652676SJed Brown for (i=0; i<s; i++) bt[i] = b[i] = 0; 378*cd652676SJed Brown for (j=0,tt=t; j<s; j++,tt*=t) { 379*cd652676SJed Brown for (i=0; i<s; i++) { 380*cd652676SJed Brown bt[i] += Bt[i*s+j] * tt; 381*cd652676SJed Brown b[i] += B[i*s+j] * tt; 382*cd652676SJed Brown } 383*cd652676SJed Brown } 384*cd652676SJed Brown if (ark->tableau->At[0*s+0] != 0.0) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_SUP,"First stage not explicit so starting stage not saved"); 385*cd652676SJed Brown ierr = VecCopy(ark->Y[0],X);CHKERRQ(ierr); 386*cd652676SJed Brown ierr = VecMAXPY(X,s,bt,ark->YdotI);CHKERRQ(ierr); 387*cd652676SJed Brown ierr = VecMAXPY(X,s,b,ark->YdotRHS);CHKERRQ(ierr); 388*cd652676SJed Brown ierr = PetscFree2(bt,b);CHKERRQ(ierr); 389*cd652676SJed Brown PetscFunctionReturn(0); 390*cd652676SJed Brown } 391*cd652676SJed Brown 3928a381b04SJed Brown /*------------------------------------------------------------*/ 3938a381b04SJed Brown #undef __FUNCT__ 3948a381b04SJed Brown #define __FUNCT__ "TSReset_ARKIMEX" 3958a381b04SJed Brown static PetscErrorCode TSReset_ARKIMEX(TS ts) 3968a381b04SJed Brown { 3978a381b04SJed Brown TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 3988a381b04SJed Brown PetscInt s; 3998a381b04SJed Brown PetscErrorCode ierr; 4008a381b04SJed Brown 4018a381b04SJed Brown PetscFunctionBegin; 4028a381b04SJed Brown if (!ark->tableau) PetscFunctionReturn(0); 4038a381b04SJed Brown s = ark->tableau->s; 4048a381b04SJed Brown ierr = VecDestroyVecs(s,&ark->Y);CHKERRQ(ierr); 4058a381b04SJed Brown ierr = VecDestroyVecs(s,&ark->YdotI);CHKERRQ(ierr); 4068a381b04SJed Brown ierr = VecDestroyVecs(s,&ark->YdotRHS);CHKERRQ(ierr); 4078a381b04SJed Brown ierr = VecDestroy(&ark->Ydot);CHKERRQ(ierr); 4088a381b04SJed Brown ierr = VecDestroy(&ark->Work);CHKERRQ(ierr); 4098a381b04SJed Brown ierr = VecDestroy(&ark->Z);CHKERRQ(ierr); 4108a381b04SJed Brown ierr = PetscFree(ark->work);CHKERRQ(ierr); 4118a381b04SJed Brown PetscFunctionReturn(0); 4128a381b04SJed Brown } 4138a381b04SJed Brown 4148a381b04SJed Brown #undef __FUNCT__ 4158a381b04SJed Brown #define __FUNCT__ "TSDestroy_ARKIMEX" 4168a381b04SJed Brown static PetscErrorCode TSDestroy_ARKIMEX(TS ts) 4178a381b04SJed Brown { 4188a381b04SJed Brown PetscErrorCode ierr; 4198a381b04SJed Brown 4208a381b04SJed Brown PetscFunctionBegin; 4218a381b04SJed Brown ierr = TSReset_ARKIMEX(ts);CHKERRQ(ierr); 4228a381b04SJed Brown ierr = PetscFree(ts->data);CHKERRQ(ierr); 4238a381b04SJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSARKIMEXGetType_C","",PETSC_NULL);CHKERRQ(ierr); 4248a381b04SJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSARKIMEXSetType_C","",PETSC_NULL);CHKERRQ(ierr); 4258a381b04SJed Brown PetscFunctionReturn(0); 4268a381b04SJed Brown } 4278a381b04SJed Brown 4288a381b04SJed Brown /* 4298a381b04SJed Brown This defines the nonlinear equation that is to be solved with SNES 4308a381b04SJed Brown G(U) = F[t0+Theta*dt, U, (U-U0)*shift] = 0 4318a381b04SJed Brown */ 4328a381b04SJed Brown #undef __FUNCT__ 4338a381b04SJed Brown #define __FUNCT__ "SNESTSFormFunction_ARKIMEX" 4348a381b04SJed Brown static PetscErrorCode SNESTSFormFunction_ARKIMEX(SNES snes,Vec X,Vec F,TS ts) 4358a381b04SJed Brown { 4368a381b04SJed Brown TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 4378a381b04SJed Brown PetscErrorCode ierr; 4388a381b04SJed Brown 4398a381b04SJed Brown PetscFunctionBegin; 4408a381b04SJed Brown ierr = VecAXPBYPCZ(ark->Ydot,-ark->shift,ark->shift,0,ark->Z,X);CHKERRQ(ierr); /* Ydot = shift*(X-Z) */ 44131f6fcc0SJed Brown ierr = TSComputeIFunction(ts,ark->stage_time,X,ark->Ydot,F,PETSC_TRUE);CHKERRQ(ierr); 4428a381b04SJed Brown PetscFunctionReturn(0); 4438a381b04SJed Brown } 4448a381b04SJed Brown 4458a381b04SJed Brown #undef __FUNCT__ 4468a381b04SJed Brown #define __FUNCT__ "SNESTSFormJacobian_ARKIMEX" 4478a381b04SJed Brown static PetscErrorCode SNESTSFormJacobian_ARKIMEX(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *str,TS ts) 4488a381b04SJed Brown { 4498a381b04SJed Brown TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 4508a381b04SJed Brown PetscErrorCode ierr; 4518a381b04SJed Brown 4528a381b04SJed Brown PetscFunctionBegin; 4538a381b04SJed Brown /* ark->Ydot has already been computed in SNESTSFormFunction_ARKIMEX (SNES guarantees this) */ 4548a381b04SJed Brown ierr = TSComputeIJacobian(ts,ark->stage_time,X,ark->Ydot,ark->shift,A,B,str,PETSC_TRUE);CHKERRQ(ierr); 4558a381b04SJed Brown PetscFunctionReturn(0); 4568a381b04SJed Brown } 4578a381b04SJed Brown 4588a381b04SJed Brown #undef __FUNCT__ 4598a381b04SJed Brown #define __FUNCT__ "TSSetUp_ARKIMEX" 4608a381b04SJed Brown static PetscErrorCode TSSetUp_ARKIMEX(TS ts) 4618a381b04SJed Brown { 4628a381b04SJed Brown TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 4638a381b04SJed Brown ARKTableau tab = ark->tableau; 4648a381b04SJed Brown PetscInt s = tab->s; 4658a381b04SJed Brown PetscErrorCode ierr; 4668a381b04SJed Brown 4678a381b04SJed Brown PetscFunctionBegin; 4688a381b04SJed Brown if (!ark->tableau) { 469e24355feSJed Brown ierr = TSARKIMEXSetType(ts,TSARKIMEXDefault);CHKERRQ(ierr); 4708a381b04SJed Brown } 4718a381b04SJed Brown ierr = VecDuplicateVecs(ts->vec_sol,s,&ark->Y);CHKERRQ(ierr); 4728a381b04SJed Brown ierr = VecDuplicateVecs(ts->vec_sol,s,&ark->YdotI);CHKERRQ(ierr); 4738a381b04SJed Brown ierr = VecDuplicateVecs(ts->vec_sol,s,&ark->YdotRHS);CHKERRQ(ierr); 4748a381b04SJed Brown ierr = VecDuplicate(ts->vec_sol,&ark->Ydot);CHKERRQ(ierr); 4758a381b04SJed Brown ierr = VecDuplicate(ts->vec_sol,&ark->Work);CHKERRQ(ierr); 4768a381b04SJed Brown ierr = VecDuplicate(ts->vec_sol,&ark->Z);CHKERRQ(ierr); 4778a381b04SJed Brown ierr = PetscMalloc(s*sizeof(ark->work[0]),&ark->work);CHKERRQ(ierr); 4788a381b04SJed Brown PetscFunctionReturn(0); 4798a381b04SJed Brown } 4808a381b04SJed Brown /*------------------------------------------------------------*/ 4818a381b04SJed Brown 4828a381b04SJed Brown #undef __FUNCT__ 4838a381b04SJed Brown #define __FUNCT__ "TSSetFromOptions_ARKIMEX" 4848a381b04SJed Brown static PetscErrorCode TSSetFromOptions_ARKIMEX(TS ts) 4858a381b04SJed Brown { 4868a381b04SJed Brown PetscErrorCode ierr; 4878a381b04SJed Brown char arktype[256]; 4888a381b04SJed Brown 4898a381b04SJed Brown PetscFunctionBegin; 4908a381b04SJed Brown ierr = PetscOptionsHead("ARKIMEX ODE solver options");CHKERRQ(ierr); 4918a381b04SJed Brown { 4928a381b04SJed Brown ARKTableauLink link; 4938a381b04SJed Brown PetscInt count,choice; 4948a381b04SJed Brown PetscBool flg; 4958a381b04SJed Brown const char **namelist; 4968a381b04SJed Brown ierr = PetscStrncpy(arktype,TSARKIMEXDefault,sizeof arktype);CHKERRQ(ierr); 4978a381b04SJed Brown for (link=ARKTableauList,count=0; link; link=link->next,count++) ; 4988a381b04SJed Brown ierr = PetscMalloc(count*sizeof(char*),&namelist);CHKERRQ(ierr); 4998a381b04SJed Brown for (link=ARKTableauList,count=0; link; link=link->next,count++) namelist[count] = link->tab.name; 5008a381b04SJed Brown ierr = PetscOptionsEList("-ts_arkimex_type","Family of ARK IMEX method","TSARKIMEXSetType",(const char*const*)namelist,count,arktype,&choice,&flg);CHKERRQ(ierr); 5018a381b04SJed Brown ierr = TSARKIMEXSetType(ts,flg ? namelist[choice] : arktype);CHKERRQ(ierr); 5028a381b04SJed Brown ierr = PetscFree(namelist);CHKERRQ(ierr); 5038a381b04SJed Brown } 5048a381b04SJed Brown ierr = PetscOptionsTail();CHKERRQ(ierr); 5058a381b04SJed Brown PetscFunctionReturn(0); 5068a381b04SJed Brown } 5078a381b04SJed Brown 5088a381b04SJed Brown #undef __FUNCT__ 5098a381b04SJed Brown #define __FUNCT__ "PetscFormatRealArray" 5108a381b04SJed Brown static PetscErrorCode PetscFormatRealArray(char buf[],size_t len,const char *fmt,PetscInt n,const PetscReal x[]) 5118a381b04SJed Brown { 5128a381b04SJed Brown int i,left,count; 5138a381b04SJed Brown char *p; 5148a381b04SJed Brown 5158a381b04SJed Brown PetscFunctionBegin; 5168a381b04SJed Brown for (i=0,p=buf,left=(int)len; i<n; i++) { 5178a381b04SJed Brown count = snprintf(p,left,fmt,x[i]); 5188a381b04SJed Brown if (count < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"snprintf()"); 5198a381b04SJed Brown if (count >= left) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Insufficient space in buffer"); 5208a381b04SJed Brown left -= count; 5218a381b04SJed Brown p += count; 5228a381b04SJed Brown *p++ = ' '; 5238a381b04SJed Brown } 5248a381b04SJed Brown p[i ? 0 : -1] = 0; 5258a381b04SJed Brown PetscFunctionReturn(0); 5268a381b04SJed Brown } 5278a381b04SJed Brown 5288a381b04SJed Brown #undef __FUNCT__ 5298a381b04SJed Brown #define __FUNCT__ "TSView_ARKIMEX" 5308a381b04SJed Brown static PetscErrorCode TSView_ARKIMEX(TS ts,PetscViewer viewer) 5318a381b04SJed Brown { 5328a381b04SJed Brown TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 5338a381b04SJed Brown ARKTableau tab = ark->tableau; 5348a381b04SJed Brown PetscBool iascii; 5358a381b04SJed Brown PetscErrorCode ierr; 5368a381b04SJed Brown 5378a381b04SJed Brown PetscFunctionBegin; 5388a381b04SJed Brown ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 5398a381b04SJed Brown if (iascii) { 5408a381b04SJed Brown const TSARKIMEXType arktype; 5418a381b04SJed Brown char buf[512]; 5428a381b04SJed Brown ierr = TSARKIMEXGetType(ts,&arktype);CHKERRQ(ierr); 5438a381b04SJed Brown ierr = PetscViewerASCIIPrintf(viewer," ARK IMEX %s\n",arktype);CHKERRQ(ierr); 5448a381b04SJed Brown ierr = PetscFormatRealArray(buf,sizeof buf,"% 8.6f",tab->s,tab->ct);CHKERRQ(ierr); 54531f6fcc0SJed Brown ierr = PetscViewerASCIIPrintf(viewer," Stiff abscissa ct = %s\n",buf);CHKERRQ(ierr); 54631f6fcc0SJed Brown ierr = PetscFormatRealArray(buf,sizeof buf,"% 8.6f",tab->s,tab->c);CHKERRQ(ierr); 54731f6fcc0SJed Brown ierr = PetscViewerASCIIPrintf(viewer," Nonstiff abscissa c = %s\n",buf);CHKERRQ(ierr); 5488a381b04SJed Brown } 5498a381b04SJed Brown PetscFunctionReturn(0); 5508a381b04SJed Brown } 5518a381b04SJed Brown 5528a381b04SJed Brown #undef __FUNCT__ 5538a381b04SJed Brown #define __FUNCT__ "TSARKIMEXSetType" 5548a381b04SJed Brown /*@C 5558a381b04SJed Brown TSARKIMEXSetType - Set the type of ARK IMEX scheme 5568a381b04SJed Brown 5578a381b04SJed Brown Logically collective 5588a381b04SJed Brown 5598a381b04SJed Brown Input Parameter: 5608a381b04SJed Brown + ts - timestepping context 5618a381b04SJed Brown - arktype - type of ARK-IMEX scheme 5628a381b04SJed Brown 5638a381b04SJed Brown Level: intermediate 5648a381b04SJed Brown 5658a381b04SJed Brown .seealso: TSARKIMEXGetType() 5668a381b04SJed Brown @*/ 5678a381b04SJed Brown PetscErrorCode TSARKIMEXSetType(TS ts,const TSARKIMEXType arktype) 5688a381b04SJed Brown { 5698a381b04SJed Brown PetscErrorCode ierr; 5708a381b04SJed Brown 5718a381b04SJed Brown PetscFunctionBegin; 5728a381b04SJed Brown PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5738a381b04SJed Brown ierr = PetscTryMethod(ts,"TSARKIMEXSetType_C",(TS,const TSARKIMEXType),(ts,arktype));CHKERRQ(ierr); 5748a381b04SJed Brown PetscFunctionReturn(0); 5758a381b04SJed Brown } 5768a381b04SJed Brown 5778a381b04SJed Brown #undef __FUNCT__ 5788a381b04SJed Brown #define __FUNCT__ "TSARKIMEXGetType" 5798a381b04SJed Brown /*@C 5808a381b04SJed Brown TSARKIMEXGetType - Get the type of ARK IMEX scheme 5818a381b04SJed Brown 5828a381b04SJed Brown Logically collective 5838a381b04SJed Brown 5848a381b04SJed Brown Input Parameter: 5858a381b04SJed Brown . ts - timestepping context 5868a381b04SJed Brown 5878a381b04SJed Brown Output Parameter: 5888a381b04SJed Brown . arktype - type of ARK-IMEX scheme 5898a381b04SJed Brown 5908a381b04SJed Brown Level: intermediate 5918a381b04SJed Brown 5928a381b04SJed Brown .seealso: TSARKIMEXGetType() 5938a381b04SJed Brown @*/ 5948a381b04SJed Brown PetscErrorCode TSARKIMEXGetType(TS ts,const TSARKIMEXType *arktype) 5958a381b04SJed Brown { 5968a381b04SJed Brown PetscErrorCode ierr; 5978a381b04SJed Brown 5988a381b04SJed Brown PetscFunctionBegin; 5998a381b04SJed Brown PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6008a381b04SJed Brown ierr = PetscUseMethod(ts,"TSARKIMEXGetType_C",(TS,const TSARKIMEXType*),(ts,arktype));CHKERRQ(ierr); 6018a381b04SJed Brown PetscFunctionReturn(0); 6028a381b04SJed Brown } 6038a381b04SJed Brown 6048a381b04SJed Brown EXTERN_C_BEGIN 6058a381b04SJed Brown #undef __FUNCT__ 6068a381b04SJed Brown #define __FUNCT__ "TSARKIMEXGetType_ARKIMEX" 6078a381b04SJed Brown PetscErrorCode TSARKIMEXGetType_ARKIMEX(TS ts,const TSARKIMEXType *arktype) 6088a381b04SJed Brown { 6098a381b04SJed Brown TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 6108a381b04SJed Brown PetscErrorCode ierr; 6118a381b04SJed Brown 6128a381b04SJed Brown PetscFunctionBegin; 6138a381b04SJed Brown if (!ark->tableau) {ierr = TSARKIMEXSetType(ts,TSARKIMEXDefault);CHKERRQ(ierr);} 6148a381b04SJed Brown *arktype = ark->tableau->name; 6158a381b04SJed Brown PetscFunctionReturn(0); 6168a381b04SJed Brown } 6178a381b04SJed Brown #undef __FUNCT__ 6188a381b04SJed Brown #define __FUNCT__ "TSARKIMEXSetType_ARKIMEX" 6198a381b04SJed Brown PetscErrorCode TSARKIMEXSetType_ARKIMEX(TS ts,const TSARKIMEXType arktype) 6208a381b04SJed Brown { 6218a381b04SJed Brown TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 6228a381b04SJed Brown PetscErrorCode ierr; 6238a381b04SJed Brown PetscBool match; 6248a381b04SJed Brown ARKTableauLink link; 6258a381b04SJed Brown 6268a381b04SJed Brown PetscFunctionBegin; 6278a381b04SJed Brown if (ark->tableau) { 6288a381b04SJed Brown ierr = PetscStrcmp(ark->tableau->name,arktype,&match);CHKERRQ(ierr); 6298a381b04SJed Brown if (match) PetscFunctionReturn(0); 6308a381b04SJed Brown } 6318a381b04SJed Brown for (link = ARKTableauList; link; link=link->next) { 6328a381b04SJed Brown ierr = PetscStrcmp(link->tab.name,arktype,&match);CHKERRQ(ierr); 6338a381b04SJed Brown if (match) { 6348a381b04SJed Brown ierr = TSReset_ARKIMEX(ts);CHKERRQ(ierr); 6358a381b04SJed Brown ark->tableau = &link->tab; 6368a381b04SJed Brown PetscFunctionReturn(0); 6378a381b04SJed Brown } 6388a381b04SJed Brown } 6398a381b04SJed Brown SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_ARG_UNKNOWN_TYPE,"Could not find '%s'",arktype); 6408a381b04SJed Brown PetscFunctionReturn(0); 6418a381b04SJed Brown } 6428a381b04SJed Brown EXTERN_C_END 6438a381b04SJed Brown 6448a381b04SJed Brown /* ------------------------------------------------------------ */ 6458a381b04SJed Brown /*MC 6468a381b04SJed Brown TSARKIMEX - ODE solver using Additive Runge-Kutta IMEX schemes 6478a381b04SJed Brown 648fca742c7SJed Brown These methods are intended for problems with well-separated time scales, especially when a slow scale is strongly 649fca742c7SJed Brown nonlinear such that it is expensive to solve with a fully implicit method. The user should provide the stiff part 650fca742c7SJed Brown of the equation using TSSetIFunction() and the non-stiff part with TSSetRHSFunction(). 651fca742c7SJed Brown 652fca742c7SJed Brown Notes: 653fca742c7SJed Brown This method currently only works with ODE, for which the stiff part G(t,X,Xdot) has the form Xdot + Ghat(t,X). 654fca742c7SJed Brown 6558a381b04SJed Brown Level: beginner 6568a381b04SJed Brown 657fca742c7SJed Brown .seealso: TSCreate(), TS, TSSetType(), TSARKIMEXRegister() 6588a381b04SJed Brown 6598a381b04SJed Brown M*/ 6608a381b04SJed Brown EXTERN_C_BEGIN 6618a381b04SJed Brown #undef __FUNCT__ 6628a381b04SJed Brown #define __FUNCT__ "TSCreate_ARKIMEX" 6638a381b04SJed Brown PetscErrorCode TSCreate_ARKIMEX(TS ts) 6648a381b04SJed Brown { 6658a381b04SJed Brown TS_ARKIMEX *th; 6668a381b04SJed Brown PetscErrorCode ierr; 6678a381b04SJed Brown 6688a381b04SJed Brown PetscFunctionBegin; 6698a381b04SJed Brown #if !defined(PETSC_USE_DYNAMIC_LIBRARIES) 6708a381b04SJed Brown ierr = TSARKIMEXInitializePackage(PETSC_NULL);CHKERRQ(ierr); 6718a381b04SJed Brown #endif 6728a381b04SJed Brown 6738a381b04SJed Brown ts->ops->reset = TSReset_ARKIMEX; 6748a381b04SJed Brown ts->ops->destroy = TSDestroy_ARKIMEX; 6758a381b04SJed Brown ts->ops->view = TSView_ARKIMEX; 6768a381b04SJed Brown ts->ops->setup = TSSetUp_ARKIMEX; 6778a381b04SJed Brown ts->ops->step = TSStep_ARKIMEX; 678*cd652676SJed Brown ts->ops->interpolate = TSInterpolate_ARKIMEX; 6798a381b04SJed Brown ts->ops->setfromoptions = TSSetFromOptions_ARKIMEX; 6808a381b04SJed Brown ts->ops->snesfunction = SNESTSFormFunction_ARKIMEX; 6818a381b04SJed Brown ts->ops->snesjacobian = SNESTSFormJacobian_ARKIMEX; 6828a381b04SJed Brown 6838a381b04SJed Brown ierr = PetscNewLog(ts,TS_ARKIMEX,&th);CHKERRQ(ierr); 6848a381b04SJed Brown ts->data = (void*)th; 6858a381b04SJed Brown 6868a381b04SJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSARKIMEXGetType_C","TSARKIMEXGetType_ARKIMEX",TSARKIMEXGetType_ARKIMEX);CHKERRQ(ierr); 6878a381b04SJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSARKIMEXSetType_C","TSARKIMEXSetType_ARKIMEX",TSARKIMEXSetType_ARKIMEX);CHKERRQ(ierr); 6888a381b04SJed Brown PetscFunctionReturn(0); 6898a381b04SJed Brown } 6908a381b04SJed Brown EXTERN_C_END 691