00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 static char const Id[] = "$Id: checkiterationllg.c 2681 2009-07-31 04:30:53Z scholz $\n\n";
00025 static char const Td[] = "$Today: " __FILE__ " " __DATE__ " " __TIME__ " $\n\n";
00026
00027 #include "llg.h"
00028 #include "io/magpario.h"
00029 #include "util/util.h"
00030 #include "field/field.h"
00031
00032 #ifdef ADDONS
00033 #include "addons/addons.h"
00034 #endif
00035
00036 static int doinit=1;
00037
00038 static PetscReal tol;
00039 static PetscReal renormtol=-1.0;
00040 static int condinp_equil;
00041 static PetscReal condinp_j;
00042 static PetscReal condinp_equil_j;
00043 static PetscReal condinp_t;
00044 static PetscReal *condinp_user=PETSC_NULL;
00045 static int userinptot = 0;
00046
00047
00048 extern KSP ksp_Au1;
00049 extern KSP ksp_Au2;
00050 extern realtype abstol, reltol;
00052 int adjtoldem(GridData *gdata, double fac)
00053 {
00054 MagparFunctionInfoBegin;
00055
00056 if (gdata->VHdem==PETSC_NULL) {
00057 MagparFunctionInfoReturn(0);
00058 }
00059
00060 PetscReal rtol, atol, dtol;
00061 int maxits;
00062
00063 ierr = KSPGetTolerances(ksp_Au1,&rtol,&atol,&dtol,(PetscInt*)&maxits);CHKERRQ(ierr);
00064
00065 if (rtol < 1e-10) {
00066 MagparFunctionInfoReturn(0);
00067 }
00068
00069 atol *= fac;
00070 rtol *= fac;
00071 ierr = KSPSetTolerances(ksp_Au1,rtol,atol,dtol,maxits);CHKERRQ(ierr);
00072
00073 PetscPrintf(PETSC_COMM_WORLD,
00074 "at t=%g ns: ",gdata->time*gdata->tscale*1e9
00075 );
00076
00077 PetscPrintf(PETSC_COMM_WORLD,
00078 "%s KSP reltol to %g , abstol to %g\n",
00079 fac>1.0 ? "Increased" : "Reduced",
00080 rtol,atol
00081 );
00082
00083 ierr = KSPGetTolerances(ksp_Au2,&rtol,&atol,&dtol,(PetscInt*)&maxits);CHKERRQ(ierr);
00084 atol *= fac;
00085 rtol *= fac;
00086 ierr = KSPSetTolerances(ksp_Au2,rtol,atol,dtol,maxits);CHKERRQ(ierr);
00087
00088 MagparFunctionInfoReturn(0);
00089 }
00090
00091
00092 int adjtol(GridData *gdata, double fac)
00093 {
00094 MagparFunctionInfoBegin;
00095
00096 if (reltol < 1e-10) {
00097 MagparFunctionInfoReturn(0);
00098 }
00099
00100 PetscPrintf(PETSC_COMM_WORLD,
00101 "at t=%g ns: ",gdata->time*gdata->tscale*1e9
00102 );
00103
00104 adjtoldem(gdata,fac);
00105
00106 reltol *= fac;
00107 abstol *= fac;
00108
00109 extern void *cvode_mem;
00110 long int nstep;
00111 int flag;
00112 flag=CVodeGetNumSteps(cvode_mem,&nstep);
00113 PetscPrintf(PETSC_COMM_WORLD,
00114 "%s PVODE reltol to %g , abstol to %g ; nstep since last reinit: %i\n",
00115 fac>1.0 ? "Increased" : "Reduced",
00116 reltol,abstol,nstep
00117 );
00118
00119 ierr = PVodeReInit(gdata);CHKERRQ(ierr);
00120
00121 MagparFunctionInfoReturn(0);
00122 }
00123
00124
00125 int EquilCheck(Vec M,PetscReal time,PetscReal *torque)
00126 {
00127 static PetscReal tlast=time-0.00001;
00128 static Vec Mold=PETSC_NULL;
00129
00130 MagparFunctionInfoBegin;
00131
00132
00133 if (Mold==PETSC_NULL) {
00134 ierr = VecDuplicate(M,&Mold);CHKERRQ(ierr);
00135 ierr = VecZeroEntries(Mold);CHKERRQ(ierr);
00136
00137
00138 ierr = VecCopy(M,Mold);CHKERRQ(ierr);
00139
00140
00141
00142 *torque=tol*1.01;
00143
00144 MagparFunctionInfoReturn(0);
00145 }
00146
00147 ierr = VecAXPY(Mold,-1.0,M);CHKERRQ(ierr);
00148
00149
00150 *torque=RenormVec(Mold,0.0,PETSC_MAX,ND)/(time-tlast);
00151
00152 ierr = VecCopy(M,Mold);CHKERRQ(ierr);
00153
00154 tlast=time;
00155
00156 MagparFunctionProfReturn(0);
00157 }
00158
00159
00160 int CheckIterationLLG_Init(GridData *gdata)
00161 {
00162 PetscTruth flg;
00163
00164 MagparFunctionLogBegin;
00165 char fn[256];
00166 char line[256];
00167 int rank;
00168 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
00169
00170 ierr = PetscOptionsGetReal(PETSC_NULL,"-renormtol",&renormtol,&flg);CHKERRQ(ierr);
00171 if (flg!=PETSC_TRUE) {
00172 renormtol=1e-2;
00173 PetscPrintf(PETSC_COMM_WORLD,
00174 "Option -renormtol not found, using default value: %g\n",
00175 renormtol
00176 );
00177 }
00178 PetscPrintf(PETSC_COMM_WORLD,"renormtol: %g\n",renormtol);
00179
00180 ierr = PetscOptionsGetReal(PETSC_NULL,"-tol",&tol,&flg);CHKERRQ(ierr);
00181 if (flg!=PETSC_TRUE) {
00182 tol=1e-5;
00183 PetscPrintf(PETSC_COMM_WORLD,
00184 "Option -tol not found, using default value: %g\n",
00185 tol
00186 );
00187 }
00188 PetscPrintf(PETSC_COMM_WORLD,"tol (equilibrium): %g\n",tol);
00189
00190 if (abstol > tol/10.0) {
00191 PetscPrintf(PETSC_COMM_WORLD,
00192 "Warning: abstol=%g should be < (tol=%g)/10.0!\n",
00193 abstol,
00194 tol
00195 );
00196 }
00197
00198 ierr = PetscOptionsGetInt(PETSC_NULL,"-condinp_equil", (PetscInt*)&condinp_equil, &flg);CHKERRQ(ierr);
00199 if (flg!=PETSC_TRUE) {
00200 condinp_equil=1;
00201 PetscPrintf(PETSC_COMM_WORLD,
00202 "Option -condinp_equil not found, using default value: %i\n",
00203 condinp_equil
00204 );
00205 }
00206 ierr = PetscOptionsGetReal(PETSC_NULL,"-condinp_j",&condinp_j,&flg);CHKERRQ(ierr);
00207 if (flg!=PETSC_TRUE) {
00208 condinp_j=0.1;
00209 PetscPrintf(PETSC_COMM_WORLD,
00210 "Option -condinp_j not found, using default value: %g\n",
00211 condinp_j
00212 );
00213 }
00214 ierr = PetscOptionsGetReal(PETSC_NULL,"-condinp_equil_j",&condinp_equil_j,&flg);CHKERRQ(ierr);
00215 if (flg!=PETSC_TRUE) {
00216 condinp_equil_j=0.0;
00217 PetscPrintf(PETSC_COMM_WORLD,
00218 "Option -condinp_equil_j not found, using default value: %g\n",
00219 condinp_equil_j
00220 );
00221 }
00222 ierr = PetscOptionsGetReal(PETSC_NULL,"-condinp_t",&condinp_t,&flg);CHKERRQ(ierr);
00223 if (flg!=PETSC_TRUE) {
00224 condinp_t=PETSC_MAX;
00225 PetscPrintf(PETSC_COMM_WORLD,
00226 "Option -condinp_t not found, using default value: %g\n",
00227 condinp_t
00228 );
00229 }
00230
00231
00232 ierr = PetscOptionsGetString(PETSC_NULL,"-condinp_file_t_ns",fn,sizeof(fn),&flg);CHKERRQ(ierr);
00233 if (flg!=PETSC_TRUE) {
00234 PetscPrintf(PETSC_COMM_WORLD,
00235 "Option -condinp_file_t_ns not found, user inp output times NOT activated\n"
00236 );
00237 userinptot = 0;
00238 }
00239 else {
00240 if (!rank) {
00241 FILE *fd=NULL;
00242 PetscPrintf(PETSC_COMM_WORLD,"Opening condinp_file_t_ns file %s\n",fn);
00243 ierr = PetscFOpen(PETSC_COMM_WORLD,fn,"r",&fd);CHKERRQ(ierr);
00244 if (!fd){
00245 SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open %s\n",fn);
00246 }
00247 read_one_line(fd,line,sizeof(line),NULL);
00248 if (sscanf(line,"%i",&userinptot) != 1) {
00249 SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"could not read number of user inp values\n");
00250 }
00251
00252 ierr = PetscMalloc(userinptot*sizeof(PetscReal),&condinp_user);CHKERRQ(ierr);
00253
00254 for (int i=0;i<userinptot;i++) {
00255 read_one_line(fd,line,sizeof(line),NULL);
00256 if (sscanf(line,"%lf",condinp_user + i) != 1) {
00257 SETERRQ1(PETSC_ERR_FILE_UNEXPECTED,"could not read user inp time value %i\n",i);
00258 }
00259 condinp_user[i] /= 1e9*gdata->tscale;
00260 }
00261
00262 PetscPrintf(PETSC_COMM_WORLD,"Number of user inp output times read in: %i\n",userinptot);
00263 ierr = PetscFClose(PETSC_COMM_WORLD,fd);CHKERRQ(ierr);
00264 }
00265
00266 ierr = MPI_Bcast(&userinptot,1,MPI_INT,0,PETSC_COMM_WORLD);CHKERRQ(ierr);
00267 if (rank) {
00268 ierr = PetscMalloc(userinptot*sizeof(PetscReal),&condinp_user);CHKERRQ(ierr);
00269 }
00270 ierr = MPI_Bcast(condinp_user,userinptot,MPIU_SCALAR,0,PETSC_COMM_WORLD);CHKERRQ(ierr);
00271 }
00272 condinp_t /= 1e9*gdata->tscale;
00273
00274 MagparFunctionLogReturn(0);
00275 }
00276
00277
00278 int CheckIterationLLG(GridData *gdata)
00279 {
00280 static PetscReal Etotold=PETSC_MAX;
00281 static PetscReal hextold=PETSC_MAX;
00282 static PetscReal condinp_last_t=PETSC_MIN;
00283 static PetscReal condinp_last_j=PETSC_MIN;
00284 static PetscReal condinp_last_equil_j=PETSC_MIN;
00285
00286 const PetscReal tolscale=3.0;
00287
00288 static int nsteps=-1;
00289 static int csteps;
00290
00291 static PetscReal Edemold=gdata->Edem;
00292 static PetscReal dEdem1=0;
00293 static PetscReal dEdem2=0;
00294
00295 static PetscReal timelast=gdata->time;
00296
00297 static int userinpindex = 0;
00298
00299 #undef CHKDMDT
00300 #ifdef CHKDMDT
00301 static Vec dMdt;
00302 #endif
00303
00304 MagparFunctionInfoBegin;
00305
00306
00307 if (doinit) {
00308 ierr = CheckIterationLLG_Init(gdata);CHKERRQ(ierr);
00309 #ifdef CHKDMDT
00310 VecDuplicate(gdata->M,&dMdt);
00311 #endif
00312 doinit=0;
00313 }
00314
00315 #ifdef CHKDMDT
00316
00317
00318
00319
00320 PetscReal veq;
00321 calc_dMdt(PETSC_NULL,0.0,gdata->M,dMdt,gdata);
00322 veq=RenormVec(dMdt,0.0,PETSC_MAX,ND);
00323 gdata->equil=veq;
00324
00325 #if 1
00326 ierr = EquilCheck(gdata->M,gdata->time,&gdata->vequil);CHKERRQ(ierr);
00327 #endif
00328
00329 PetscPrintf(PETSC_COMM_WORLD,"torque = %g %g %g\n",veq,gdata->vequil,veq/gdata->vequil);
00330 #else
00331 ierr = EquilCheck(gdata->M,gdata->time,&gdata->vequil);CHKERRQ(ierr);
00332 #endif
00333
00334
00335
00336
00337
00338 if (gdata->vequil < tol) {
00339
00340 gdata->equil++;
00341 }
00342 else {
00343
00344 gdata->equil=0;
00345 }
00346
00347
00348
00349
00350 PetscReal hext;
00351 hext=Hexternal_hext();
00352 if (gdata->Etot > Etotold &&
00353 hext == hextold &&
00354 ((gdata->Etot-Etotold)/Etotold)>1e-8) {
00355
00356 PetscPrintf(MPI_COMM_WORLD,
00357 "Warning (t=%g ns): Etot increased by %g (%g*Etot) from %g to %g J/m^3\n",
00358 gdata->time*gdata->tscale*1e9,
00359 (gdata->Etot-Etotold)*gdata->escale,
00360 (gdata->Etot-Etotold)/Etotold,
00361 Etotold*gdata->escale,
00362 gdata->Etot*gdata->escale
00363 );
00364
00365
00366
00367
00368 }
00369 Etotold=gdata->Etot;
00370 hextold=hext;
00371
00372 PetscReal valMpHext;
00373 ierr = MpHext(gdata->M,&valMpHext);CHKERRQ(ierr);
00374
00375
00376 if (PetscAbsReal(valMpHext-condinp_last_j) > condinp_j) {
00377 gdata->inp=PetscAbsInt(gdata->inp);
00378
00379 condinp_last_t=gdata->time;
00380 condinp_last_j=valMpHext;
00381 }
00382 else if (PetscAbsReal(gdata->time-condinp_last_t) > condinp_t) {
00383 gdata->inp=PetscAbsInt(gdata->inp);
00384
00385 condinp_last_t=gdata->time;
00386 condinp_last_j=valMpHext;
00387 }
00388 else if ( userinpindex < userinptot && gdata->time >= condinp_user[userinpindex]) {
00389 gdata->inp=PetscAbsInt(gdata->inp);
00390
00391 condinp_last_t=gdata->time;
00392 condinp_last_j=valMpHext;
00393 userinpindex++;
00394 }
00395 else if (condinp_equil==1 && gdata->equil > 0) {
00396
00397 if (PetscAbsReal(valMpHext-condinp_last_equil_j) > condinp_equil_j) {
00398 gdata->inp=PetscAbsInt(gdata->inp);
00399
00400 condinp_last_t=gdata->time;
00401 condinp_last_j=valMpHext;
00402 condinp_last_equil_j=valMpHext;
00403 }
00404 }
00405
00406 if (nsteps<0) {
00407 PetscTruth flg;
00408 ierr = PetscOptionsGetInt(PETSC_NULL,"-ts_logsteps",(PetscInt*)&nsteps,&flg);CHKERRQ(ierr);
00409 if (flg!=PETSC_TRUE) {
00410 nsteps=1;
00411 PetscPrintf(PETSC_COMM_WORLD,
00412 "Option -ts_logsteps not found, using default value: %i\n",
00413 nsteps
00414 );
00415 }
00416 if (nsteps<1) {
00417 SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Option set: -ts_logsteps %i, but has to be >0\n",nsteps);
00418 }
00419 csteps=0;
00420 }
00421
00422 if (csteps % nsteps == 0 || gdata->equil>0) {
00423 ierr = WriteLog(gdata);CHKERRQ(ierr);
00424 ierr = WriteSet(gdata);CHKERRQ(ierr);
00425 csteps=0;
00426 }
00427 csteps++;
00428
00429 #ifdef ADDONS
00430
00431 ierr = MovingField(gdata);CHKERRQ(ierr);
00432 #endif
00433
00434 extern void *cvode_mem;
00435 long int nstep;
00436 int flag;
00437 flag=CVodeGetNumSteps(cvode_mem,&nstep);
00438
00439
00440 if (gdata->equil>0) {
00441 ierr = Hext_ho_hstep(gdata);CHKERRQ(ierr);
00442
00443
00444 if (gdata->equil>0) {
00445
00446 PetscPrintf(PETSC_COMM_WORLD,"gdata->equil %i >= 1\n",gdata->equil);
00447 gdata->mode=99;
00448 }
00449
00450 else if (nstep>0) {
00451 ierr = PVodeReInit(gdata);CHKERRQ(ierr);
00452 }
00453 }
00454
00455
00456
00457 PetscReal devNorm;
00458 devNorm=RenormVec(gdata->M,1.0,renormtol,ND);
00459
00460 if (PetscAbsReal(devNorm) > renormtol) {
00461 PetscPrintf(PETSC_COMM_WORLD,
00462 "t=%g ns: renormalized M because |%g| > %g\n",
00463 gdata->time*gdata->tscale*1e9,
00464 devNorm,
00465 renormtol
00466 );
00467
00468
00469 if (nstep<3 && reltol > 1e-10) {
00470
00471 ierr = adjtol(gdata,1.0/tolscale);CHKERRQ(ierr);
00472 }
00473 else {
00474
00475 ierr = PVodeReInit(gdata);CHKERRQ(ierr);
00476 }
00477 }
00478
00479 else if ((gdata->time-timelast)*gdata->tscale*1e9<1e-5 && nstep>100) {
00480 PetscInfo2(0,
00481 "Warning (t=%g ns): timestep is %g < 1e-4\n",
00482 gdata->time*gdata->tscale*1e9,
00483 (gdata->time-timelast)*gdata->tscale*1e9
00484 );
00485
00486
00487
00488
00489
00490 if (gdata->VHdem!=PETSC_NULL &&
00491 (gdata->Edem-Edemold)*dEdem1<0 &&
00492 (gdata->Edem-Edemold)*dEdem2>0) {
00493 PetscInfo2(0,
00494 "and Edem oscillates: %g %g\n",
00495 gdata->Edem,
00496 Edemold
00497 );
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511 }
00512 }
00513
00514 else if (gdata->VHdem!=PETSC_NULL &&
00515 (gdata->Edem-Edemold)*dEdem1<0 &&
00516 (gdata->Edem-Edemold)*dEdem2>0) {
00517 PetscInfo2(0,
00518 "Warning (t=%g ns): Edem oscillates: %g\n",
00519 gdata->time*gdata->tscale*1e9,
00520 gdata->Edem
00521 );
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536 }
00537
00538
00539
00540
00541
00542 else {
00543 long int ncfn;
00544 extern void *cvode_mem;
00545 CVodeGetNumNonlinSolvConvFails(cvode_mem,&ncfn);
00546 if (nstep > 30 &&
00547 devNorm <= renormtol/100.0 &&
00548 reltol <= tol/10.0 &&
00549 reltol <= 1e-2 &&
00550 ncfn == 0) {
00551 ierr = adjtol(gdata,tolscale);CHKERRQ(ierr);
00552 }
00553 }
00554
00555 timelast=gdata->time;
00556
00557 dEdem2=dEdem1;
00558 dEdem1=gdata->Edem-Edemold;
00559 Edemold=gdata->Edem;
00560
00561 MagparFunctionProfReturn(0);
00562 }