1e27a552bSJed Brown /* 2e27a552bSJed Brown Code for timestepping with additive Runge-Kutta IMEX method 3e27a552bSJed Brown 4e27a552bSJed Brown Notes: 5e27a552bSJed Brown The general system is written as 6e27a552bSJed Brown 7e27a552bSJed Brown F(t,X,Xdot) = G(t,X) 8e27a552bSJed Brown 9e27a552bSJed Brown where F represents the stiff part of the physics and G represents the non-stiff part. 10e27a552bSJed Brown 11e27a552bSJed Brown */ 12e27a552bSJed Brown #include <private/tsimpl.h> /*I "petscts.h" I*/ 13e27a552bSJed Brown 14e27a552bSJed Brown static const TSRosWType TSRosWDefault = TSROSW2E; 15e27a552bSJed Brown static PetscBool TSRosWRegisterAllCalled; 16e27a552bSJed Brown static PetscBool TSRosWPackageInitialized; 17e27a552bSJed Brown 18e27a552bSJed Brown typedef struct _ARKTableau *ARKTableau; 19e27a552bSJed Brown struct _ARKTableau { 20e27a552bSJed Brown char *name; 21e27a552bSJed Brown PetscInt order; /* Classical approximation order of the method */ 22e27a552bSJed Brown PetscInt s; /* Number of stages */ 23e27a552bSJed Brown PetscInt pinterp; /* Interpolation order */ 24e27a552bSJed Brown PetscReal *At,*bt,*ct; /* Stiff tableau */ 25e27a552bSJed Brown PetscReal *A,*b,*c; /* Non-stiff tableau */ 26e27a552bSJed Brown PetscReal *binterpt,*binterp; /* Dense output formula */ 27e27a552bSJed Brown }; 28e27a552bSJed Brown typedef struct _ARKTableauLink *ARKTableauLink; 29e27a552bSJed Brown struct _ARKTableauLink { 30e27a552bSJed Brown struct _ARKTableau tab; 31e27a552bSJed Brown ARKTableauLink next; 32e27a552bSJed Brown }; 33e27a552bSJed Brown static ARKTableauLink ARKTableauList; 34e27a552bSJed Brown 35e27a552bSJed Brown typedef struct { 36e27a552bSJed Brown ARKTableau tableau; 37e27a552bSJed Brown Vec *Y; /* States computed during the step */ 38e27a552bSJed Brown Vec *YdotI; /* Time derivatives for the stiff part */ 39e27a552bSJed Brown Vec *YdotRHS; /* Function evaluations for the non-stiff part */ 40e27a552bSJed Brown Vec Ydot; /* Work vector holding Ydot during residual evaluation */ 41e27a552bSJed Brown Vec Work; /* Generic work vector */ 42e27a552bSJed Brown Vec Z; /* Ydot = shift(Y-Z) */ 43e27a552bSJed Brown PetscScalar *work; /* Scalar work */ 44e27a552bSJed Brown PetscReal shift; 45e27a552bSJed Brown PetscReal stage_time; 46e27a552bSJed Brown PetscBool imex; 47e27a552bSJed Brown } TS_RosW; 48e27a552bSJed Brown 49e27a552bSJed Brown #undef __FUNCT__ 50e27a552bSJed Brown #define __FUNCT__ "TSRosWRegisterAll" 51e27a552bSJed Brown /*@C 52e27a552bSJed Brown TSRosWRegisterAll - Registers all of the additive Runge-Kutta implicit-explicit methods in TSRosW 53e27a552bSJed Brown 54e27a552bSJed Brown Not Collective, but should be called by all processes which will need the schemes to be registered 55e27a552bSJed Brown 56e27a552bSJed Brown Level: advanced 57e27a552bSJed Brown 58e27a552bSJed Brown .keywords: TS, TSRosW, register, all 59e27a552bSJed Brown 60e27a552bSJed Brown .seealso: TSRosWRegisterDestroy() 61e27a552bSJed Brown @*/ 62e27a552bSJed Brown PetscErrorCode TSRosWRegisterAll(void) 63e27a552bSJed Brown { 64e27a552bSJed Brown PetscErrorCode ierr; 65e27a552bSJed Brown 66e27a552bSJed Brown PetscFunctionBegin; 67e27a552bSJed Brown if (TSRosWRegisterAllCalled) PetscFunctionReturn(0); 68e27a552bSJed Brown TSRosWRegisterAllCalled = PETSC_TRUE; 69e27a552bSJed Brown 70e27a552bSJed Brown { 71e27a552bSJed Brown const PetscReal 72e27a552bSJed Brown A[3][3] = {{0,0,0}, 73e27a552bSJed Brown {0.41421356237309504880,0,0}, 74e27a552bSJed Brown {0.75,0.25,0}}, 75e27a552bSJed Brown At[3][3] = {{0,0,0}, 76e27a552bSJed Brown {0.12132034355964257320,0.29289321881345247560,0}, 77e27a552bSJed Brown {0.20710678118654752440,0.50000000000000000000,0.29289321881345247560}}, 78e27a552bSJed Brown binterpt[3][2] = {{1,-0.5},{0,0},{0,0.5}}; 79e27a552bSJed Brown ierr = TSRosWRegister(TSROSW2D,2,3,&At[0][0],PETSC_NULL,PETSC_NULL,&A[0][0],PETSC_NULL,PETSC_NULL,2,binterpt[0],PETSC_NULL);CHKERRQ(ierr); 80e27a552bSJed Brown } 81e27a552bSJed Brown { /* Optimal for linear implicit part */ 82e27a552bSJed Brown const PetscReal s2 = PetscSqrtReal((PetscReal)2.0), 83e27a552bSJed Brown A[3][3] = {{0,0,0}, 84e27a552bSJed Brown {2-s2,0,0}, 85e27a552bSJed Brown {(3-2*s2)/6,(3+2*s2)/6,0}}, 86e27a552bSJed Brown At[3][3] = {{0,0,0}, 87e27a552bSJed Brown {1-1/s2,1-1/s2,0}, 88e27a552bSJed Brown {1/(2*s2),1/(2*s2),1-1/s2}}, 89e27a552bSJed Brown binterpt[3][2] = {{1,-0.5},{0,0},{0,0.5}}; 90e27a552bSJed Brown ierr = TSRosWRegister(TSROSW2E,2,3,&At[0][0],PETSC_NULL,PETSC_NULL,&A[0][0],PETSC_NULL,PETSC_NULL,2,binterpt[0],PETSC_NULL);CHKERRQ(ierr); 91e27a552bSJed Brown } 92e27a552bSJed Brown { 93e27a552bSJed Brown const PetscReal 94e27a552bSJed Brown A[4][4] = {{0,0,0,0}, 95e27a552bSJed Brown {1767732205903./2027836641118.,0,0,0}, 96e27a552bSJed Brown {5535828885825./10492691773637.,788022342437./10882634858940.,0,0}, 97e27a552bSJed Brown {6485989280629./16251701735622.,-4246266847089./9704473918619.,10755448449292./10357097424841.,0}}, 98e27a552bSJed Brown At[4][4] = {{0,0,0,0}, 99e27a552bSJed Brown {1767732205903./4055673282236.,1767732205903./4055673282236.,0,0}, 100e27a552bSJed Brown {2746238789719./10658868560708.,-640167445237./6845629431997.,1767732205903./4055673282236.,0}, 101e27a552bSJed Brown {1471266399579./7840856788654.,-4482444167858./7529755066697.,11266239266428./11593286722821.,1767732205903./4055673282236.}}, 102e27a552bSJed Brown binterpt[4][2] = {{4655552711362./22874653954995., -215264564351./13552729205753.}, 103e27a552bSJed Brown {-18682724506714./9892148508045.,17870216137069./13817060693119.}, 104e27a552bSJed Brown {34259539580243./13192909600954.,-28141676662227./17317692491321.}, 105e27a552bSJed Brown {584795268549./6622622206610., 2508943948391./7218656332882.}}; 106e27a552bSJed Brown ierr = TSRosWRegister(TSROSW3,3,4,&At[0][0],PETSC_NULL,PETSC_NULL,&A[0][0],PETSC_NULL,PETSC_NULL,2,binterpt[0],PETSC_NULL);CHKERRQ(ierr); 107e27a552bSJed Brown } 108e27a552bSJed Brown { 109e27a552bSJed Brown const PetscReal 110e27a552bSJed Brown A[6][6] = {{0,0,0,0,0,0}, 111e27a552bSJed Brown {1./2,0,0,0,0,0}, 112e27a552bSJed Brown {13861./62500.,6889./62500.,0,0,0,0}, 113e27a552bSJed Brown {-116923316275./2393684061468.,-2731218467317./15368042101831.,9408046702089./11113171139209.,0,0,0}, 114e27a552bSJed Brown {-451086348788./2902428689909.,-2682348792572./7519795681897.,12662868775082./11960479115383.,3355817975965./11060851509271.,0,0}, 115e27a552bSJed Brown {647845179188./3216320057751.,73281519250./8382639484533.,552539513391./3454668386233.,3354512671639./8306763924573.,4040./17871.,0}}, 116e27a552bSJed Brown At[6][6] = {{0,0,0,0,0,0}, 117e27a552bSJed Brown {1./4,1./4,0,0,0,0}, 118e27a552bSJed Brown {8611./62500.,-1743./31250.,1./4,0,0,0}, 119e27a552bSJed Brown {5012029./34652500.,-654441./2922500.,174375./388108.,1./4,0,0}, 120e27a552bSJed Brown {15267082809./155376265600.,-71443401./120774400.,730878875./902184768.,2285395./8070912.,1./4,0}, 121e27a552bSJed Brown {82889./524892.,0,15625./83664.,69875./102672.,-2260./8211,1./4}}, 122e27a552bSJed Brown binterpt[6][3] = {{6943876665148./7220017795957.,-54480133./30881146.,6818779379841./7100303317025.}, 123e27a552bSJed Brown {0,0,0}, 124e27a552bSJed Brown {7640104374378./9702883013639.,-11436875./14766696.,2173542590792./12501825683035.}, 125e27a552bSJed Brown {-20649996744609./7521556579894.,174696575./18121608.,-31592104683404./5083833661969.}, 126e27a552bSJed Brown {8854892464581./2390941311638.,-12120380./966161.,61146701046299./7138195549469.}, 127e27a552bSJed Brown {-11397109935349./6675773540249.,3843./706.,-17219254887155./4939391667607.}}; 128e27a552bSJed Brown ierr = TSRosWRegister(TSROSW4,4,6,&At[0][0],PETSC_NULL,PETSC_NULL,&A[0][0],PETSC_NULL,PETSC_NULL,3,binterpt[0],PETSC_NULL);CHKERRQ(ierr); 129e27a552bSJed Brown } 130e27a552bSJed Brown { 131e27a552bSJed Brown const PetscReal 132e27a552bSJed Brown A[8][8] = {{0,0,0,0,0,0,0,0}, 133e27a552bSJed Brown {41./100,0,0,0,0,0,0,0}, 134e27a552bSJed Brown {367902744464./2072280473677.,677623207551./8224143866563.,0,0,0,0,0,0}, 135e27a552bSJed Brown {1268023523408./10340822734521.,0,1029933939417./13636558850479.,0,0,0,0,0}, 136e27a552bSJed Brown {14463281900351./6315353703477.,0,66114435211212./5879490589093.,-54053170152839./4284798021562.,0,0,0,0}, 137e27a552bSJed Brown {14090043504691./34967701212078.,0,15191511035443./11219624916014.,-18461159152457./12425892160975.,-281667163811./9011619295870.,0,0,0}, 138e27a552bSJed Brown {19230459214898./13134317526959.,0,21275331358303./2942455364971.,-38145345988419./4862620318723.,-1./8,-1./8,0,0}, 139e27a552bSJed Brown {-19977161125411./11928030595625.,0,-40795976796054./6384907823539.,177454434618887./12078138498510.,782672205425./8267701900261.,-69563011059811./9646580694205.,7356628210526./4942186776405.,0}}, 140e27a552bSJed Brown At[8][8] = {{0,0,0,0,0,0,0,0}, 141e27a552bSJed Brown {41./200.,41./200.,0,0,0,0,0,0}, 142e27a552bSJed Brown {41./400.,-567603406766./11931857230679.,41./200.,0,0,0,0,0}, 143e27a552bSJed Brown {683785636431./9252920307686.,0,-110385047103./1367015193373.,41./200.,0,0,0,0}, 144e27a552bSJed Brown {3016520224154./10081342136671.,0,30586259806659./12414158314087.,-22760509404356./11113319521817.,41./200.,0,0,0}, 145e27a552bSJed Brown {218866479029./1489978393911.,0,638256894668./5436446318841.,-1179710474555./5321154724896.,-60928119172./8023461067671.,41./200.,0,0}, 146e27a552bSJed Brown {1020004230633./5715676835656.,0,25762820946817./25263940353407.,-2161375909145./9755907335909.,-211217309593./5846859502534.,-4269925059573./7827059040749.,41./200,0}, 147e27a552bSJed Brown {-872700587467./9133579230613.,0,0,22348218063261./9555858737531.,-1143369518992./8141816002931.,-39379526789629./19018526304540.,32727382324388./42900044865799.,41./200.}}, 148e27a552bSJed Brown binterpt[8][3] = {{-17674230611817./10670229744614. , 43486358583215./12773830924787. , -9257016797708./5021505065439.}, 149e27a552bSJed Brown {0 , 0 , 0 }, 150e27a552bSJed Brown {0 , 0 , 0 }, 151e27a552bSJed Brown {65168852399939./7868540260826. , -91478233927265./11067650958493., 26096422576131./11239449250142.}, 152e27a552bSJed Brown {15494834004392./5936557850923. , -79368583304911./10890268929626., 92396832856987./20362823103730.}, 153e27a552bSJed Brown {-99329723586156./26959484932159., -12239297817655./9152339842473. , 30029262896817./10175596800299.}, 154e27a552bSJed Brown {-19024464361622./5461577185407. , 115839755401235./10719374521269., -26136350496073./3983972220547.}, 155e27a552bSJed Brown {-6511271360970./6095937251113. , 5843115559534./2180450260947. , -5289405421727./3760307252460. }}; 156e27a552bSJed Brown ierr = TSRosWRegister(TSROSW5,5,8,&At[0][0],PETSC_NULL,PETSC_NULL,&A[0][0],PETSC_NULL,PETSC_NULL,3,binterpt[0],PETSC_NULL);CHKERRQ(ierr); 157e27a552bSJed Brown } 158e27a552bSJed Brown 159e27a552bSJed Brown PetscFunctionReturn(0); 160e27a552bSJed Brown } 161e27a552bSJed Brown 162e27a552bSJed Brown #undef __FUNCT__ 163e27a552bSJed Brown #define __FUNCT__ "TSRosWRegisterDestroy" 164e27a552bSJed Brown /*@C 165e27a552bSJed Brown TSRosWRegisterDestroy - Frees the list of schemes that were registered by TSRosWRegister(). 166e27a552bSJed Brown 167e27a552bSJed Brown Not Collective 168e27a552bSJed Brown 169e27a552bSJed Brown Level: advanced 170e27a552bSJed Brown 171e27a552bSJed Brown .keywords: TSRosW, register, destroy 172e27a552bSJed Brown .seealso: TSRosWRegister(), TSRosWRegisterAll(), TSRosWRegisterDynamic() 173e27a552bSJed Brown @*/ 174e27a552bSJed Brown PetscErrorCode TSRosWRegisterDestroy(void) 175e27a552bSJed Brown { 176e27a552bSJed Brown PetscErrorCode ierr; 177e27a552bSJed Brown ARKTableauLink link; 178e27a552bSJed Brown 179e27a552bSJed Brown PetscFunctionBegin; 180e27a552bSJed Brown while ((link = ARKTableauList)) { 181e27a552bSJed Brown ARKTableau t = &link->tab; 182e27a552bSJed Brown ARKTableauList = link->next; 183e27a552bSJed Brown ierr = PetscFree6(t->At,t->bt,t->ct,t->A,t->b,t->c);CHKERRQ(ierr); 184e27a552bSJed Brown ierr = PetscFree2(t->binterpt,t->binterp);CHKERRQ(ierr); 185e27a552bSJed Brown ierr = PetscFree(t->name);CHKERRQ(ierr); 186e27a552bSJed Brown ierr = PetscFree(link);CHKERRQ(ierr); 187e27a552bSJed Brown } 188e27a552bSJed Brown TSRosWRegisterAllCalled = PETSC_FALSE; 189e27a552bSJed Brown PetscFunctionReturn(0); 190e27a552bSJed Brown } 191e27a552bSJed Brown 192e27a552bSJed Brown #undef __FUNCT__ 193e27a552bSJed Brown #define __FUNCT__ "TSRosWInitializePackage" 194e27a552bSJed Brown /*@C 195e27a552bSJed Brown TSRosWInitializePackage - This function initializes everything in the TSRosW package. It is called 196e27a552bSJed Brown from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to TSCreate_RosW() 197e27a552bSJed Brown when using static libraries. 198e27a552bSJed Brown 199e27a552bSJed Brown Input Parameter: 200e27a552bSJed Brown path - The dynamic library path, or PETSC_NULL 201e27a552bSJed Brown 202e27a552bSJed Brown Level: developer 203e27a552bSJed Brown 204e27a552bSJed Brown .keywords: TS, TSRosW, initialize, package 205e27a552bSJed Brown .seealso: PetscInitialize() 206e27a552bSJed Brown @*/ 207e27a552bSJed Brown PetscErrorCode TSRosWInitializePackage(const char path[]) 208e27a552bSJed Brown { 209e27a552bSJed Brown PetscErrorCode ierr; 210e27a552bSJed Brown 211e27a552bSJed Brown PetscFunctionBegin; 212e27a552bSJed Brown if (TSRosWPackageInitialized) PetscFunctionReturn(0); 213e27a552bSJed Brown TSRosWPackageInitialized = PETSC_TRUE; 214e27a552bSJed Brown ierr = TSRosWRegisterAll();CHKERRQ(ierr); 215e27a552bSJed Brown ierr = PetscRegisterFinalize(TSRosWFinalizePackage);CHKERRQ(ierr); 216e27a552bSJed Brown PetscFunctionReturn(0); 217e27a552bSJed Brown } 218e27a552bSJed Brown 219e27a552bSJed Brown #undef __FUNCT__ 220e27a552bSJed Brown #define __FUNCT__ "TSRosWFinalizePackage" 221e27a552bSJed Brown /*@C 222e27a552bSJed Brown TSRosWFinalizePackage - This function destroys everything in the TSRosW package. It is 223e27a552bSJed Brown called from PetscFinalize(). 224e27a552bSJed Brown 225e27a552bSJed Brown Level: developer 226e27a552bSJed Brown 227e27a552bSJed Brown .keywords: Petsc, destroy, package 228e27a552bSJed Brown .seealso: PetscFinalize() 229e27a552bSJed Brown @*/ 230e27a552bSJed Brown PetscErrorCode TSRosWFinalizePackage(void) 231e27a552bSJed Brown { 232e27a552bSJed Brown PetscErrorCode ierr; 233e27a552bSJed Brown 234e27a552bSJed Brown PetscFunctionBegin; 235e27a552bSJed Brown TSRosWPackageInitialized = PETSC_FALSE; 236e27a552bSJed Brown ierr = TSRosWRegisterDestroy();CHKERRQ(ierr); 237e27a552bSJed Brown PetscFunctionReturn(0); 238e27a552bSJed Brown } 239e27a552bSJed Brown 240e27a552bSJed Brown #undef __FUNCT__ 241e27a552bSJed Brown #define __FUNCT__ "TSRosWRegister" 242e27a552bSJed Brown /*@C 243e27a552bSJed Brown TSRosWRegister - register an ARK IMEX scheme by providing the entries in the Butcher tableau and optionally embedded approximations and interpolation 244e27a552bSJed Brown 245e27a552bSJed Brown Not Collective, but the same schemes should be registered on all processes on which they will be used 246e27a552bSJed Brown 247e27a552bSJed Brown Input Parameters: 248e27a552bSJed Brown + name - identifier for method 249e27a552bSJed Brown . order - approximation order of method 250e27a552bSJed Brown . s - number of stages, this is the dimension of the matrices below 251e27a552bSJed Brown . At - Butcher table of stage coefficients for stiff part (dimension s*s, row-major) 252e27a552bSJed Brown . bt - Butcher table for completing the stiff part of the step (dimension s; PETSC_NULL to use the last row of At) 253e27a552bSJed Brown . ct - Abscissa of each stiff stage (dimension s, PETSC_NULL to use row sums of At) 254e27a552bSJed Brown . A - Non-stiff stage coefficients (dimension s*s, row-major) 255e27a552bSJed Brown . b - Non-stiff step completion table (dimension s; PETSC_NULL to use last row of At) 256e27a552bSJed Brown . c - Non-stiff abscissa (dimension s; PETSC_NULL to use row sums of A) 257e27a552bSJed Brown . pinterp - Order of the interpolation scheme, equal to the number of columns of binterpt and binterp 258e27a552bSJed Brown . binterpt - Coefficients of the interpolation formula for the stiff part (dimension s*pinterp) 259e27a552bSJed Brown - binterp - Coefficients of the interpolation formula for the non-stiff part (dimension s*pinterp; PETSC_NULL to reuse binterpt) 260e27a552bSJed Brown 261e27a552bSJed Brown Notes: 262e27a552bSJed Brown Several ARK IMEX methods are provided, this function is only needed to create new methods. 263e27a552bSJed Brown 264e27a552bSJed Brown Level: advanced 265e27a552bSJed Brown 266e27a552bSJed Brown .keywords: TS, register 267e27a552bSJed Brown 268e27a552bSJed Brown .seealso: TSRosW 269e27a552bSJed Brown @*/ 270e27a552bSJed Brown PetscErrorCode TSRosWRegister(const TSRosWType name,PetscInt order,PetscInt s, 271e27a552bSJed Brown const PetscReal At[],const PetscReal bt[],const PetscReal ct[], 272e27a552bSJed Brown const PetscReal A[],const PetscReal b[],const PetscReal c[], 273e27a552bSJed Brown PetscInt pinterp,const PetscReal binterpt[],const PetscReal binterp[]) 274e27a552bSJed Brown { 275e27a552bSJed Brown PetscErrorCode ierr; 276e27a552bSJed Brown ARKTableauLink link; 277e27a552bSJed Brown ARKTableau t; 278e27a552bSJed Brown PetscInt i,j; 279e27a552bSJed Brown 280e27a552bSJed Brown PetscFunctionBegin; 281e27a552bSJed Brown ierr = PetscMalloc(sizeof(*link),&link);CHKERRQ(ierr); 282e27a552bSJed Brown ierr = PetscMemzero(link,sizeof(*link));CHKERRQ(ierr); 283e27a552bSJed Brown t = &link->tab; 284e27a552bSJed Brown ierr = PetscStrallocpy(name,&t->name);CHKERRQ(ierr); 285e27a552bSJed Brown t->order = order; 286e27a552bSJed Brown t->s = s; 287e27a552bSJed 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); 288e27a552bSJed Brown ierr = PetscMemcpy(t->At,At,s*s*sizeof(At[0]));CHKERRQ(ierr); 289e27a552bSJed Brown ierr = PetscMemcpy(t->A,A,s*s*sizeof(A[0]));CHKERRQ(ierr); 290e27a552bSJed Brown if (bt) {ierr = PetscMemcpy(t->bt,bt,s*sizeof(bt[0]));CHKERRQ(ierr);} 291e27a552bSJed Brown else for (i=0; i<s; i++) t->bt[i] = At[(s-1)*s+i]; 292e27a552bSJed Brown if (b) {ierr = PetscMemcpy(t->b,b,s*sizeof(b[0]));CHKERRQ(ierr);} 293e27a552bSJed Brown else for (i=0; i<s; i++) t->b[i] = At[(s-1)*s+i]; 294e27a552bSJed Brown if (ct) {ierr = PetscMemcpy(t->ct,ct,s*sizeof(ct[0]));CHKERRQ(ierr);} 295e27a552bSJed 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]; 296e27a552bSJed Brown if (c) {ierr = PetscMemcpy(t->c,c,s*sizeof(c[0]));CHKERRQ(ierr);} 297e27a552bSJed 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]; 298e27a552bSJed Brown t->pinterp = pinterp; 299e27a552bSJed Brown ierr = PetscMalloc2(s*pinterp,PetscReal,&t->binterpt,s*pinterp,PetscReal,&t->binterp);CHKERRQ(ierr); 300e27a552bSJed Brown ierr = PetscMemcpy(t->binterpt,binterpt,s*pinterp*sizeof(binterpt[0]));CHKERRQ(ierr); 301e27a552bSJed Brown ierr = PetscMemcpy(t->binterp,binterp?binterp:binterpt,s*pinterp*sizeof(binterpt[0]));CHKERRQ(ierr); 302e27a552bSJed Brown link->next = ARKTableauList; 303e27a552bSJed Brown ARKTableauList = link; 304e27a552bSJed Brown PetscFunctionReturn(0); 305e27a552bSJed Brown } 306e27a552bSJed Brown 307e27a552bSJed Brown #undef __FUNCT__ 308e27a552bSJed Brown #define __FUNCT__ "TSStep_RosW" 309e27a552bSJed Brown static PetscErrorCode TSStep_RosW(TS ts) 310e27a552bSJed Brown { 311e27a552bSJed Brown TS_RosW *ark = (TS_RosW*)ts->data; 312e27a552bSJed Brown ARKTableau tab = ark->tableau; 313e27a552bSJed Brown const PetscInt s = tab->s; 314e27a552bSJed Brown const PetscReal *At = tab->At,*A = tab->A,*bt = tab->bt,*b = tab->b,*ct = tab->ct,*c = tab->c; 315e27a552bSJed Brown PetscScalar *w = ark->work; 316e27a552bSJed Brown Vec *Y = ark->Y,*YdotI = ark->YdotI,*YdotRHS = ark->YdotRHS,Ydot = ark->Ydot,W = ark->Work,Z = ark->Z; 317e27a552bSJed Brown SNES snes; 318e27a552bSJed Brown PetscInt i,j,its,lits; 319*cdbf8f93SLisandro Dalcin PetscReal next_time_step; 320e27a552bSJed Brown PetscReal h,t; 321e27a552bSJed Brown PetscErrorCode ierr; 322e27a552bSJed Brown 323e27a552bSJed Brown PetscFunctionBegin; 324e27a552bSJed Brown ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); 325*cdbf8f93SLisandro Dalcin next_time_step = ts->time_step; 326*cdbf8f93SLisandro Dalcin h = ts->time_step; 327e27a552bSJed Brown t = ts->ptime; 328e27a552bSJed Brown 329e27a552bSJed Brown for (i=0; i<s; i++) { 330e27a552bSJed Brown if (At[i*s+i] == 0) { /* This stage is explicit */ 331e27a552bSJed Brown ierr = VecCopy(ts->vec_sol,Y[i]);CHKERRQ(ierr); 332e27a552bSJed Brown for (j=0; j<i; j++) w[j] = -h*At[i*s+j]; 333e27a552bSJed Brown ierr = VecMAXPY(Y[i],i,w,YdotI);CHKERRQ(ierr); 334e27a552bSJed Brown for (j=0; j<i; j++) w[j] = h*A[i*s+j]; 335e27a552bSJed Brown ierr = VecMAXPY(Y[i],i,w,YdotRHS);CHKERRQ(ierr); 336e27a552bSJed Brown } else { 337e27a552bSJed Brown ark->stage_time = t + h*ct[i]; 338e27a552bSJed Brown ark->shift = 1./(h*At[i*s+i]); 339e27a552bSJed Brown /* Affine part */ 340e27a552bSJed Brown ierr = VecZeroEntries(W);CHKERRQ(ierr); 341e27a552bSJed Brown for (j=0; j<i; j++) w[j] = h*A[i*s+j]; 342e27a552bSJed Brown ierr = VecMAXPY(W,i,w,YdotRHS);CHKERRQ(ierr); 343e27a552bSJed Brown /* Ydot = shift*(Y-Z) */ 344e27a552bSJed Brown ierr = VecCopy(ts->vec_sol,Z);CHKERRQ(ierr); 345e27a552bSJed Brown for (j=0; j<i; j++) w[j] = -h*At[i*s+j]; 346e27a552bSJed Brown ierr = VecMAXPY(Z,i,w,YdotI);CHKERRQ(ierr); 347e27a552bSJed Brown /* Initial guess taken from last stage */ 348e27a552bSJed Brown ierr = VecCopy(i>0?Y[i-1]:ts->vec_sol,Y[i]);CHKERRQ(ierr); 349e27a552bSJed Brown ierr = SNESSolve(snes,W,Y[i]);CHKERRQ(ierr); 350e27a552bSJed Brown ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); 351e27a552bSJed Brown ierr = SNESGetLinearSolveIterations(snes,&lits);CHKERRQ(ierr); 352e27a552bSJed Brown ts->nonlinear_its += its; ts->linear_its += lits; 353e27a552bSJed Brown } 354e27a552bSJed Brown ierr = VecZeroEntries(Ydot);CHKERRQ(ierr); 355e27a552bSJed Brown ierr = TSComputeIFunction(ts,t+h*ct[i],Y[i],Ydot,YdotI[i],ark->imex);CHKERRQ(ierr); 356e27a552bSJed Brown if (ark->imex) { 357e27a552bSJed Brown ierr = TSComputeRHSFunction(ts,t+h*c[i],Y[i],YdotRHS[i]);CHKERRQ(ierr); 358e27a552bSJed Brown } else { 359e27a552bSJed Brown ierr = VecZeroEntries(YdotRHS[i]);CHKERRQ(ierr); 360e27a552bSJed Brown } 361e27a552bSJed Brown } 362e27a552bSJed Brown for (j=0; j<s; j++) w[j] = -h*bt[j]; 363e27a552bSJed Brown ierr = VecMAXPY(ts->vec_sol,s,w,YdotI);CHKERRQ(ierr); 364e27a552bSJed Brown for (j=0; j<s; j++) w[j] = h*b[j]; 365e27a552bSJed Brown ierr = VecMAXPY(ts->vec_sol,s,w,YdotRHS);CHKERRQ(ierr); 366e27a552bSJed Brown 367e27a552bSJed Brown ts->ptime += ts->time_step; 368*cdbf8f93SLisandro Dalcin ts->time_step_prev = ts->time_step; 369*cdbf8f93SLisandro Dalcin ts->time_step = next_time_step; 370e27a552bSJed Brown ts->steps++; 371e27a552bSJed Brown PetscFunctionReturn(0); 372e27a552bSJed Brown } 373e27a552bSJed Brown 374e27a552bSJed Brown #undef __FUNCT__ 375e27a552bSJed Brown #define __FUNCT__ "TSInterpolate_RosW" 376e27a552bSJed Brown static PetscErrorCode TSInterpolate_RosW(TS ts,PetscReal itime,Vec X) 377e27a552bSJed Brown { 378e27a552bSJed Brown TS_RosW *ark = (TS_RosW*)ts->data; 379e27a552bSJed Brown PetscInt s = ark->tableau->s,pinterp = ark->tableau->pinterp,i,j; 380e27a552bSJed Brown PetscReal tt,t = (itime - ts->ptime)/ts->time_step + 1; /* In the interval [0,1] */ 381e27a552bSJed Brown PetscScalar *bt,*b; 382e27a552bSJed Brown const PetscReal *Bt = ark->tableau->binterpt,*B = ark->tableau->binterp; 383e27a552bSJed Brown PetscErrorCode ierr; 384e27a552bSJed Brown 385e27a552bSJed Brown PetscFunctionBegin; 386e27a552bSJed Brown if (!Bt || !B) SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_SUP,"TSRosW %s does not have an interpolation formula",ark->tableau->name); 387e27a552bSJed Brown ierr = PetscMalloc2(s,PetscScalar,&bt,s,PetscScalar,&b);CHKERRQ(ierr); 388e27a552bSJed Brown for (i=0; i<s; i++) bt[i] = b[i] = 0; 389e27a552bSJed Brown for (j=0,tt=t; j<pinterp; j++,tt*=t) { 390e27a552bSJed Brown for (i=0; i<s; i++) { 391e27a552bSJed Brown bt[i] += ts->time_step * Bt[i*pinterp+j] * tt * -1.0; 392e27a552bSJed Brown b[i] += ts->time_step * B[i*pinterp+j] * tt; 393e27a552bSJed Brown } 394e27a552bSJed Brown } 395e27a552bSJed 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"); 396e27a552bSJed Brown ierr = VecCopy(ark->Y[0],X);CHKERRQ(ierr); 397e27a552bSJed Brown ierr = VecMAXPY(X,s,bt,ark->YdotI);CHKERRQ(ierr); 398e27a552bSJed Brown ierr = VecMAXPY(X,s,b,ark->YdotRHS);CHKERRQ(ierr); 399e27a552bSJed Brown ierr = PetscFree2(bt,b);CHKERRQ(ierr); 400e27a552bSJed Brown PetscFunctionReturn(0); 401e27a552bSJed Brown } 402e27a552bSJed Brown 403e27a552bSJed Brown /*------------------------------------------------------------*/ 404e27a552bSJed Brown #undef __FUNCT__ 405e27a552bSJed Brown #define __FUNCT__ "TSReset_RosW" 406e27a552bSJed Brown static PetscErrorCode TSReset_RosW(TS ts) 407e27a552bSJed Brown { 408e27a552bSJed Brown TS_RosW *ark = (TS_RosW*)ts->data; 409e27a552bSJed Brown PetscInt s; 410e27a552bSJed Brown PetscErrorCode ierr; 411e27a552bSJed Brown 412e27a552bSJed Brown PetscFunctionBegin; 413e27a552bSJed Brown if (!ark->tableau) PetscFunctionReturn(0); 414e27a552bSJed Brown s = ark->tableau->s; 415e27a552bSJed Brown ierr = VecDestroyVecs(s,&ark->Y);CHKERRQ(ierr); 416e27a552bSJed Brown ierr = VecDestroyVecs(s,&ark->YdotI);CHKERRQ(ierr); 417e27a552bSJed Brown ierr = VecDestroyVecs(s,&ark->YdotRHS);CHKERRQ(ierr); 418e27a552bSJed Brown ierr = VecDestroy(&ark->Ydot);CHKERRQ(ierr); 419e27a552bSJed Brown ierr = VecDestroy(&ark->Work);CHKERRQ(ierr); 420e27a552bSJed Brown ierr = VecDestroy(&ark->Z);CHKERRQ(ierr); 421e27a552bSJed Brown ierr = PetscFree(ark->work);CHKERRQ(ierr); 422e27a552bSJed Brown PetscFunctionReturn(0); 423e27a552bSJed Brown } 424e27a552bSJed Brown 425e27a552bSJed Brown #undef __FUNCT__ 426e27a552bSJed Brown #define __FUNCT__ "TSDestroy_RosW" 427e27a552bSJed Brown static PetscErrorCode TSDestroy_RosW(TS ts) 428e27a552bSJed Brown { 429e27a552bSJed Brown PetscErrorCode ierr; 430e27a552bSJed Brown 431e27a552bSJed Brown PetscFunctionBegin; 432e27a552bSJed Brown ierr = TSReset_RosW(ts);CHKERRQ(ierr); 433e27a552bSJed Brown ierr = PetscFree(ts->data);CHKERRQ(ierr); 434e27a552bSJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWGetType_C","",PETSC_NULL);CHKERRQ(ierr); 435e27a552bSJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWSetType_C","",PETSC_NULL);CHKERRQ(ierr); 436e27a552bSJed Brown PetscFunctionReturn(0); 437e27a552bSJed Brown } 438e27a552bSJed Brown 439e27a552bSJed Brown /* 440e27a552bSJed Brown This defines the nonlinear equation that is to be solved with SNES 441e27a552bSJed Brown G(U) = F[t0+Theta*dt, U, (U-U0)*shift] = 0 442e27a552bSJed Brown */ 443e27a552bSJed Brown #undef __FUNCT__ 444e27a552bSJed Brown #define __FUNCT__ "SNESTSFormFunction_RosW" 445e27a552bSJed Brown static PetscErrorCode SNESTSFormFunction_RosW(SNES snes,Vec X,Vec F,TS ts) 446e27a552bSJed Brown { 447e27a552bSJed Brown TS_RosW *ark = (TS_RosW*)ts->data; 448e27a552bSJed Brown PetscErrorCode ierr; 449e27a552bSJed Brown 450e27a552bSJed Brown PetscFunctionBegin; 451e27a552bSJed Brown ierr = VecAXPBYPCZ(ark->Ydot,-ark->shift,ark->shift,0,ark->Z,X);CHKERRQ(ierr); /* Ydot = shift*(X-Z) */ 452e27a552bSJed Brown ierr = TSComputeIFunction(ts,ark->stage_time,X,ark->Ydot,F,ark->imex);CHKERRQ(ierr); 453e27a552bSJed Brown PetscFunctionReturn(0); 454e27a552bSJed Brown } 455e27a552bSJed Brown 456e27a552bSJed Brown #undef __FUNCT__ 457e27a552bSJed Brown #define __FUNCT__ "SNESTSFormJacobian_RosW" 458e27a552bSJed Brown static PetscErrorCode SNESTSFormJacobian_RosW(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *str,TS ts) 459e27a552bSJed Brown { 460e27a552bSJed Brown TS_RosW *ark = (TS_RosW*)ts->data; 461e27a552bSJed Brown PetscErrorCode ierr; 462e27a552bSJed Brown 463e27a552bSJed Brown PetscFunctionBegin; 464e27a552bSJed Brown /* ark->Ydot has already been computed in SNESTSFormFunction_RosW (SNES guarantees this) */ 465e27a552bSJed Brown ierr = TSComputeIJacobian(ts,ark->stage_time,X,ark->Ydot,ark->shift,A,B,str,PETSC_TRUE);CHKERRQ(ierr); 466e27a552bSJed Brown PetscFunctionReturn(0); 467e27a552bSJed Brown } 468e27a552bSJed Brown 469e27a552bSJed Brown #undef __FUNCT__ 470e27a552bSJed Brown #define __FUNCT__ "TSSetUp_RosW" 471e27a552bSJed Brown static PetscErrorCode TSSetUp_RosW(TS ts) 472e27a552bSJed Brown { 473e27a552bSJed Brown TS_RosW *ark = (TS_RosW*)ts->data; 474e27a552bSJed Brown ARKTableau tab = ark->tableau; 475e27a552bSJed Brown PetscInt s = tab->s; 476e27a552bSJed Brown PetscErrorCode ierr; 477e27a552bSJed Brown 478e27a552bSJed Brown PetscFunctionBegin; 479e27a552bSJed Brown if (!ark->tableau) { 480e27a552bSJed Brown ierr = TSRosWSetType(ts,TSRosWDefault);CHKERRQ(ierr); 481e27a552bSJed Brown } 482e27a552bSJed Brown ierr = VecDuplicateVecs(ts->vec_sol,s,&ark->Y);CHKERRQ(ierr); 483e27a552bSJed Brown ierr = VecDuplicateVecs(ts->vec_sol,s,&ark->YdotI);CHKERRQ(ierr); 484e27a552bSJed Brown ierr = VecDuplicateVecs(ts->vec_sol,s,&ark->YdotRHS);CHKERRQ(ierr); 485e27a552bSJed Brown ierr = VecDuplicate(ts->vec_sol,&ark->Ydot);CHKERRQ(ierr); 486e27a552bSJed Brown ierr = VecDuplicate(ts->vec_sol,&ark->Work);CHKERRQ(ierr); 487e27a552bSJed Brown ierr = VecDuplicate(ts->vec_sol,&ark->Z);CHKERRQ(ierr); 488e27a552bSJed Brown ierr = PetscMalloc(s*sizeof(ark->work[0]),&ark->work);CHKERRQ(ierr); 489e27a552bSJed Brown PetscFunctionReturn(0); 490e27a552bSJed Brown } 491e27a552bSJed Brown /*------------------------------------------------------------*/ 492e27a552bSJed Brown 493e27a552bSJed Brown #undef __FUNCT__ 494e27a552bSJed Brown #define __FUNCT__ "TSSetFromOptions_RosW" 495e27a552bSJed Brown static PetscErrorCode TSSetFromOptions_RosW(TS ts) 496e27a552bSJed Brown { 497e27a552bSJed Brown TS_RosW *ark = (TS_RosW*)ts->data; 498e27a552bSJed Brown PetscErrorCode ierr; 499e27a552bSJed Brown char arktype[256]; 500e27a552bSJed Brown 501e27a552bSJed Brown PetscFunctionBegin; 502e27a552bSJed Brown ierr = PetscOptionsHead("RosW ODE solver options");CHKERRQ(ierr); 503e27a552bSJed Brown { 504e27a552bSJed Brown ARKTableauLink link; 505e27a552bSJed Brown PetscInt count,choice; 506e27a552bSJed Brown PetscBool flg; 507e27a552bSJed Brown const char **namelist; 508e27a552bSJed Brown ierr = PetscStrncpy(arktype,TSRosWDefault,sizeof arktype);CHKERRQ(ierr); 509e27a552bSJed Brown for (link=ARKTableauList,count=0; link; link=link->next,count++) ; 510e27a552bSJed Brown ierr = PetscMalloc(count*sizeof(char*),&namelist);CHKERRQ(ierr); 511e27a552bSJed Brown for (link=ARKTableauList,count=0; link; link=link->next,count++) namelist[count] = link->tab.name; 512e27a552bSJed Brown ierr = PetscOptionsEList("-ts_rosw_type","Family of ARK IMEX method","TSRosWSetType",(const char*const*)namelist,count,arktype,&choice,&flg);CHKERRQ(ierr); 513e27a552bSJed Brown ierr = TSRosWSetType(ts,flg ? namelist[choice] : arktype);CHKERRQ(ierr); 514e27a552bSJed Brown ierr = PetscFree(namelist);CHKERRQ(ierr); 515e27a552bSJed Brown flg = (PetscBool)!ark->imex; 516e27a552bSJed Brown ierr = PetscOptionsBool("-ts_rosw_fully_implicit","Solve the problem fully implicitly","TSRosWSetFullyImplicit",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 517e27a552bSJed Brown ark->imex = (PetscBool)!flg; 518e27a552bSJed Brown ierr = SNESSetFromOptions(ts->snes);CHKERRQ(ierr); 519e27a552bSJed Brown } 520e27a552bSJed Brown ierr = PetscOptionsTail();CHKERRQ(ierr); 521e27a552bSJed Brown PetscFunctionReturn(0); 522e27a552bSJed Brown } 523e27a552bSJed Brown 524e27a552bSJed Brown #undef __FUNCT__ 525e27a552bSJed Brown #define __FUNCT__ "PetscFormatRealArray" 526e27a552bSJed Brown static PetscErrorCode PetscFormatRealArray(char buf[],size_t len,const char *fmt,PetscInt n,const PetscReal x[]) 527e27a552bSJed Brown { 528e27a552bSJed Brown PetscErrorCode ierr; 529e27a552bSJed Brown int i,left,count; 530e27a552bSJed Brown char *p; 531e27a552bSJed Brown 532e27a552bSJed Brown PetscFunctionBegin; 533e27a552bSJed Brown for (i=0,p=buf,left=(int)len; i<n; i++) { 534e27a552bSJed Brown ierr = PetscSNPrintf(p,left,fmt,&count,x[i]);CHKERRQ(ierr); 535e27a552bSJed Brown if (count >= left) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Insufficient space in buffer"); 536e27a552bSJed Brown left -= count; 537e27a552bSJed Brown p += count; 538e27a552bSJed Brown *p++ = ' '; 539e27a552bSJed Brown } 540e27a552bSJed Brown p[i ? 0 : -1] = 0; 541e27a552bSJed Brown PetscFunctionReturn(0); 542e27a552bSJed Brown } 543e27a552bSJed Brown 544e27a552bSJed Brown #undef __FUNCT__ 545e27a552bSJed Brown #define __FUNCT__ "TSView_RosW" 546e27a552bSJed Brown static PetscErrorCode TSView_RosW(TS ts,PetscViewer viewer) 547e27a552bSJed Brown { 548e27a552bSJed Brown TS_RosW *ark = (TS_RosW*)ts->data; 549e27a552bSJed Brown ARKTableau tab = ark->tableau; 550e27a552bSJed Brown PetscBool iascii; 551e27a552bSJed Brown PetscErrorCode ierr; 552e27a552bSJed Brown 553e27a552bSJed Brown PetscFunctionBegin; 554e27a552bSJed Brown ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 555e27a552bSJed Brown if (iascii) { 556e27a552bSJed Brown const TSRosWType arktype; 557e27a552bSJed Brown char buf[512]; 558e27a552bSJed Brown ierr = TSRosWGetType(ts,&arktype);CHKERRQ(ierr); 559e27a552bSJed Brown ierr = PetscViewerASCIIPrintf(viewer," ARK IMEX %s\n",arktype);CHKERRQ(ierr); 560e27a552bSJed Brown ierr = PetscFormatRealArray(buf,sizeof buf,"% 8.6f",tab->s,tab->ct);CHKERRQ(ierr); 561e27a552bSJed Brown ierr = PetscViewerASCIIPrintf(viewer," Stiff abscissa ct = %s\n",buf);CHKERRQ(ierr); 562e27a552bSJed Brown ierr = PetscFormatRealArray(buf,sizeof buf,"% 8.6f",tab->s,tab->c);CHKERRQ(ierr); 563e27a552bSJed Brown ierr = PetscViewerASCIIPrintf(viewer," Nonstiff abscissa c = %s\n",buf);CHKERRQ(ierr); 564e27a552bSJed Brown } 565e27a552bSJed Brown ierr = SNESView(ts->snes,viewer);CHKERRQ(ierr); 566e27a552bSJed Brown PetscFunctionReturn(0); 567e27a552bSJed Brown } 568e27a552bSJed Brown 569e27a552bSJed Brown #undef __FUNCT__ 570e27a552bSJed Brown #define __FUNCT__ "TSRosWSetType" 571e27a552bSJed Brown /*@C 572e27a552bSJed Brown TSRosWSetType - Set the type of ARK IMEX scheme 573e27a552bSJed Brown 574e27a552bSJed Brown Logically collective 575e27a552bSJed Brown 576e27a552bSJed Brown Input Parameter: 577e27a552bSJed Brown + ts - timestepping context 578e27a552bSJed Brown - arktype - type of ARK-IMEX scheme 579e27a552bSJed Brown 580e27a552bSJed Brown Level: intermediate 581e27a552bSJed Brown 582e27a552bSJed Brown .seealso: TSRosWGetType() 583e27a552bSJed Brown @*/ 584e27a552bSJed Brown PetscErrorCode TSRosWSetType(TS ts,const TSRosWType arktype) 585e27a552bSJed Brown { 586e27a552bSJed Brown PetscErrorCode ierr; 587e27a552bSJed Brown 588e27a552bSJed Brown PetscFunctionBegin; 589e27a552bSJed Brown PetscValidHeaderSpecific(ts,TS_CLASSID,1); 590e27a552bSJed Brown ierr = PetscTryMethod(ts,"TSRosWSetType_C",(TS,const TSRosWType),(ts,arktype));CHKERRQ(ierr); 591e27a552bSJed Brown PetscFunctionReturn(0); 592e27a552bSJed Brown } 593e27a552bSJed Brown 594e27a552bSJed Brown #undef __FUNCT__ 595e27a552bSJed Brown #define __FUNCT__ "TSRosWGetType" 596e27a552bSJed Brown /*@C 597e27a552bSJed Brown TSRosWGetType - Get the type of ARK IMEX scheme 598e27a552bSJed Brown 599e27a552bSJed Brown Logically collective 600e27a552bSJed Brown 601e27a552bSJed Brown Input Parameter: 602e27a552bSJed Brown . ts - timestepping context 603e27a552bSJed Brown 604e27a552bSJed Brown Output Parameter: 605e27a552bSJed Brown . arktype - type of ARK-IMEX scheme 606e27a552bSJed Brown 607e27a552bSJed Brown Level: intermediate 608e27a552bSJed Brown 609e27a552bSJed Brown .seealso: TSRosWGetType() 610e27a552bSJed Brown @*/ 611e27a552bSJed Brown PetscErrorCode TSRosWGetType(TS ts,const TSRosWType *arktype) 612e27a552bSJed Brown { 613e27a552bSJed Brown PetscErrorCode ierr; 614e27a552bSJed Brown 615e27a552bSJed Brown PetscFunctionBegin; 616e27a552bSJed Brown PetscValidHeaderSpecific(ts,TS_CLASSID,1); 617e27a552bSJed Brown ierr = PetscUseMethod(ts,"TSRosWGetType_C",(TS,const TSRosWType*),(ts,arktype));CHKERRQ(ierr); 618e27a552bSJed Brown PetscFunctionReturn(0); 619e27a552bSJed Brown } 620e27a552bSJed Brown 621e27a552bSJed Brown #undef __FUNCT__ 622e27a552bSJed Brown #define __FUNCT__ "TSRosWSetFullyImplicit" 623e27a552bSJed Brown /*@C 624e27a552bSJed Brown TSRosWSetFullyImplicit - Solve both parts of the equation implicitly 625e27a552bSJed Brown 626e27a552bSJed Brown Logically collective 627e27a552bSJed Brown 628e27a552bSJed Brown Input Parameter: 629e27a552bSJed Brown + ts - timestepping context 630e27a552bSJed Brown - flg - PETSC_TRUE for fully implicit 631e27a552bSJed Brown 632e27a552bSJed Brown Level: intermediate 633e27a552bSJed Brown 634e27a552bSJed Brown .seealso: TSRosWGetType() 635e27a552bSJed Brown @*/ 636e27a552bSJed Brown PetscErrorCode TSRosWSetFullyImplicit(TS ts,PetscBool flg) 637e27a552bSJed Brown { 638e27a552bSJed Brown PetscErrorCode ierr; 639e27a552bSJed Brown 640e27a552bSJed Brown PetscFunctionBegin; 641e27a552bSJed Brown PetscValidHeaderSpecific(ts,TS_CLASSID,1); 642e27a552bSJed Brown ierr = PetscTryMethod(ts,"TSRosWSetFullyImplicit_C",(TS,PetscBool),(ts,flg));CHKERRQ(ierr); 643e27a552bSJed Brown PetscFunctionReturn(0); 644e27a552bSJed Brown } 645e27a552bSJed Brown 646e27a552bSJed Brown EXTERN_C_BEGIN 647e27a552bSJed Brown #undef __FUNCT__ 648e27a552bSJed Brown #define __FUNCT__ "TSRosWGetType_RosW" 649e27a552bSJed Brown PetscErrorCode TSRosWGetType_RosW(TS ts,const TSRosWType *arktype) 650e27a552bSJed Brown { 651e27a552bSJed Brown TS_RosW *ark = (TS_RosW*)ts->data; 652e27a552bSJed Brown PetscErrorCode ierr; 653e27a552bSJed Brown 654e27a552bSJed Brown PetscFunctionBegin; 655e27a552bSJed Brown if (!ark->tableau) {ierr = TSRosWSetType(ts,TSRosWDefault);CHKERRQ(ierr);} 656e27a552bSJed Brown *arktype = ark->tableau->name; 657e27a552bSJed Brown PetscFunctionReturn(0); 658e27a552bSJed Brown } 659e27a552bSJed Brown #undef __FUNCT__ 660e27a552bSJed Brown #define __FUNCT__ "TSRosWSetType_RosW" 661e27a552bSJed Brown PetscErrorCode TSRosWSetType_RosW(TS ts,const TSRosWType arktype) 662e27a552bSJed Brown { 663e27a552bSJed Brown TS_RosW *ark = (TS_RosW*)ts->data; 664e27a552bSJed Brown PetscErrorCode ierr; 665e27a552bSJed Brown PetscBool match; 666e27a552bSJed Brown ARKTableauLink link; 667e27a552bSJed Brown 668e27a552bSJed Brown PetscFunctionBegin; 669e27a552bSJed Brown if (ark->tableau) { 670e27a552bSJed Brown ierr = PetscStrcmp(ark->tableau->name,arktype,&match);CHKERRQ(ierr); 671e27a552bSJed Brown if (match) PetscFunctionReturn(0); 672e27a552bSJed Brown } 673e27a552bSJed Brown for (link = ARKTableauList; link; link=link->next) { 674e27a552bSJed Brown ierr = PetscStrcmp(link->tab.name,arktype,&match);CHKERRQ(ierr); 675e27a552bSJed Brown if (match) { 676e27a552bSJed Brown ierr = TSReset_RosW(ts);CHKERRQ(ierr); 677e27a552bSJed Brown ark->tableau = &link->tab; 678e27a552bSJed Brown PetscFunctionReturn(0); 679e27a552bSJed Brown } 680e27a552bSJed Brown } 681e27a552bSJed Brown SETERRQ1(((PetscObject)ts)->comm,PETSC_ERR_ARG_UNKNOWN_TYPE,"Could not find '%s'",arktype); 682e27a552bSJed Brown PetscFunctionReturn(0); 683e27a552bSJed Brown } 684e27a552bSJed Brown #undef __FUNCT__ 685e27a552bSJed Brown #define __FUNCT__ "TSRosWSetFullyImplicit_RosW" 686e27a552bSJed Brown PetscErrorCode TSRosWSetFullyImplicit_RosW(TS ts,PetscBool flg) 687e27a552bSJed Brown { 688e27a552bSJed Brown TS_RosW *ark = (TS_RosW*)ts->data; 689e27a552bSJed Brown 690e27a552bSJed Brown PetscFunctionBegin; 691e27a552bSJed Brown ark->imex = (PetscBool)!flg; 692e27a552bSJed Brown PetscFunctionReturn(0); 693e27a552bSJed Brown } 694e27a552bSJed Brown EXTERN_C_END 695e27a552bSJed Brown 696e27a552bSJed Brown /* ------------------------------------------------------------ */ 697e27a552bSJed Brown /*MC 698e27a552bSJed Brown TSRosW - ODE solver using Rosenbrock-W schemes 699e27a552bSJed Brown 700e27a552bSJed Brown These methods are intended for problems with well-separated time scales, especially when a slow scale is strongly 701e27a552bSJed Brown nonlinear such that it is expensive to solve with a fully implicit method. The user should provide the stiff part 702e27a552bSJed Brown of the equation using TSSetIFunction() and the non-stiff part with TSSetRHSFunction(). 703e27a552bSJed Brown 704e27a552bSJed Brown Notes: 705e27a552bSJed Brown This method currently only works with ODE, for which the stiff part G(t,X,Xdot) has the form Xdot + Ghat(t,X). 706e27a552bSJed Brown 707e27a552bSJed Brown Level: beginner 708e27a552bSJed Brown 709e27a552bSJed Brown .seealso: TSCreate(), TS, TSSetType(), TSRosWRegister() 710e27a552bSJed Brown 711e27a552bSJed Brown M*/ 712e27a552bSJed Brown EXTERN_C_BEGIN 713e27a552bSJed Brown #undef __FUNCT__ 714e27a552bSJed Brown #define __FUNCT__ "TSCreate_RosW" 715e27a552bSJed Brown PetscErrorCode TSCreate_RosW(TS ts) 716e27a552bSJed Brown { 717e27a552bSJed Brown TS_RosW *th; 718e27a552bSJed Brown PetscErrorCode ierr; 719e27a552bSJed Brown 720e27a552bSJed Brown PetscFunctionBegin; 721e27a552bSJed Brown #if !defined(PETSC_USE_DYNAMIC_LIBRARIES) 722e27a552bSJed Brown ierr = TSRosWInitializePackage(PETSC_NULL);CHKERRQ(ierr); 723e27a552bSJed Brown #endif 724e27a552bSJed Brown 725e27a552bSJed Brown ts->ops->reset = TSReset_RosW; 726e27a552bSJed Brown ts->ops->destroy = TSDestroy_RosW; 727e27a552bSJed Brown ts->ops->view = TSView_RosW; 728e27a552bSJed Brown ts->ops->setup = TSSetUp_RosW; 729e27a552bSJed Brown ts->ops->step = TSStep_RosW; 730e27a552bSJed Brown ts->ops->interpolate = TSInterpolate_RosW; 731e27a552bSJed Brown ts->ops->setfromoptions = TSSetFromOptions_RosW; 732e27a552bSJed Brown ts->ops->snesfunction = SNESTSFormFunction_RosW; 733e27a552bSJed Brown ts->ops->snesjacobian = SNESTSFormJacobian_RosW; 734e27a552bSJed Brown 735e27a552bSJed Brown ierr = PetscNewLog(ts,TS_RosW,&th);CHKERRQ(ierr); 736e27a552bSJed Brown ts->data = (void*)th; 737e27a552bSJed Brown th->imex = PETSC_TRUE; 738e27a552bSJed Brown 739e27a552bSJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWGetType_C","TSRosWGetType_RosW",TSRosWGetType_RosW);CHKERRQ(ierr); 740e27a552bSJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWSetType_C","TSRosWSetType_RosW",TSRosWSetType_RosW);CHKERRQ(ierr); 741e27a552bSJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)ts,"TSRosWSetFullyImplicit_C","TSRosWSetFullyImplicit_RosW",TSRosWSetFullyImplicit_RosW);CHKERRQ(ierr); 742e27a552bSJed Brown PetscFunctionReturn(0); 743e27a552bSJed Brown } 744e27a552bSJed Brown EXTERN_C_END 745