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 144f385281SJed Brown static const TSARKIMEXType TSARKIMEXDefault = TSARKIMEX2E; 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; 214f385281SJed Brown PetscInt order; /* Classical approximation order of the method */ 224f385281SJed Brown PetscInt s; /* Number of stages */ 234f385281SJed Brown PetscInt pinterp; /* Interpolation order */ 244f385281SJed Brown PetscReal *At,*bt,*ct; /* Stiff tableau */ 258a381b04SJed Brown PetscReal *A,*b,*c; /* Non-stiff tableau */ 26cd652676SJed Brown PetscReal *binterpt,*binterp; /* Dense output formula */ 278a381b04SJed Brown }; 288a381b04SJed Brown typedef struct _ARKTableauLink *ARKTableauLink; 298a381b04SJed Brown struct _ARKTableauLink { 308a381b04SJed Brown struct _ARKTableau tab; 318a381b04SJed Brown ARKTableauLink next; 328a381b04SJed Brown }; 338a381b04SJed Brown static ARKTableauLink ARKTableauList; 348a381b04SJed Brown 358a381b04SJed Brown typedef struct { 368a381b04SJed Brown ARKTableau tableau; 378a381b04SJed Brown Vec *Y; /* States computed during the step */ 388a381b04SJed Brown Vec *YdotI; /* Time derivatives for the stiff part */ 398a381b04SJed Brown Vec *YdotRHS; /* Function evaluations for the non-stiff part */ 408a381b04SJed Brown Vec Ydot; /* Work vector holding Ydot during residual evaluation */ 418a381b04SJed Brown Vec Work; /* Generic work vector */ 428a381b04SJed Brown Vec Z; /* Ydot = shift(Y-Z) */ 438a381b04SJed Brown PetscScalar *work; /* Scalar work */ 448a381b04SJed Brown PetscReal shift; 458a381b04SJed Brown PetscReal stage_time; 46*4cc180ffSJed Brown PetscBool imex; 478a381b04SJed Brown } TS_ARKIMEX; 488a381b04SJed Brown 498a381b04SJed Brown #undef __FUNCT__ 508a381b04SJed Brown #define __FUNCT__ "TSARKIMEXRegisterAll" 518a381b04SJed Brown /*@C 528a381b04SJed Brown TSARKIMEXRegisterAll - Registers all of the additive Runge-Kutta implicit-explicit methods in TSARKIMEX 538a381b04SJed Brown 54fca742c7SJed Brown Not Collective, but should be called by all processes which will need the schemes to be registered 558a381b04SJed Brown 568a381b04SJed Brown Level: advanced 578a381b04SJed Brown 588a381b04SJed Brown .keywords: TS, TSARKIMEX, register, all 598a381b04SJed Brown 608a381b04SJed Brown .seealso: TSARKIMEXRegisterDestroy() 618a381b04SJed Brown @*/ 628a381b04SJed Brown PetscErrorCode TSARKIMEXRegisterAll(void) 638a381b04SJed Brown { 648a381b04SJed Brown PetscErrorCode ierr; 658a381b04SJed Brown 668a381b04SJed Brown PetscFunctionBegin; 678a381b04SJed Brown if (TSARKIMEXRegisterAllCalled) PetscFunctionReturn(0); 688a381b04SJed Brown TSARKIMEXRegisterAllCalled = PETSC_TRUE; 698a381b04SJed Brown 708a381b04SJed Brown { 718a381b04SJed Brown const PetscReal 728a381b04SJed Brown A[3][3] = {{0,0,0}, 738a381b04SJed Brown {0.41421356237309504880,0,0}, 748a381b04SJed Brown {0.75,0.25,0}}, 758a381b04SJed Brown At[3][3] = {{0,0,0}, 768a381b04SJed Brown {0.12132034355964257320,0.29289321881345247560,0}, 7706db7b1cSJed Brown {0.20710678118654752440,0.50000000000000000000,0.29289321881345247560}}, 7806db7b1cSJed Brown binterpt[3][2] = {{1,-0.5},{0,0},{0,0.5}}; 7906db7b1cSJed Brown ierr = TSARKIMEXRegister(TSARKIMEX2D,2,3,&At[0][0],PETSC_NULL,PETSC_NULL,&A[0][0],PETSC_NULL,PETSC_NULL,2,binterpt[0],PETSC_NULL);CHKERRQ(ierr); 808a381b04SJed Brown } 8106db7b1cSJed Brown { /* Optimal for linear implicit part */ 82a3a57f36SJed Brown const PetscReal s2 = sqrt(2), 83a3a57f36SJed Brown A[3][3] = {{0,0,0}, 84a3a57f36SJed Brown {2-s2,0,0}, 85a3a57f36SJed Brown {(3-2*s2)/6,(3+2*s2)/6,0}}, 86a3a57f36SJed Brown At[3][3] = {{0,0,0}, 87a3a57f36SJed Brown {1-1/s2,1-1/s2,0}, 88cd652676SJed Brown {1/(2*s2),1/(2*s2),1-1/s2}}, 89cd652676SJed Brown binterpt[3][2] = {{1,-0.5},{0,0},{0,0.5}}; 90cd652676SJed 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); 91a3a57f36SJed Brown } 92a3a57f36SJed Brown { 93a3a57f36SJed Brown const PetscReal 94a3a57f36SJed Brown A[4][4] = {{0,0,0,0}, 954040e9f2SJed Brown {1767732205903./2027836641118.,0,0,0}, 964040e9f2SJed Brown {5535828885825./10492691773637.,788022342437./10882634858940.,0,0}, 974040e9f2SJed Brown {6485989280629./16251701735622.,-4246266847089./9704473918619.,10755448449292./10357097424841.,0}}, 98a3a57f36SJed Brown At[4][4] = {{0,0,0,0}, 994040e9f2SJed Brown {1767732205903./4055673282236.,1767732205903./4055673282236.,0,0}, 1004040e9f2SJed Brown {2746238789719./10658868560708.,-640167445237./6845629431997.,1767732205903./4055673282236.,0}, 1014040e9f2SJed Brown {1471266399579./7840856788654.,-4482444167858./7529755066697.,11266239266428./11593286722821.,1767732205903./4055673282236.}}, 1024040e9f2SJed Brown binterpt[4][2] = {{4655552711362./22874653954995., -215264564351./13552729205753.}, 1034040e9f2SJed Brown {-18682724506714./9892148508045.,17870216137069./13817060693119.}, 1044040e9f2SJed Brown {34259539580243./13192909600954.,-28141676662227./17317692491321.}, 1054040e9f2SJed Brown {584795268549./6622622206610., 2508943948391./7218656332882.}}; 106cd652676SJed 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); 107a3a57f36SJed Brown } 108a3a57f36SJed Brown { 109a3a57f36SJed Brown const PetscReal 110a3a57f36SJed Brown A[6][6] = {{0,0,0,0,0,0}, 111a3a57f36SJed Brown {1./2,0,0,0,0,0}, 1124040e9f2SJed Brown {13861./62500.,6889./62500.,0,0,0,0}, 1134040e9f2SJed Brown {-116923316275./2393684061468.,-2731218467317./15368042101831.,9408046702089./11113171139209.,0,0,0}, 1144040e9f2SJed Brown {-451086348788./2902428689909.,-2682348792572./7519795681897.,12662868775082./11960479115383.,3355817975965./11060851509271.,0,0}, 1154040e9f2SJed Brown {647845179188./3216320057751.,73281519250./8382639484533.,552539513391./3454668386233.,3354512671639./8306763924573.,4040./17871.,0}}, 116a3a57f36SJed Brown At[6][6] = {{0,0,0,0,0,0}, 117a3a57f36SJed Brown {1./4,1./4,0,0,0,0}, 1184040e9f2SJed Brown {8611./62500.,-1743./31250.,1./4,0,0,0}, 1194040e9f2SJed Brown {5012029./34652500.,-654441./2922500.,174375./388108.,1./4,0,0}, 1204040e9f2SJed Brown {15267082809./155376265600.,-71443401./120774400.,730878875./902184768.,2285395./8070912.,1./4,0}, 1214040e9f2SJed Brown {82889./524892.,0,15625./83664.,69875./102672.,-2260./8211,1./4}}, 1224040e9f2SJed Brown binterpt[6][3] = {{6943876665148./7220017795957.,-54480133./30881146.,6818779379841./7100303317025.}, 123cd652676SJed Brown {0,0,0}, 1244040e9f2SJed Brown {7640104374378./9702883013639.,-11436875./14766696.,2173542590792./12501825683035.}, 1254040e9f2SJed Brown {-20649996744609./7521556579894.,174696575./18121608.,-31592104683404./5083833661969.}, 1264040e9f2SJed Brown {8854892464581./2390941311638.,-12120380./966161.,61146701046299./7138195549469.}, 1274040e9f2SJed Brown {-11397109935349./6675773540249.,3843./706.,-17219254887155./4939391667607.}}; 128cd652676SJed 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); 129a3a57f36SJed Brown } 130a3a57f36SJed Brown { 131a3a57f36SJed Brown const PetscReal 132a3a57f36SJed Brown A[8][8] = {{0,0,0,0,0,0,0,0}, 133a3a57f36SJed Brown {41./100,0,0,0,0,0,0,0}, 1344040e9f2SJed Brown {367902744464./2072280473677.,677623207551./8224143866563.,0,0,0,0,0,0}, 1354040e9f2SJed Brown {1268023523408./10340822734521.,0,1029933939417./13636558850479.,0,0,0,0,0}, 1364040e9f2SJed Brown {14463281900351./6315353703477.,0,66114435211212./5879490589093.,-54053170152839./4284798021562.,0,0,0,0}, 1374040e9f2SJed Brown {14090043504691./34967701212078.,0,15191511035443./11219624916014.,-18461159152457./12425892160975.,-281667163811./9011619295870.,0,0,0}, 1384040e9f2SJed Brown {19230459214898./13134317526959.,0,21275331358303./2942455364971.,-38145345988419./4862620318723.,-1./8,-1./8,0,0}, 1394040e9f2SJed Brown {-19977161125411./11928030595625.,0,-40795976796054./6384907823539.,177454434618887./12078138498510.,782672205425./8267701900261.,-69563011059811./9646580694205.,7356628210526./4942186776405.,0}}, 140a3a57f36SJed Brown At[8][8] = {{0,0,0,0,0,0,0,0}, 1414040e9f2SJed Brown {41./200.,41./200.,0,0,0,0,0,0}, 1424040e9f2SJed Brown {41./400.,-567603406766./11931857230679.,41./200.,0,0,0,0,0}, 1434040e9f2SJed Brown {683785636431./9252920307686.,0,-110385047103./1367015193373.,41./200.,0,0,0,0}, 1444040e9f2SJed Brown {3016520224154./10081342136671.,0,30586259806659./12414158314087.,-22760509404356./11113319521817.,41./200.,0,0,0}, 1454040e9f2SJed Brown {218866479029./1489978393911.,0,638256894668./5436446318841.,-1179710474555./5321154724896.,-60928119172./8023461067671.,41./200.,0,0}, 1464040e9f2SJed Brown {1020004230633./5715676835656.,0,25762820946817./25263940353407.,-2161375909145./9755907335909.,-211217309593./5846859502534.,-4269925059573./7827059040749.,41./200,0}, 1474040e9f2SJed Brown {-872700587467./9133579230613.,0,0,22348218063261./9555858737531.,-1143369518992./8141816002931.,-39379526789629./19018526304540.,32727382324388./42900044865799.,41./200.}}, 1484040e9f2SJed Brown binterpt[8][3] = {{-17674230611817./10670229744614. , 43486358583215./12773830924787. , -9257016797708./5021505065439.}, 149cd652676SJed Brown {0 , 0 , 0 }, 150cd652676SJed Brown {0 , 0 , 0 }, 1514040e9f2SJed Brown {65168852399939./7868540260826. , -91478233927265./11067650958493., 26096422576131./11239449250142.}, 1524040e9f2SJed Brown {15494834004392./5936557850923. , -79368583304911./10890268929626., 92396832856987./20362823103730.}, 1534040e9f2SJed Brown {-99329723586156./26959484932159., -12239297817655./9152339842473. , 30029262896817./10175596800299.}, 1544040e9f2SJed Brown {-19024464361622./5461577185407. , 115839755401235./10719374521269., -26136350496073./3983972220547.}, 1554040e9f2SJed Brown {-6511271360970./6095937251113. , 5843115559534./2180450260947. , -5289405421727./3760307252460. }}; 156cd652676SJed 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); 157a3a57f36SJed Brown } 158a3a57f36SJed Brown 1598a381b04SJed Brown PetscFunctionReturn(0); 1608a381b04SJed Brown } 1618a381b04SJed Brown 1628a381b04SJed Brown #undef __FUNCT__ 1638a381b04SJed Brown #define __FUNCT__ "TSARKIMEXRegisterDestroy" 1648a381b04SJed Brown /*@C 1658a381b04SJed Brown TSARKIMEXRegisterDestroy - Frees the list of schemes that were registered by TSARKIMEXRegister(). 1668a381b04SJed Brown 1678a381b04SJed Brown Not Collective 1688a381b04SJed Brown 1698a381b04SJed Brown Level: advanced 1708a381b04SJed Brown 1718a381b04SJed Brown .keywords: TSARKIMEX, register, destroy 1728a381b04SJed Brown .seealso: TSARKIMEXRegister(), TSARKIMEXRegisterAll(), TSARKIMEXRegisterDynamic() 1738a381b04SJed Brown @*/ 1748a381b04SJed Brown PetscErrorCode TSARKIMEXRegisterDestroy(void) 1758a381b04SJed Brown { 1768a381b04SJed Brown PetscErrorCode ierr; 1778a381b04SJed Brown ARKTableauLink link; 1788a381b04SJed Brown 1798a381b04SJed Brown PetscFunctionBegin; 1808a381b04SJed Brown while ((link = ARKTableauList)) { 1818a381b04SJed Brown ARKTableau t = &link->tab; 1828a381b04SJed Brown ARKTableauList = link->next; 1838a381b04SJed Brown ierr = PetscFree6(t->At,t->bt,t->ct,t->A,t->b,t->c);CHKERRQ(ierr); 184cd652676SJed Brown ierr = PetscFree2(t->binterpt,t->binterp);CHKERRQ(ierr); 1858a381b04SJed Brown ierr = PetscFree(t->name);CHKERRQ(ierr); 1868a381b04SJed Brown ierr = PetscFree(link);CHKERRQ(ierr); 1878a381b04SJed Brown } 1888a381b04SJed Brown TSARKIMEXRegisterAllCalled = PETSC_FALSE; 1898a381b04SJed Brown PetscFunctionReturn(0); 1908a381b04SJed Brown } 1918a381b04SJed Brown 1928a381b04SJed Brown #undef __FUNCT__ 1938a381b04SJed Brown #define __FUNCT__ "TSARKIMEXInitializePackage" 1948a381b04SJed Brown /*@C 1958a381b04SJed Brown TSARKIMEXInitializePackage - This function initializes everything in the TSARKIMEX package. It is called 1968a381b04SJed Brown from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to TSCreate_ARKIMEX() 1978a381b04SJed Brown when using static libraries. 1988a381b04SJed Brown 1998a381b04SJed Brown Input Parameter: 2008a381b04SJed Brown path - The dynamic library path, or PETSC_NULL 2018a381b04SJed Brown 2028a381b04SJed Brown Level: developer 2038a381b04SJed Brown 2048a381b04SJed Brown .keywords: TS, TSARKIMEX, initialize, package 2058a381b04SJed Brown .seealso: PetscInitialize() 2068a381b04SJed Brown @*/ 2078a381b04SJed Brown PetscErrorCode TSARKIMEXInitializePackage(const char path[]) 2088a381b04SJed Brown { 2098a381b04SJed Brown PetscErrorCode ierr; 2108a381b04SJed Brown 2118a381b04SJed Brown PetscFunctionBegin; 2128a381b04SJed Brown if (TSARKIMEXPackageInitialized) PetscFunctionReturn(0); 2138a381b04SJed Brown TSARKIMEXPackageInitialized = PETSC_TRUE; 2148a381b04SJed Brown ierr = TSARKIMEXRegisterAll();CHKERRQ(ierr); 2158a381b04SJed Brown ierr = PetscRegisterFinalize(TSARKIMEXFinalizePackage);CHKERRQ(ierr); 2168a381b04SJed Brown PetscFunctionReturn(0); 2178a381b04SJed Brown } 2188a381b04SJed Brown 2198a381b04SJed Brown #undef __FUNCT__ 2208a381b04SJed Brown #define __FUNCT__ "TSARKIMEXFinalizePackage" 2218a381b04SJed Brown /*@C 2228a381b04SJed Brown TSARKIMEXFinalizePackage - This function destroys everything in the TSARKIMEX package. It is 2238a381b04SJed Brown called from PetscFinalize(). 2248a381b04SJed Brown 2258a381b04SJed Brown Level: developer 2268a381b04SJed Brown 2278a381b04SJed Brown .keywords: Petsc, destroy, package 2288a381b04SJed Brown .seealso: PetscFinalize() 2298a381b04SJed Brown @*/ 2308a381b04SJed Brown PetscErrorCode TSARKIMEXFinalizePackage(void) 2318a381b04SJed Brown { 2328a381b04SJed Brown PetscErrorCode ierr; 2338a381b04SJed Brown 2348a381b04SJed Brown PetscFunctionBegin; 2358a381b04SJed Brown TSARKIMEXPackageInitialized = PETSC_FALSE; 2368a381b04SJed Brown ierr = TSARKIMEXRegisterDestroy();CHKERRQ(ierr); 2378a381b04SJed Brown PetscFunctionReturn(0); 2388a381b04SJed Brown } 2398a381b04SJed Brown 2408a381b04SJed Brown #undef __FUNCT__ 2418a381b04SJed Brown #define __FUNCT__ "TSARKIMEXRegister" 242cd652676SJed Brown /*@C 243cd652676SJed Brown TSARKIMEXRegister - register an ARK IMEX scheme by providing the entries in the Butcher tableau and optionally embedded approximations and interpolation 244cd652676SJed Brown 245cd652676SJed Brown Not Collective, but the same schemes should be registered on all processes on which they will be used 246cd652676SJed Brown 247cd652676SJed Brown Input Parameters: 248cd652676SJed Brown + name - identifier for method 249cd652676SJed Brown . order - approximation order of method 250cd652676SJed Brown . s - number of stages, this is the dimension of the matrices below 251cd652676SJed Brown . At - Butcher table of stage coefficients for stiff part (dimension s*s, row-major) 252cd652676SJed Brown . bt - Butcher table for completing the stiff part of the step (dimension s; PETSC_NULL to use the last row of At) 253cd652676SJed Brown . ct - Abscissa of each stiff stage (dimension s, PETSC_NULL to use row sums of At) 254cd652676SJed Brown . A - Non-stiff stage coefficients (dimension s*s, row-major) 255cd652676SJed Brown . b - Non-stiff step completion table (dimension s; PETSC_NULL to use last row of At) 256cd652676SJed Brown . c - Non-stiff abscissa (dimension s; PETSC_NULL to use row sums of A) 257cd652676SJed Brown . pinterp - Order of the interpolation scheme, equal to the number of columns of binterpt and binterp 258cd652676SJed Brown . binterpt - Coefficients of the interpolation formula for the stiff part (dimension s*pinterp) 259cd652676SJed Brown - binterp - Coefficients of the interpolation formula for the non-stiff part (dimension s*pinterp; PETSC_NULL to reuse binterpt) 260cd652676SJed Brown 261cd652676SJed Brown Notes: 262cd652676SJed Brown Several ARK IMEX methods are provided, this function is only needed to create new methods. 263cd652676SJed Brown 264cd652676SJed Brown Level: advanced 265cd652676SJed Brown 266cd652676SJed Brown .keywords: TS, register 267cd652676SJed Brown 268cd652676SJed Brown .seealso: TSARKIMEX 269cd652676SJed Brown @*/ 2708a381b04SJed Brown PetscErrorCode TSARKIMEXRegister(const TSARKIMEXType name,PetscInt order,PetscInt s, 2718a381b04SJed Brown const PetscReal At[],const PetscReal bt[],const PetscReal ct[], 272cd652676SJed Brown const PetscReal A[],const PetscReal b[],const PetscReal c[], 273cd652676SJed Brown PetscInt pinterp,const PetscReal binterpt[],const PetscReal binterp[]) 2748a381b04SJed Brown { 2758a381b04SJed Brown PetscErrorCode ierr; 2768a381b04SJed Brown ARKTableauLink link; 2778a381b04SJed Brown ARKTableau t; 2788a381b04SJed Brown PetscInt i,j; 2798a381b04SJed Brown 2808a381b04SJed Brown PetscFunctionBegin; 2818a381b04SJed Brown ierr = PetscMalloc(sizeof(*link),&link);CHKERRQ(ierr); 282cd652676SJed Brown ierr = PetscMemzero(link,sizeof(*link));CHKERRQ(ierr); 2838a381b04SJed Brown t = &link->tab; 2848a381b04SJed Brown ierr = PetscStrallocpy(name,&t->name);CHKERRQ(ierr); 2858a381b04SJed Brown t->order = order; 2868a381b04SJed Brown t->s = s; 2878a381b04SJed 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); 2888a381b04SJed Brown ierr = PetscMemcpy(t->At,At,s*s*sizeof(At[0]));CHKERRQ(ierr); 2898a381b04SJed Brown ierr = PetscMemcpy(t->A,A,s*s*sizeof(A[0]));CHKERRQ(ierr); 2908a381b04SJed Brown if (bt) {ierr = PetscMemcpy(t->bt,bt,s*sizeof(bt[0]));CHKERRQ(ierr);} 2918a381b04SJed Brown else for (i=0; i<s; i++) t->bt[i] = At[(s-1)*s+i]; 2928a381b04SJed Brown if (b) {ierr = PetscMemcpy(t->b,b,s*sizeof(b[0]));CHKERRQ(ierr);} 2938a381b04SJed Brown else for (i=0; i<s; i++) t->b[i] = At[(s-1)*s+i]; 2948a381b04SJed Brown if (ct) {ierr = PetscMemcpy(t->ct,ct,s*sizeof(ct[0]));CHKERRQ(ierr);} 2958a381b04SJed 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]; 2968a381b04SJed Brown if (c) {ierr = PetscMemcpy(t->c,c,s*sizeof(c[0]));CHKERRQ(ierr);} 2978a381b04SJed 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]; 2984f385281SJed Brown t->pinterp = pinterp; 299cd652676SJed Brown ierr = PetscMalloc2(s*pinterp,PetscReal,&t->binterpt,s*pinterp,PetscReal,&t->binterp);CHKERRQ(ierr); 300cd652676SJed Brown ierr = PetscMemcpy(t->binterpt,binterpt,s*pinterp*sizeof(binterpt[0]));CHKERRQ(ierr); 301cd652676SJed Brown ierr = PetscMemcpy(t->binterp,binterp?binterp:binterpt,s*pinterp*sizeof(binterpt[0]));CHKERRQ(ierr); 3028a381b04SJed Brown link->next = ARKTableauList; 3038a381b04SJed Brown ARKTableauList = link; 3048a381b04SJed Brown PetscFunctionReturn(0); 3058a381b04SJed Brown } 3068a381b04SJed Brown 3078a381b04SJed Brown #undef __FUNCT__ 3088a381b04SJed Brown #define __FUNCT__ "TSStep_ARKIMEX" 3098a381b04SJed Brown static PetscErrorCode TSStep_ARKIMEX(TS ts) 3108a381b04SJed Brown { 3118a381b04SJed Brown TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 3128a381b04SJed Brown ARKTableau tab = ark->tableau; 3138a381b04SJed Brown const PetscInt s = tab->s; 3148a381b04SJed Brown const PetscReal *At = tab->At,*A = tab->A,*bt = tab->bt,*b = tab->b,*ct = tab->ct,*c = tab->c; 315406d0ec2SJed Brown PetscScalar *w = ark->work; 3168a381b04SJed Brown Vec *Y = ark->Y,*YdotI = ark->YdotI,*YdotRHS = ark->YdotRHS,Ydot = ark->Ydot,W = ark->Work,Z = ark->Z; 3178a381b04SJed Brown SNES snes; 3188a381b04SJed Brown PetscInt i,j,its,lits; 3198a381b04SJed Brown PetscReal h,t; 3208a381b04SJed Brown PetscErrorCode ierr; 3218a381b04SJed Brown 3228a381b04SJed Brown PetscFunctionBegin; 3238a381b04SJed Brown ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 3248a381b04SJed Brown h = ts->time_step = ts->next_time_step; 3258a381b04SJed Brown t = ts->ptime; 3268a381b04SJed Brown 3278a381b04SJed Brown for (i=0; i<s; i++) { 3288a381b04SJed Brown if (At[i*s+i] == 0) { /* This stage is explicit */ 3298a381b04SJed Brown ierr = VecCopy(ts->vec_sol,Y[i]);CHKERRQ(ierr); 3308a381b04SJed Brown for (j=0; j<i; j++) w[j] = -h*At[i*s+j]; 3318a381b04SJed Brown ierr = VecMAXPY(Y[i],i,w,YdotI);CHKERRQ(ierr); 3328a381b04SJed Brown for (j=0; j<i; j++) w[j] = h*A[i*s+j]; 3338a381b04SJed Brown ierr = VecMAXPY(Y[i],i,w,YdotRHS);CHKERRQ(ierr); 3348a381b04SJed Brown } else { 3358a381b04SJed Brown ark->stage_time = t + h*ct[i]; 3368a381b04SJed Brown ark->shift = 1./(h*At[i*s+i]); 3378a381b04SJed Brown /* Affine part */ 3388a381b04SJed Brown ierr = VecZeroEntries(W);CHKERRQ(ierr); 3398a381b04SJed Brown for (j=0; j<i; j++) w[j] = h*A[i*s+j]; 3408a381b04SJed Brown ierr = VecMAXPY(W,i,w,YdotRHS);CHKERRQ(ierr); 3418a381b04SJed Brown /* Ydot = shift*(Y-Z) */ 3428a381b04SJed Brown ierr = VecCopy(ts->vec_sol,Z);CHKERRQ(ierr); 3434f385281SJed Brown for (j=0; j<i; j++) w[j] = -h*At[i*s+j]; 3444f385281SJed Brown ierr = VecMAXPY(Z,i,w,YdotI);CHKERRQ(ierr); 3458a381b04SJed Brown /* Initial guess taken from last stage */ 3468a381b04SJed Brown ierr = VecCopy(i>0?Y[i-1]:ts->vec_sol,Y[i]);CHKERRQ(ierr); 3478a381b04SJed Brown ierr = SNESSolve(snes,W,Y[i]);CHKERRQ(ierr); 3488a381b04SJed Brown ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); 3498a381b04SJed Brown ierr = SNESGetLinearSolveIterations(snes,&lits);CHKERRQ(ierr); 3508a381b04SJed Brown ts->nonlinear_its += its; ts->linear_its += lits; 3518a381b04SJed Brown } 3528a381b04SJed Brown ierr = VecZeroEntries(Ydot);CHKERRQ(ierr); 353*4cc180ffSJed Brown ierr = TSComputeIFunction(ts,t+h*ct[i],Y[i],Ydot,YdotI[i],ark->imex);CHKERRQ(ierr); 354*4cc180ffSJed Brown if (ark->imex) { 3558a381b04SJed Brown ierr = TSComputeRHSFunction(ts,t+h*c[i],Y[i],YdotRHS[i]);CHKERRQ(ierr); 356*4cc180ffSJed Brown } else { 357*4cc180ffSJed Brown ierr = VecZeroEntries(YdotRHS[i]);CHKERRQ(ierr); 358*4cc180ffSJed Brown } 3598a381b04SJed Brown } 360a17b68daSJed Brown for (j=0; j<s; j++) w[j] = -h*bt[j]; 3618a381b04SJed Brown ierr = VecMAXPY(ts->vec_sol,s,w,YdotI);CHKERRQ(ierr); 3628a381b04SJed Brown for (j=0; j<s; j++) w[j] = h*b[j]; 3638a381b04SJed Brown ierr = VecMAXPY(ts->vec_sol,s,w,YdotRHS);CHKERRQ(ierr); 3648a381b04SJed Brown 3658a381b04SJed Brown ts->ptime += ts->time_step; 3668a381b04SJed Brown ts->next_time_step = ts->time_step; 3678a381b04SJed Brown ts->steps++; 3688a381b04SJed Brown PetscFunctionReturn(0); 3698a381b04SJed Brown } 3708a381b04SJed Brown 371cd652676SJed Brown #undef __FUNCT__ 372cd652676SJed Brown #define __FUNCT__ "TSInterpolate_ARKIMEX" 373cd652676SJed Brown static PetscErrorCode TSInterpolate_ARKIMEX(TS ts,PetscReal itime,Vec X) 374cd652676SJed Brown { 375cd652676SJed Brown TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 3764f385281SJed Brown PetscInt s = ark->tableau->s,pinterp = ark->tableau->pinterp,i,j; 3774f385281SJed Brown PetscReal tt,t = (itime - ts->ptime)/ts->time_step + 1; /* In the interval [0,1] */ 378cd652676SJed Brown PetscScalar *bt,*b; 379cd652676SJed Brown const PetscReal *Bt = ark->tableau->binterpt,*B = ark->tableau->binterp; 380cd652676SJed Brown PetscErrorCode ierr; 381cd652676SJed Brown 382cd652676SJed Brown PetscFunctionBegin; 383cd652676SJed Brown if (!Bt || !B) SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_SUP,"TSARKIMEX %s does not have an interpolation formula",ark->tableau->name); 384cd652676SJed Brown ierr = PetscMalloc2(s,PetscScalar,&bt,s,PetscScalar,&b);CHKERRQ(ierr); 385cd652676SJed Brown for (i=0; i<s; i++) bt[i] = b[i] = 0; 3864f385281SJed Brown for (j=0,tt=t; j<pinterp; j++,tt*=t) { 387cd652676SJed Brown for (i=0; i<s; i++) { 3884f385281SJed Brown bt[i] += ts->time_step * Bt[i*pinterp+j] * tt * -1.0; 3894f385281SJed Brown b[i] += ts->time_step * B[i*pinterp+j] * tt; 390cd652676SJed Brown } 391cd652676SJed Brown } 392cd652676SJed 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"); 393cd652676SJed Brown ierr = VecCopy(ark->Y[0],X);CHKERRQ(ierr); 394cd652676SJed Brown ierr = VecMAXPY(X,s,bt,ark->YdotI);CHKERRQ(ierr); 395cd652676SJed Brown ierr = VecMAXPY(X,s,b,ark->YdotRHS);CHKERRQ(ierr); 396cd652676SJed Brown ierr = PetscFree2(bt,b);CHKERRQ(ierr); 397cd652676SJed Brown PetscFunctionReturn(0); 398cd652676SJed Brown } 399cd652676SJed Brown 4008a381b04SJed Brown /*------------------------------------------------------------*/ 4018a381b04SJed Brown #undef __FUNCT__ 4028a381b04SJed Brown #define __FUNCT__ "TSReset_ARKIMEX" 4038a381b04SJed Brown static PetscErrorCode TSReset_ARKIMEX(TS ts) 4048a381b04SJed Brown { 4058a381b04SJed Brown TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 4068a381b04SJed Brown PetscInt s; 4078a381b04SJed Brown PetscErrorCode ierr; 4088a381b04SJed Brown 4098a381b04SJed Brown PetscFunctionBegin; 4108a381b04SJed Brown if (!ark->tableau) PetscFunctionReturn(0); 4118a381b04SJed Brown s = ark->tableau->s; 4128a381b04SJed Brown ierr = VecDestroyVecs(s,&ark->Y);CHKERRQ(ierr); 4138a381b04SJed Brown ierr = VecDestroyVecs(s,&ark->YdotI);CHKERRQ(ierr); 4148a381b04SJed Brown ierr = VecDestroyVecs(s,&ark->YdotRHS);CHKERRQ(ierr); 4158a381b04SJed Brown ierr = VecDestroy(&ark->Ydot);CHKERRQ(ierr); 4168a381b04SJed Brown ierr = VecDestroy(&ark->Work);CHKERRQ(ierr); 4178a381b04SJed Brown ierr = VecDestroy(&ark->Z);CHKERRQ(ierr); 4188a381b04SJed Brown ierr = PetscFree(ark->work);CHKERRQ(ierr); 4198a381b04SJed Brown PetscFunctionReturn(0); 4208a381b04SJed Brown } 4218a381b04SJed Brown 4228a381b04SJed Brown #undef __FUNCT__ 4238a381b04SJed Brown #define __FUNCT__ "TSDestroy_ARKIMEX" 4248a381b04SJed Brown static PetscErrorCode TSDestroy_ARKIMEX(TS ts) 4258a381b04SJed Brown { 4268a381b04SJed Brown PetscErrorCode ierr; 4278a381b04SJed Brown 4288a381b04SJed Brown PetscFunctionBegin; 4298a381b04SJed Brown ierr = TSReset_ARKIMEX(ts);CHKERRQ(ierr); 4308a381b04SJed Brown ierr = PetscFree(ts->data);CHKERRQ(ierr); 4318a381b04SJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSARKIMEXGetType_C","",PETSC_NULL);CHKERRQ(ierr); 4328a381b04SJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSARKIMEXSetType_C","",PETSC_NULL);CHKERRQ(ierr); 4338a381b04SJed Brown PetscFunctionReturn(0); 4348a381b04SJed Brown } 4358a381b04SJed Brown 4368a381b04SJed Brown /* 4378a381b04SJed Brown This defines the nonlinear equation that is to be solved with SNES 4388a381b04SJed Brown G(U) = F[t0+Theta*dt, U, (U-U0)*shift] = 0 4398a381b04SJed Brown */ 4408a381b04SJed Brown #undef __FUNCT__ 4418a381b04SJed Brown #define __FUNCT__ "SNESTSFormFunction_ARKIMEX" 4428a381b04SJed Brown static PetscErrorCode SNESTSFormFunction_ARKIMEX(SNES snes,Vec X,Vec F,TS ts) 4438a381b04SJed Brown { 4448a381b04SJed Brown TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 4458a381b04SJed Brown PetscErrorCode ierr; 4468a381b04SJed Brown 4478a381b04SJed Brown PetscFunctionBegin; 4488a381b04SJed Brown ierr = VecAXPBYPCZ(ark->Ydot,-ark->shift,ark->shift,0,ark->Z,X);CHKERRQ(ierr); /* Ydot = shift*(X-Z) */ 449*4cc180ffSJed Brown ierr = TSComputeIFunction(ts,ark->stage_time,X,ark->Ydot,F,ark->imex);CHKERRQ(ierr); 4508a381b04SJed Brown PetscFunctionReturn(0); 4518a381b04SJed Brown } 4528a381b04SJed Brown 4538a381b04SJed Brown #undef __FUNCT__ 4548a381b04SJed Brown #define __FUNCT__ "SNESTSFormJacobian_ARKIMEX" 4558a381b04SJed Brown static PetscErrorCode SNESTSFormJacobian_ARKIMEX(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *str,TS ts) 4568a381b04SJed Brown { 4578a381b04SJed Brown TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 4588a381b04SJed Brown PetscErrorCode ierr; 4598a381b04SJed Brown 4608a381b04SJed Brown PetscFunctionBegin; 4618a381b04SJed Brown /* ark->Ydot has already been computed in SNESTSFormFunction_ARKIMEX (SNES guarantees this) */ 4628a381b04SJed Brown ierr = TSComputeIJacobian(ts,ark->stage_time,X,ark->Ydot,ark->shift,A,B,str,PETSC_TRUE);CHKERRQ(ierr); 4638a381b04SJed Brown PetscFunctionReturn(0); 4648a381b04SJed Brown } 4658a381b04SJed Brown 4668a381b04SJed Brown #undef __FUNCT__ 4678a381b04SJed Brown #define __FUNCT__ "TSSetUp_ARKIMEX" 4688a381b04SJed Brown static PetscErrorCode TSSetUp_ARKIMEX(TS ts) 4698a381b04SJed Brown { 4708a381b04SJed Brown TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 4718a381b04SJed Brown ARKTableau tab = ark->tableau; 4728a381b04SJed Brown PetscInt s = tab->s; 4738a381b04SJed Brown PetscErrorCode ierr; 4748a381b04SJed Brown 4758a381b04SJed Brown PetscFunctionBegin; 4768a381b04SJed Brown if (!ark->tableau) { 477e24355feSJed Brown ierr = TSARKIMEXSetType(ts,TSARKIMEXDefault);CHKERRQ(ierr); 4788a381b04SJed Brown } 4798a381b04SJed Brown ierr = VecDuplicateVecs(ts->vec_sol,s,&ark->Y);CHKERRQ(ierr); 4808a381b04SJed Brown ierr = VecDuplicateVecs(ts->vec_sol,s,&ark->YdotI);CHKERRQ(ierr); 4818a381b04SJed Brown ierr = VecDuplicateVecs(ts->vec_sol,s,&ark->YdotRHS);CHKERRQ(ierr); 4828a381b04SJed Brown ierr = VecDuplicate(ts->vec_sol,&ark->Ydot);CHKERRQ(ierr); 4838a381b04SJed Brown ierr = VecDuplicate(ts->vec_sol,&ark->Work);CHKERRQ(ierr); 4848a381b04SJed Brown ierr = VecDuplicate(ts->vec_sol,&ark->Z);CHKERRQ(ierr); 4858a381b04SJed Brown ierr = PetscMalloc(s*sizeof(ark->work[0]),&ark->work);CHKERRQ(ierr); 4868a381b04SJed Brown PetscFunctionReturn(0); 4878a381b04SJed Brown } 4888a381b04SJed Brown /*------------------------------------------------------------*/ 4898a381b04SJed Brown 4908a381b04SJed Brown #undef __FUNCT__ 4918a381b04SJed Brown #define __FUNCT__ "TSSetFromOptions_ARKIMEX" 4928a381b04SJed Brown static PetscErrorCode TSSetFromOptions_ARKIMEX(TS ts) 4938a381b04SJed Brown { 494*4cc180ffSJed Brown TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 4958a381b04SJed Brown PetscErrorCode ierr; 4968a381b04SJed Brown char arktype[256]; 4978a381b04SJed Brown 4988a381b04SJed Brown PetscFunctionBegin; 4998a381b04SJed Brown ierr = PetscOptionsHead("ARKIMEX ODE solver options");CHKERRQ(ierr); 5008a381b04SJed Brown { 5018a381b04SJed Brown ARKTableauLink link; 5028a381b04SJed Brown PetscInt count,choice; 5038a381b04SJed Brown PetscBool flg; 5048a381b04SJed Brown const char **namelist; 5058a381b04SJed Brown ierr = PetscStrncpy(arktype,TSARKIMEXDefault,sizeof arktype);CHKERRQ(ierr); 5068a381b04SJed Brown for (link=ARKTableauList,count=0; link; link=link->next,count++) ; 5078a381b04SJed Brown ierr = PetscMalloc(count*sizeof(char*),&namelist);CHKERRQ(ierr); 5088a381b04SJed Brown for (link=ARKTableauList,count=0; link; link=link->next,count++) namelist[count] = link->tab.name; 5098a381b04SJed Brown ierr = PetscOptionsEList("-ts_arkimex_type","Family of ARK IMEX method","TSARKIMEXSetType",(const char*const*)namelist,count,arktype,&choice,&flg);CHKERRQ(ierr); 5108a381b04SJed Brown ierr = TSARKIMEXSetType(ts,flg ? namelist[choice] : arktype);CHKERRQ(ierr); 5118a381b04SJed Brown ierr = PetscFree(namelist);CHKERRQ(ierr); 512*4cc180ffSJed Brown flg = (PetscBool)!ark->imex; 513*4cc180ffSJed Brown ierr = PetscOptionsBool("-ts_arkimex_fully_implicit","Solve the problem fully implicitly","TSARKIMEXSetFullyImplicit",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 514*4cc180ffSJed Brown ark->imex = (PetscBool)!flg; 5158a381b04SJed Brown } 5168a381b04SJed Brown ierr = PetscOptionsTail();CHKERRQ(ierr); 5178a381b04SJed Brown PetscFunctionReturn(0); 5188a381b04SJed Brown } 5198a381b04SJed Brown 5208a381b04SJed Brown #undef __FUNCT__ 5218a381b04SJed Brown #define __FUNCT__ "PetscFormatRealArray" 5228a381b04SJed Brown static PetscErrorCode PetscFormatRealArray(char buf[],size_t len,const char *fmt,PetscInt n,const PetscReal x[]) 5238a381b04SJed Brown { 5248a381b04SJed Brown int i,left,count; 5258a381b04SJed Brown char *p; 5268a381b04SJed Brown 5278a381b04SJed Brown PetscFunctionBegin; 5288a381b04SJed Brown for (i=0,p=buf,left=(int)len; i<n; i++) { 5298a381b04SJed Brown count = snprintf(p,left,fmt,x[i]); 5308a381b04SJed Brown if (count < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"snprintf()"); 5318a381b04SJed Brown if (count >= left) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Insufficient space in buffer"); 5328a381b04SJed Brown left -= count; 5338a381b04SJed Brown p += count; 5348a381b04SJed Brown *p++ = ' '; 5358a381b04SJed Brown } 5368a381b04SJed Brown p[i ? 0 : -1] = 0; 5378a381b04SJed Brown PetscFunctionReturn(0); 5388a381b04SJed Brown } 5398a381b04SJed Brown 5408a381b04SJed Brown #undef __FUNCT__ 5418a381b04SJed Brown #define __FUNCT__ "TSView_ARKIMEX" 5428a381b04SJed Brown static PetscErrorCode TSView_ARKIMEX(TS ts,PetscViewer viewer) 5438a381b04SJed Brown { 5448a381b04SJed Brown TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 5458a381b04SJed Brown ARKTableau tab = ark->tableau; 5468a381b04SJed Brown PetscBool iascii; 5478a381b04SJed Brown PetscErrorCode ierr; 5488a381b04SJed Brown 5498a381b04SJed Brown PetscFunctionBegin; 5508a381b04SJed Brown ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 5518a381b04SJed Brown if (iascii) { 5528a381b04SJed Brown const TSARKIMEXType arktype; 5538a381b04SJed Brown char buf[512]; 5548a381b04SJed Brown ierr = TSARKIMEXGetType(ts,&arktype);CHKERRQ(ierr); 5558a381b04SJed Brown ierr = PetscViewerASCIIPrintf(viewer," ARK IMEX %s\n",arktype);CHKERRQ(ierr); 5568a381b04SJed Brown ierr = PetscFormatRealArray(buf,sizeof buf,"% 8.6f",tab->s,tab->ct);CHKERRQ(ierr); 55731f6fcc0SJed Brown ierr = PetscViewerASCIIPrintf(viewer," Stiff abscissa ct = %s\n",buf);CHKERRQ(ierr); 55831f6fcc0SJed Brown ierr = PetscFormatRealArray(buf,sizeof buf,"% 8.6f",tab->s,tab->c);CHKERRQ(ierr); 55931f6fcc0SJed Brown ierr = PetscViewerASCIIPrintf(viewer," Nonstiff abscissa c = %s\n",buf);CHKERRQ(ierr); 5608a381b04SJed Brown } 5618a381b04SJed Brown PetscFunctionReturn(0); 5628a381b04SJed Brown } 5638a381b04SJed Brown 5648a381b04SJed Brown #undef __FUNCT__ 5658a381b04SJed Brown #define __FUNCT__ "TSARKIMEXSetType" 5668a381b04SJed Brown /*@C 5678a381b04SJed Brown TSARKIMEXSetType - Set the type of ARK IMEX scheme 5688a381b04SJed Brown 5698a381b04SJed Brown Logically collective 5708a381b04SJed Brown 5718a381b04SJed Brown Input Parameter: 5728a381b04SJed Brown + ts - timestepping context 5738a381b04SJed Brown - arktype - type of ARK-IMEX scheme 5748a381b04SJed Brown 5758a381b04SJed Brown Level: intermediate 5768a381b04SJed Brown 5778a381b04SJed Brown .seealso: TSARKIMEXGetType() 5788a381b04SJed Brown @*/ 5798a381b04SJed Brown PetscErrorCode TSARKIMEXSetType(TS ts,const TSARKIMEXType arktype) 5808a381b04SJed Brown { 5818a381b04SJed Brown PetscErrorCode ierr; 5828a381b04SJed Brown 5838a381b04SJed Brown PetscFunctionBegin; 5848a381b04SJed Brown PetscValidHeaderSpecific(ts,TS_CLASSID,1); 5858a381b04SJed Brown ierr = PetscTryMethod(ts,"TSARKIMEXSetType_C",(TS,const TSARKIMEXType),(ts,arktype));CHKERRQ(ierr); 5868a381b04SJed Brown PetscFunctionReturn(0); 5878a381b04SJed Brown } 5888a381b04SJed Brown 5898a381b04SJed Brown #undef __FUNCT__ 5908a381b04SJed Brown #define __FUNCT__ "TSARKIMEXGetType" 5918a381b04SJed Brown /*@C 5928a381b04SJed Brown TSARKIMEXGetType - Get the type of ARK IMEX scheme 5938a381b04SJed Brown 5948a381b04SJed Brown Logically collective 5958a381b04SJed Brown 5968a381b04SJed Brown Input Parameter: 5978a381b04SJed Brown . ts - timestepping context 5988a381b04SJed Brown 5998a381b04SJed Brown Output Parameter: 6008a381b04SJed Brown . arktype - type of ARK-IMEX scheme 6018a381b04SJed Brown 6028a381b04SJed Brown Level: intermediate 6038a381b04SJed Brown 6048a381b04SJed Brown .seealso: TSARKIMEXGetType() 6058a381b04SJed Brown @*/ 6068a381b04SJed Brown PetscErrorCode TSARKIMEXGetType(TS ts,const TSARKIMEXType *arktype) 6078a381b04SJed Brown { 6088a381b04SJed Brown PetscErrorCode ierr; 6098a381b04SJed Brown 6108a381b04SJed Brown PetscFunctionBegin; 6118a381b04SJed Brown PetscValidHeaderSpecific(ts,TS_CLASSID,1); 6128a381b04SJed Brown ierr = PetscUseMethod(ts,"TSARKIMEXGetType_C",(TS,const TSARKIMEXType*),(ts,arktype));CHKERRQ(ierr); 6138a381b04SJed Brown PetscFunctionReturn(0); 6148a381b04SJed Brown } 6158a381b04SJed Brown 616*4cc180ffSJed Brown #undef __FUNCT__ 617*4cc180ffSJed Brown #define __FUNCT__ "TSARKIMEXSetFullyImplicit" 618*4cc180ffSJed Brown /*@C 619*4cc180ffSJed Brown TSARKIMEXSetFullyImplicit - Solve both parts of the equation implicitly 620*4cc180ffSJed Brown 621*4cc180ffSJed Brown Logically collective 622*4cc180ffSJed Brown 623*4cc180ffSJed Brown Input Parameter: 624*4cc180ffSJed Brown + ts - timestepping context 625*4cc180ffSJed Brown - flg - PETSC_TRUE for fully implicit 626*4cc180ffSJed Brown 627*4cc180ffSJed Brown Level: intermediate 628*4cc180ffSJed Brown 629*4cc180ffSJed Brown .seealso: TSARKIMEXGetType() 630*4cc180ffSJed Brown @*/ 631*4cc180ffSJed Brown PetscErrorCode TSARKIMEXSetFullyImplicit(TS ts,PetscBool flg) 632*4cc180ffSJed Brown { 633*4cc180ffSJed Brown PetscErrorCode ierr; 634*4cc180ffSJed Brown 635*4cc180ffSJed Brown PetscFunctionBegin; 636*4cc180ffSJed Brown PetscValidHeaderSpecific(ts,TS_CLASSID,1); 637*4cc180ffSJed Brown ierr = PetscTryMethod(ts,"TSARKIMEXSetFullyImplicit_C",(TS,PetscBool),(ts,flg));CHKERRQ(ierr); 638*4cc180ffSJed Brown PetscFunctionReturn(0); 639*4cc180ffSJed Brown } 640*4cc180ffSJed Brown 6418a381b04SJed Brown EXTERN_C_BEGIN 6428a381b04SJed Brown #undef __FUNCT__ 6438a381b04SJed Brown #define __FUNCT__ "TSARKIMEXGetType_ARKIMEX" 6448a381b04SJed Brown PetscErrorCode TSARKIMEXGetType_ARKIMEX(TS ts,const TSARKIMEXType *arktype) 6458a381b04SJed Brown { 6468a381b04SJed Brown TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 6478a381b04SJed Brown PetscErrorCode ierr; 6488a381b04SJed Brown 6498a381b04SJed Brown PetscFunctionBegin; 6508a381b04SJed Brown if (!ark->tableau) {ierr = TSARKIMEXSetType(ts,TSARKIMEXDefault);CHKERRQ(ierr);} 6518a381b04SJed Brown *arktype = ark->tableau->name; 6528a381b04SJed Brown PetscFunctionReturn(0); 6538a381b04SJed Brown } 6548a381b04SJed Brown #undef __FUNCT__ 6558a381b04SJed Brown #define __FUNCT__ "TSARKIMEXSetType_ARKIMEX" 6568a381b04SJed Brown PetscErrorCode TSARKIMEXSetType_ARKIMEX(TS ts,const TSARKIMEXType arktype) 6578a381b04SJed Brown { 6588a381b04SJed Brown TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 6598a381b04SJed Brown PetscErrorCode ierr; 6608a381b04SJed Brown PetscBool match; 6618a381b04SJed Brown ARKTableauLink link; 6628a381b04SJed Brown 6638a381b04SJed Brown PetscFunctionBegin; 6648a381b04SJed Brown if (ark->tableau) { 6658a381b04SJed Brown ierr = PetscStrcmp(ark->tableau->name,arktype,&match);CHKERRQ(ierr); 6668a381b04SJed Brown if (match) PetscFunctionReturn(0); 6678a381b04SJed Brown } 6688a381b04SJed Brown for (link = ARKTableauList; link; link=link->next) { 6698a381b04SJed Brown ierr = PetscStrcmp(link->tab.name,arktype,&match);CHKERRQ(ierr); 6708a381b04SJed Brown if (match) { 6718a381b04SJed Brown ierr = TSReset_ARKIMEX(ts);CHKERRQ(ierr); 6728a381b04SJed Brown ark->tableau = &link->tab; 6738a381b04SJed Brown PetscFunctionReturn(0); 6748a381b04SJed Brown } 6758a381b04SJed Brown } 6768a381b04SJed Brown SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_ARG_UNKNOWN_TYPE,"Could not find '%s'",arktype); 6778a381b04SJed Brown PetscFunctionReturn(0); 6788a381b04SJed Brown } 679*4cc180ffSJed Brown #undef __FUNCT__ 680*4cc180ffSJed Brown #define __FUNCT__ "TSARKIMEXSetFullyImplicit_ARKIMEX" 681*4cc180ffSJed Brown PetscErrorCode TSARKIMEXSetFullyImplicit_ARKIMEX(TS ts,PetscBool flg) 682*4cc180ffSJed Brown { 683*4cc180ffSJed Brown TS_ARKIMEX *ark = (TS_ARKIMEX*)ts->data; 684*4cc180ffSJed Brown 685*4cc180ffSJed Brown PetscFunctionBegin; 686*4cc180ffSJed Brown ark->imex = (PetscBool)!flg; 687*4cc180ffSJed Brown PetscFunctionReturn(0); 688*4cc180ffSJed Brown } 6898a381b04SJed Brown EXTERN_C_END 6908a381b04SJed Brown 6918a381b04SJed Brown /* ------------------------------------------------------------ */ 6928a381b04SJed Brown /*MC 6938a381b04SJed Brown TSARKIMEX - ODE solver using Additive Runge-Kutta IMEX schemes 6948a381b04SJed Brown 695fca742c7SJed Brown These methods are intended for problems with well-separated time scales, especially when a slow scale is strongly 696fca742c7SJed Brown nonlinear such that it is expensive to solve with a fully implicit method. The user should provide the stiff part 697fca742c7SJed Brown of the equation using TSSetIFunction() and the non-stiff part with TSSetRHSFunction(). 698fca742c7SJed Brown 699fca742c7SJed Brown Notes: 700fca742c7SJed Brown This method currently only works with ODE, for which the stiff part G(t,X,Xdot) has the form Xdot + Ghat(t,X). 701fca742c7SJed Brown 7028a381b04SJed Brown Level: beginner 7038a381b04SJed Brown 704fca742c7SJed Brown .seealso: TSCreate(), TS, TSSetType(), TSARKIMEXRegister() 7058a381b04SJed Brown 7068a381b04SJed Brown M*/ 7078a381b04SJed Brown EXTERN_C_BEGIN 7088a381b04SJed Brown #undef __FUNCT__ 7098a381b04SJed Brown #define __FUNCT__ "TSCreate_ARKIMEX" 7108a381b04SJed Brown PetscErrorCode TSCreate_ARKIMEX(TS ts) 7118a381b04SJed Brown { 7128a381b04SJed Brown TS_ARKIMEX *th; 7138a381b04SJed Brown PetscErrorCode ierr; 7148a381b04SJed Brown 7158a381b04SJed Brown PetscFunctionBegin; 7168a381b04SJed Brown #if !defined(PETSC_USE_DYNAMIC_LIBRARIES) 7178a381b04SJed Brown ierr = TSARKIMEXInitializePackage(PETSC_NULL);CHKERRQ(ierr); 7188a381b04SJed Brown #endif 7198a381b04SJed Brown 7208a381b04SJed Brown ts->ops->reset = TSReset_ARKIMEX; 7218a381b04SJed Brown ts->ops->destroy = TSDestroy_ARKIMEX; 7228a381b04SJed Brown ts->ops->view = TSView_ARKIMEX; 7238a381b04SJed Brown ts->ops->setup = TSSetUp_ARKIMEX; 7248a381b04SJed Brown ts->ops->step = TSStep_ARKIMEX; 725cd652676SJed Brown ts->ops->interpolate = TSInterpolate_ARKIMEX; 7268a381b04SJed Brown ts->ops->setfromoptions = TSSetFromOptions_ARKIMEX; 7278a381b04SJed Brown ts->ops->snesfunction = SNESTSFormFunction_ARKIMEX; 7288a381b04SJed Brown ts->ops->snesjacobian = SNESTSFormJacobian_ARKIMEX; 7298a381b04SJed Brown 7308a381b04SJed Brown ierr = PetscNewLog(ts,TS_ARKIMEX,&th);CHKERRQ(ierr); 7318a381b04SJed Brown ts->data = (void*)th; 732*4cc180ffSJed Brown th->imex = PETSC_TRUE; 7338a381b04SJed Brown 7348a381b04SJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSARKIMEXGetType_C","TSARKIMEXGetType_ARKIMEX",TSARKIMEXGetType_ARKIMEX);CHKERRQ(ierr); 7358a381b04SJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSARKIMEXSetType_C","TSARKIMEXSetType_ARKIMEX",TSARKIMEXSetType_ARKIMEX);CHKERRQ(ierr); 736*4cc180ffSJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSARKIMEXSetFullyImplicit_C","TSARKIMEXSetFullyImplicit_ARKIMEX",TSARKIMEXSetFullyImplicit_ARKIMEX);CHKERRQ(ierr); 7378a381b04SJed Brown PetscFunctionReturn(0); 7388a381b04SJed Brown } 7398a381b04SJed Brown EXTERN_C_END 740