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: hdemag.c 2897 2009-12-04 03:56:51Z scholz $\n\n";
00025 static char const Td[] = "$Today: " __FILE__ " " __DATE__ " " __TIME__ " $\n\n";
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "field/field.h"
00036 #include "init/init.h"
00037 #include "util/util.h"
00038
00039 static int doinit=1;
00040 static int fieldon=0;
00041
00042 static Mat Bmat;
00043 static Mat AdivM;
00044 static Mat Agradu;
00045 static Mat ABu1;
00046 static Mat ABu2;
00047 static Vec u2bnd;
00048 static Vec u1;
00049 static Vec u1bnd;
00050 static Vec u2;
00051 static Vec bu1;
00052 static Vec bu2;
00053 static Vec utot;
00055 KSP ksp_Au1;
00056 KSP ksp_Au2;
00057
00058 #ifdef HDEMAGUEPOL
00059 static Vec u1bak;
00060 static Vec u2bak;
00061 static Vec du1dt;
00062 static Vec du2dt;
00063 #endif
00064
00065 #include "bmatrix.c"
00066
00067 int Hdemag_Init(GridData *gdata)
00068 {
00069 MagparFunctionLogBegin;
00070
00071 int rank,size;
00072 ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr);
00073 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
00074
00075 gdata->VHdem=PETSC_NULL;
00076
00077 PetscTruth flg;
00078 ierr = PetscOptionsGetInt(PETSC_NULL,"-demag",(PetscInt*)&fieldon,&flg);CHKERRQ(ierr);
00079 if (flg!=PETSC_TRUE) {
00080 fieldon=1;
00081 PetscPrintf(PETSC_COMM_WORLD,
00082 "Option -demag not found, using default value: %i\n",
00083 fieldon
00084 );
00085 }
00086
00087 if (!fieldon) {
00088 PetscPrintf(PETSC_COMM_WORLD,"Hdemag off\n");
00089 MagparFunctionLogReturn(0);
00090 }
00091 PetscPrintf(PETSC_COMM_WORLD,"Hdemag on\n");
00092
00093
00094
00095
00096 #if 0
00097 #define U1DIRICHLET 0
00098 PetscPrintf(PETSC_COMM_WORLD,"Using 1 Dirichlet BC for u1 on node %i\n",U1DIRICHLET);
00099 #else
00100 PetscPrintf(PETSC_COMM_WORLD,"No Dirichlet BC for u1 (floating)\n");
00101 #endif
00102
00103
00104
00105
00106
00107
00108 int ln_bmatrixrows;
00109 ln_bmatrixrows=gdata->n_vert_bnd/size;
00110 if ((gdata->n_vert_bnd%size)/(rank+1)>=1) ln_bmatrixrows++;
00111
00112 int ln_vert;
00113 ln_vert=gdata->ln_vert;
00114 int n_vert;
00115 n_vert=gdata->n_vert;
00116
00117 PetscPrintf(PETSC_COMM_WORLD,"Calculating sparsity pattern for matrix preallocation\n");
00118
00119
00120 int low,high;
00121 ierr = VecGetOwnershipRange(gdata->elevol,&low,&high);CHKERRQ(ierr);
00122
00123 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
00124 "<%i>element ownership: %i - %i\n",
00125 rank,low,high-1
00126 );
00127 PetscSynchronizedFlush(PETSC_COMM_WORLD);
00128
00129 int *elevertall;
00130
00131 #ifdef HAVE_ELEVERTALL
00132 elevertall=gdata->elevertall;
00133 #else
00134 if (size>1) {
00135 ierr = PetscMalloc(NV*gdata->n_ele*sizeof(int),&elevertall);CHKERRQ(ierr);
00136 ierr = PetscMemcpy(elevertall+NV*low,gdata->elevert,NV*gdata->ln_ele*sizeof(int));CHKERRQ(ierr);
00137
00138 int *p;
00139 p=elevertall;
00140
00141 int recvcount[size];
00142 recvcount[rank]=NV*gdata->ln_ele;
00143 for (int i=0;i<size;i++) {
00144 ierr = MPI_Bcast(recvcount+i,1,MPI_INT,i,PETSC_COMM_WORLD);CHKERRQ(ierr);
00145
00146 ierr = MPI_Bcast(p,recvcount[i],MPI_INT,i,PETSC_COMM_WORLD);CHKERRQ(ierr);
00147 p+=recvcount[i];
00148 }
00149 assert(p==elevertall+NV*gdata->n_ele);
00150 }
00151 else {
00152 elevertall=gdata->elevert;
00153 }
00154 #endif
00155
00156 int *ia,*ja;
00157 #ifdef HAVE_M2IJ
00158 ia=gdata->mesh2nodal_ia;
00159 ja=gdata->mesh2nodal_ja;
00160 #else
00161 ierr = Mesh2Nodal(gdata->n_ele,gdata->n_vert,elevertall,&ia,&ja);CHKERRQ(ierr);
00162 #endif
00163
00164
00165 ierr = VecGetOwnershipRange(gdata->M,&low,&high);CHKERRQ(ierr);
00166 low/=ND;
00167 high/=ND;
00168
00169
00170 ierr = VecCreate(PETSC_COMM_WORLD,&utot);CHKERRQ(ierr);
00171 ierr = VecSetSizes(utot,ln_vert,n_vert);CHKERRQ(ierr);
00172 ierr = VecSetFromOptions(utot);CHKERRQ(ierr);
00173
00174 #define XND 1
00175 int *d_nnz;
00176 int *o_nnz;
00177 ierr = PetscMalloc(ND*gdata->n_vert*sizeof(int),&d_nnz);CHKERRQ(ierr);
00178 ierr = PetscMalloc(ND*gdata->n_vert*sizeof(int),&o_nnz);CHKERRQ(ierr);
00179
00180 for (int i=0;i<gdata->n_vert;i++) {
00181 for (int j=0;j<XND;j++) {
00182 d_nnz[XND*i+j]=XND;
00183 o_nnz[XND*i+j]=0;
00184 for (int l=ia[i];l<ia[i+1];l++) {
00185 if (ja[l]>=low && ja[l]<high) {
00186 d_nnz[XND*i+j]+=1;
00187 }
00188 else {
00189 o_nnz[XND*i+j]+=1;
00190 }
00191 }
00192 }
00193 }
00194
00195 int *d_nnzm;
00196 int *o_nnzm;
00197 ierr = PetscMalloc(ND*n_vert*sizeof(int),&d_nnzm);CHKERRQ(ierr);
00198 ierr = PetscMalloc(ND*n_vert*sizeof(int),&o_nnzm);CHKERRQ(ierr);
00199
00200
00201 int lowm,highm;
00202
00203 lowm=low;
00204 highm=high;
00205
00206 ierr = PetscMemcpy(d_nnzm,d_nnz,ND*n_vert*sizeof(int));CHKERRQ(ierr);
00207 ierr = PetscMemcpy(o_nnzm,o_nnz,ND*n_vert*sizeof(int));CHKERRQ(ierr);
00208
00209
00210 Mat Au1;
00211 ierr = MatCreateMPIAIJ(
00212 PETSC_COMM_WORLD,
00213 ln_vert,ln_vert,
00214 n_vert,n_vert,
00215 0,d_nnzm+lowm,0,o_nnzm+lowm,
00216 &Au1
00217 );CHKERRQ(ierr);
00218 ierr = MatSetFromOptions(Au1);CHKERRQ(ierr);
00219
00220 ierr = MatCreateMPIAIJ(
00221 PETSC_COMM_WORLD,
00222 ln_bmatrixrows,ln_vert,
00223 gdata->n_vert_bnd,n_vert,
00224 1,PETSC_NULL,1,PETSC_NULL,
00225 &ABu1
00226 );CHKERRQ(ierr);
00227 ierr = MatSetFromOptions(ABu1);CHKERRQ(ierr);
00228
00229 Mat Au2;
00230 ierr = MatCreateMPIAIJ(
00231 PETSC_COMM_WORLD,
00232 ln_vert,ln_vert,
00233 n_vert,n_vert,
00234 0,d_nnzm+lowm,0,o_nnzm+lowm,
00235 &Au2
00236 );CHKERRQ(ierr);
00237 ierr = MatSetFromOptions(Au2);CHKERRQ(ierr);
00238
00239
00240
00241 for (int i=lowm; i<highm; i++) {
00242 d_nnzm[i] = PetscMin(d_nnzm[i],ln_bmatrixrows);
00243 o_nnzm[i] = PetscMin(d_nnzm[i],gdata->n_vert_bnd-ln_bmatrixrows);
00244 assert(d_nnzm[i]>=0);
00245 assert(o_nnzm[i]>=0);
00246 }
00247
00248 ierr = MatCreateMPIAIJ(
00249 PETSC_COMM_WORLD,
00250 ln_vert,ln_bmatrixrows,
00251 n_vert,gdata->n_vert_bnd,
00252 0,d_nnzm+lowm,0,o_nnzm+lowm,
00253 &ABu2
00254 );CHKERRQ(ierr);
00255 ierr = MatSetFromOptions(ABu2);CHKERRQ(ierr);
00256
00257
00258 for (int i=0; i<n_vert; i++) {
00259 d_nnzm[i] = 0;
00260 o_nnzm[i] = 0;
00261 }
00262 for (int i=0; i<gdata->n_vert; i++) {
00263 int i2;
00264 i2=i;
00265 if (i<lowm || i>=highm) continue;
00266 assert(d_nnz[i]>=0);
00267 assert(o_nnz[i]>=0);
00268 d_nnzm[i2] += ND*d_nnz[i]+ND*o_nnz[i];
00269 o_nnzm[i2] += ND*d_nnz[i]+ND*o_nnz[i];
00270 assert(i2<n_vert);
00271 assert(d_nnzm[i2]>=0);
00272 assert(o_nnzm[i2]>=0);
00273 }
00274
00275
00276 ierr = MatCreateMPIAIJ(
00277 PETSC_COMM_WORLD,
00278 ln_vert,ND*gdata->ln_vert,
00279 n_vert,ND*gdata->n_vert,
00280 0,d_nnzm+lowm,0,o_nnzm+lowm,
00281 &AdivM
00282 );CHKERRQ(ierr);
00283 ierr = MatSetFromOptions(AdivM);CHKERRQ(ierr);
00284
00285 for (int i=ND*gdata->n_vert-1; i>=0; i--) {
00286 d_nnz[i] = d_nnz[i/ND]+o_nnz[i/ND];
00287 o_nnz[i] = d_nnz[i/ND]+o_nnz[i/ND];
00288 assert(d_nnz[i]>=0);
00289 assert(o_nnz[i]>=0);
00290 }
00291
00292
00293 ierr = MatCreateMPIAIJ(
00294 PETSC_COMM_WORLD,
00295 ND*gdata->ln_vert,ln_vert,
00296 ND*gdata->n_vert,n_vert,
00297 0,d_nnz+ND*low,0,o_nnz+ND*low,
00298 &Agradu
00299 );CHKERRQ(ierr);
00300 ierr = MatSetFromOptions(Agradu);CHKERRQ(ierr);
00301
00302 #ifndef HAVE_M2IJ
00303 ierr = PetscFree(ia);CHKERRQ(ierr);
00304 ierr = PetscFree(ja);CHKERRQ(ierr);
00305 #endif
00306 ierr = PetscFree(d_nnz);CHKERRQ(ierr);
00307 ierr = PetscFree(o_nnz);CHKERRQ(ierr);
00308 #ifndef HAVE_ELEVERTALL
00309 if (size>1) {
00310 ierr = PetscFree(elevertall);CHKERRQ(ierr);
00311 }
00312 #endif
00313 ierr = PetscFree(d_nnzm);CHKERRQ(ierr);
00314 ierr = PetscFree(o_nnzm);CHKERRQ(ierr);
00315
00316 PetscReal *ta_elevol;
00317 ierr = VecGetArray(gdata->elevol,&ta_elevol);CHKERRQ(ierr);
00318
00319 PetscPrintf(PETSC_COMM_WORLD,"Calculating stiffness matrices...\n");
00320 for (int i=0; i<gdata->ln_ele; i++) {
00321 ierr = ProgressBar(i,gdata->ln_ele,10);
00322
00323
00324 int t_v[NV];
00325 int t_w[NV];
00326
00327 for (int j=0; j<NV; j++) {
00328 t_v[j]=gdata->elevert[i*NV+j];
00329 t_w[j]=t_v[j];
00330 }
00331
00332
00333 PetscReal D_etaj[NV][ND];
00334 tetgrad(
00335 gdata->vertxyz+t_v[0]*ND,
00336 gdata->vertxyz+t_v[1]*ND,
00337 gdata->vertxyz+t_v[2]*ND,
00338 gdata->vertxyz+t_v[3]*ND,
00339 D_etaj
00340 );
00341
00342
00343
00344 for (int l=0;l<NV;l++) {
00345 for (int j=0;j<NV;j++) {
00346
00347 PetscReal matele;
00348 matele=-ta_elevol[i]*my_ddot(ND,D_etaj[j],1,D_etaj[l],1);
00349
00350
00351
00352
00353 if (PetscAbsReal(matele)>D_EPS) {
00354 #ifdef U1DIRICHLET
00355
00356
00357
00358 if (t_w[j] != U1DIRICHLET &&
00359 t_w[l] != U1DIRICHLET) {
00360 #endif
00361 ierr = MatSetValue(
00362 Au1,
00363 t_w[j],
00364 t_w[l],
00365 matele,
00366 ADD_VALUES
00367 );CHKERRQ(ierr);
00368
00369 assert(t_w[j]<n_vert);
00370 assert(t_w[l]<n_vert);
00371 #ifdef U1DIRICHLET
00372 }
00373 #endif
00374
00375 int tvj,tvl;
00376 tvj=t_v[j];
00377 tvl=t_v[l];
00378 if (gdata->vertbndg2bnd[tvj]==C_INT) {
00379
00380 if (gdata->vertbndg2bnd[tvl]==C_INT) {
00381
00382
00383
00384 ierr = MatSetValue(
00385 Au2,
00386 t_w[j],
00387 t_w[l],
00388 matele,
00389 ADD_VALUES
00390 );CHKERRQ(ierr);
00391 assert(t_w[j]>=0);
00392 assert(t_w[l]>=0);
00393 assert(t_w[j]<n_vert);
00394 assert(t_w[l]<n_vert);
00395 }
00396 else {
00397
00398 ierr = MatSetValue(
00399 ABu2,
00400 t_w[j],
00401 gdata->vertbndg2bnd[tvl],
00402 -matele,
00403 ADD_VALUES
00404 );CHKERRQ(ierr);
00405 assert(t_w[j]<n_vert);
00406 assert(gdata->vertbndg2bnd[tvl]<gdata->n_vert_bnd);
00407 }
00408 }
00409 }
00410 }
00411 }
00412
00413 for (int l=0;l<NV;l++) {
00414 for (int k=0;k<ND;k++) {
00415 PetscReal matele;
00416 matele=ta_elevol[i]/NV*D_etaj[l][k];
00417 if (PetscAbsReal(matele)>D_EPS) {
00418 for (int j=0;j<NV;j++) {
00419 ierr = MatSetValue(
00420 Agradu,
00421 ND*t_v[j]+k,
00422 t_w[l],
00423 matele,
00424 ADD_VALUES
00425 );CHKERRQ(ierr);
00426 assert(t_v[j]<gdata->n_vert);
00427 assert(t_w[l]<n_vert);
00428
00429 #ifdef U1DIRICHLET
00430
00431 if (t_w[l] != U1DIRICHLET) {
00432 #endif
00433
00434 if (gdata->propdat[NP*gdata->eleprop[i]+4]>0.0) {
00435 ierr = MatSetValue(
00436 AdivM,
00437 t_w[l],
00438 ND*t_v[j]+k,
00439 matele*gdata->propdat[NP*gdata->eleprop[i]+4],
00440 ADD_VALUES
00441 );CHKERRQ(ierr);
00442 assert(t_w[l]<n_vert);
00443 assert(t_v[j]<gdata->n_vert);
00444 }
00445 #ifdef U1DIRICHLET
00446 }
00447 #endif
00448 }
00449 }
00450 }
00451 }
00452 }
00453 ierr = ProgressBar(1,1,10);
00454
00455 #undef MATFLUSH
00456 #ifdef MATFLUSH
00457 ierr = MatAssemblyBegin(Au1,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr);
00458 ierr = MatAssemblyEnd(Au1,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr);
00459 ierr = MatAssemblyBegin(Au2,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr);
00460 ierr = MatAssemblyEnd(Au2,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr);
00461 ierr = MatAssemblyBegin(ABu2,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr);
00462 ierr = MatAssemblyEnd(ABu2,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr);
00463 ierr = MatAssemblyBegin(Agradu,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr);
00464 ierr = MatAssemblyEnd(Agradu,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr);
00465 ierr = MatAssemblyBegin(AdivM,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr);
00466 ierr = MatAssemblyEnd(AdivM,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr);
00467 #endif
00468
00469 ierr = PetscGetTime(&t_t2);CHKERRQ(ierr);
00470 PetscPrintf(PETSC_COMM_WORLD,
00471 "stiffness matrix calculation took %g s = %g min\n",
00472 t_t2-t_t1,
00473 (t_t2-t_t1)/60.0
00474 );
00475
00476 ierr = VecRestoreArray(gdata->elevol,&ta_elevol);CHKERRQ(ierr);
00477
00478
00479 if (!rank) {
00480 #ifdef U1DIRICHLET
00481 ierr = MatSetValue(Au1,U1DIRICHLET,U1DIRICHLET,-1.0,ADD_VALUES);CHKERRQ(ierr);
00482 #endif
00483
00484 for (int i=0; i<gdata->n_vert; i++) {
00485 int j,k;
00486 j=i;
00487 k=j;
00488 if (gdata->vertbndg2bnd[j] >= 0) {
00489 assert(gdata->vertbndg2bnd[j]<gdata->n_vert_bnd);
00490
00491 ierr = MatSetValue(Au2,k,k,-1.0,ADD_VALUES);CHKERRQ(ierr);
00492 ierr = MatSetValue(ABu2,k,gdata->vertbndg2bnd[j],-1.0,ADD_VALUES);CHKERRQ(ierr);
00493 ierr = MatSetValue(ABu1,gdata->vertbndg2bnd[j],k,1.0,INSERT_VALUES);CHKERRQ(ierr);
00494 }
00495 }
00496 }
00497
00498 #undef DOMATCOMPRESS
00499 PetscPrintf(PETSC_COMM_WORLD,"Au1 matrix assembly complete\n");
00500 ierr = MatAssemblyBegin(Au1,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
00501 ierr = MatAssemblyEnd(Au1,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
00502
00503 #ifdef DOMATCOMPRESS
00504 ierr = MatCompress(Au1);CHKERRQ(ierr);
00505 #endif
00506 ierr = PrintMatInfoAll(Au1);CHKERRQ(ierr);
00507
00508 PetscPrintf(PETSC_COMM_WORLD,"Au2 matrix assembly complete\n");
00509 ierr = MatAssemblyBegin(Au2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
00510 ierr = MatAssemblyEnd(Au2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
00511 #ifdef DOMATCOMPRESS
00512 ierr = MatCompress(Au2);CHKERRQ(ierr);
00513 #endif
00514 ierr = PrintMatInfoAll(Au2);CHKERRQ(ierr);
00515
00516 PetscPrintf(PETSC_COMM_WORLD,"AdivM matrix assembly complete\n");
00517 ierr = MatAssemblyBegin(AdivM,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
00518 ierr = MatAssemblyEnd(AdivM,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
00519 #ifdef DOMATCOMPRESS
00520 ierr = MatCompress(AdivM);CHKERRQ(ierr);
00521 #endif
00522 ierr = PrintMatInfoAll(AdivM);CHKERRQ(ierr);
00523
00524 PetscPrintf(PETSC_COMM_WORLD,"Agradu matrix assembly complete\n");
00525 ierr = MatAssemblyBegin(Agradu,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
00526 ierr = MatAssemblyEnd(Agradu,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
00527 #ifdef DOMATCOMPRESS
00528 ierr = MatCompress(Agradu);CHKERRQ(ierr);
00529 #endif
00530 ierr = PrintMatInfoAll(Agradu);CHKERRQ(ierr);
00531
00532 PetscPrintf(PETSC_COMM_WORLD,"ABu1 matrix assembly complete\n");
00533 ierr = MatAssemblyBegin(ABu1,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
00534 ierr = MatAssemblyEnd(ABu1,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
00535 #ifdef DOMATCOMPRESS
00536 ierr = MatCompress(ABu1);CHKERRQ(ierr);
00537 #endif
00538 ierr = PrintMatInfoAll(ABu1);CHKERRQ(ierr);
00539
00540 PetscPrintf(PETSC_COMM_WORLD,"ABu2 matrix assembly complete\n");
00541 ierr = MatAssemblyBegin(ABu2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
00542 ierr = MatAssemblyEnd(ABu2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
00543 #ifdef DOMATCOMPRESS
00544 ierr = MatCompress(ABu2);CHKERRQ(ierr);
00545 #endif
00546 ierr = PrintMatInfoAll(ABu2);CHKERRQ(ierr);
00547
00548 Vec vertvolrec3;
00549 ierr = VecDuplicate(gdata->M,&vertvolrec3);CHKERRQ(ierr);
00550 for (int i=0;i<ND;i++) {
00551 ierr = VecStrideScatter(gdata->vertvol,i,vertvolrec3,INSERT_VALUES);CHKERRQ(ierr);
00552 }
00553 ierr = VecReciprocal(vertvolrec3);CHKERRQ(ierr);
00554 ierr = MatDiagonalScale(Agradu,vertvolrec3,PETSC_NULL);CHKERRQ(ierr);
00555
00556 ierr = VecDestroy(vertvolrec3);CHKERRQ(ierr);
00557
00558 ierr = MatScale(Au1,-1.0);CHKERRQ(ierr);
00559 ierr = MatScale(AdivM,-1.0);CHKERRQ(ierr);
00560
00561 ierr = MatScale(Au2,-1.0);CHKERRQ(ierr);
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579 #ifdef SUPERLU
00580 Mat Au1tmp;
00581 ierr = MatConvert(Au1,MATSUPERLU_DIST,MAT_INITIAL_MATRIX,&Au1tmp);CHKERRQ(ierr);
00582 ierr = MatDestroy(Au1);CHKERRQ(ierr);
00583 Au1=Au1tmp;
00584 #elif defined(BLOCKSOLVE)
00585 Mat Au1tmp;
00586 ierr = MatConvert(Au1,MATMPIROWBS,MAT_INITIAL_MATRIX,&Au1tmp);CHKERRQ(ierr);
00587 ierr = MatDestroy(Au1);CHKERRQ(ierr);
00588 Au1=Au1tmp;
00589 #endif
00590
00591 #ifdef SUPERLU
00592 Mat Au2tmp;
00593 ierr = MatConvert(Au2,MATSUPERLU_DIST,MAT_INITIAL_MATRIX,&Au2tmp);CHKERRQ(ierr);
00594 ierr = MatDestroy(Au2);CHKERRQ(ierr);
00595 Au2=Au2tmp;
00596 #elif defined(BLOCKSOLVE)
00597 Mat Au2tmp;
00598 ierr = MatConvert(Au2,MATMPIROWBS,MAT_INITIAL_MATRIX,&Au2tmp);CHKERRQ(ierr);
00599 ierr = MatDestroy(Au2);CHKERRQ(ierr);
00600 Au2=Au2tmp;
00601 #endif
00602
00603
00604 #if PETSC_VERSION >= 300
00605 ierr = MatSetOption(Au1,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
00606 ierr = MatSetOption(Au2,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
00607 ierr = MatSetOption(Au1,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr);
00608 ierr = MatSetOption(Au2,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr);
00609 #else
00610 ierr = MatSetOption(Au1,MAT_SYMMETRIC);CHKERRQ(ierr);
00611 ierr = MatSetOption(Au2,MAT_SYMMETRIC);CHKERRQ(ierr);
00612 ierr = MatSetOption(Au1,MAT_SYMMETRY_ETERNAL);CHKERRQ(ierr);
00613 ierr = MatSetOption(Au2,MAT_SYMMETRY_ETERNAL);CHKERRQ(ierr);
00614 #endif
00615
00616 ierr = VecDuplicate(utot,&u1);CHKERRQ(ierr);
00617 ierr = VecDuplicate(utot,&u2);CHKERRQ(ierr);
00618
00619 ierr = VecDuplicate(utot,&bu1);CHKERRQ(ierr);
00620 ierr = VecDuplicate(utot,&bu2);CHKERRQ(ierr);
00621
00622 ierr = VecCreate(PETSC_COMM_WORLD,&u1bnd);CHKERRQ(ierr);
00623 ierr = VecSetSizes(u1bnd,ln_bmatrixrows,gdata->n_vert_bnd);CHKERRQ(ierr);
00624 ierr = VecSetFromOptions(u1bnd);CHKERRQ(ierr);
00625
00626 ierr = VecDuplicate(u1bnd,&u2bnd);CHKERRQ(ierr);
00627
00628
00629
00630
00631 ierr = KSPCreate(PETSC_COMM_WORLD,&ksp_Au1);CHKERRQ(ierr);
00632 ierr = KSPCreate(PETSC_COMM_WORLD,&ksp_Au2);CHKERRQ(ierr);
00633 ierr = KSPSetOperators(ksp_Au1,Au1,Au1,SAME_PRECONDITIONER);CHKERRQ(ierr);
00634 ierr = KSPSetOperators(ksp_Au2,Au2,Au2,SAME_PRECONDITIONER);CHKERRQ(ierr);
00635
00636
00637
00638
00639 ierr = PetscOptionsHasName(PETSC_NULL,"-ksp_type",&flg);CHKERRQ(ierr);
00640 if (flg==PETSC_TRUE) {
00641 PetscPrintf(PETSC_COMM_WORLD,"Warning: Options '-ksp_*' are deprecated! Please use -hdemag_u{1,2}_ksp_* instead!\n");
00642 ierr = KSPSetFromOptions(ksp_Au1);CHKERRQ(ierr);
00643 ierr = KSPSetFromOptions(ksp_Au2);CHKERRQ(ierr);
00644 }
00645 else {
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656 for (int i=1;i<=2;i++) {
00657 char str[256],ostr[256];
00658
00659
00660 sprintf(ostr,"-hdemag_u%i_ksp_type",i);
00661 ierr = PetscOptionsGetString(PETSC_NULL,ostr,str,256,&flg);CHKERRQ(ierr);
00662 if (flg!=PETSC_TRUE) {
00663 sprintf(str,"cg");
00664 PetscOptionsSetValue(ostr,str);
00665 PetscPrintf(PETSC_COMM_WORLD,"Option %s not found, using default value %s!\n",ostr,str);
00666 }
00667
00668 if (size>1) {
00669
00670 sprintf(ostr,"-hdemag_u%i_pc_type",i);
00671 ierr = PetscOptionsGetString(PETSC_NULL,ostr,str,256,&flg);CHKERRQ(ierr);
00672 if (flg!=PETSC_TRUE) {
00673 sprintf(str,"bjacobi");
00674 PetscOptionsSetValue(ostr,str);
00675 PetscPrintf(PETSC_COMM_WORLD,"Option %s not found, using default value %s!\n",ostr,str);
00676 }
00677
00678
00679 sprintf(ostr,"-hdemag_u%i_sub_pc_type",i);
00680 ierr = PetscOptionsGetString(PETSC_NULL,ostr,str,256,&flg);CHKERRQ(ierr);
00681 if (flg!=PETSC_TRUE) {
00682 sprintf(str,"icc");
00683 PetscOptionsSetValue(ostr,str);
00684 PetscPrintf(PETSC_COMM_WORLD,"Option %s not found, using default value %s!\n",ostr,str);
00685 }
00686
00687
00688 sprintf(ostr,"-hdemag_u%i_sub_pc_factor_shift_positive_definite",i);
00689 ierr = PetscOptionsGetString(PETSC_NULL,ostr,str,256,&flg);CHKERRQ(ierr);
00690 if (flg!=PETSC_TRUE) {
00691 sprintf(str,"1");
00692 PetscOptionsSetValue(ostr,str);
00693 PetscPrintf(PETSC_COMM_WORLD,"Option %s not found, using default value %s!\n",ostr,str);
00694 }
00695 }
00696 else {
00697
00698 sprintf(ostr,"-hdemag_u%i_pc_type",i);
00699 ierr = PetscOptionsGetString(PETSC_NULL,ostr,str,256,&flg);CHKERRQ(ierr);
00700 if (flg!=PETSC_TRUE) {
00701 sprintf(str,"icc");
00702 PetscOptionsSetValue(ostr,str);
00703 PetscPrintf(PETSC_COMM_WORLD,"Option %s not found, using default value %s!\n",ostr,str);
00704 }
00705
00706
00707 sprintf(ostr,"-hdemag_u%i_pc_factor_shift_positive_definite",i);
00708 ierr = PetscOptionsGetString(PETSC_NULL,ostr,str,256,&flg);CHKERRQ(ierr);
00709 if (flg!=PETSC_TRUE) {
00710 sprintf(str,"1");
00711 PetscOptionsSetValue(ostr,str);
00712 PetscPrintf(PETSC_COMM_WORLD,"Option %s not found, using default value %s!\n",ostr,str);
00713 }
00714 }
00715 }
00716 }
00717
00718
00719 ierr = KSPSetOptionsPrefix(ksp_Au1,"hdemag_u1_");CHKERRQ(ierr);
00720
00721 ierr = KSPSetFromOptions(ksp_Au1);CHKERRQ(ierr);
00722
00723
00724 ierr = KSPSetOptionsPrefix(ksp_Au2,"hdemag_u2_");CHKERRQ(ierr);
00725
00726 ierr = KSPSetFromOptions(ksp_Au2);CHKERRQ(ierr);
00727
00728
00729 ierr = PetscOptionsHasName(PETSC_NULL,"-hdemag_u2_ksp_rtol",&flg);CHKERRQ(ierr);
00730
00731 if (flg!=PETSC_TRUE) {
00732 PetscReal rtol,atol,dtol;
00733 int maxits;
00734 ierr = KSPGetTolerances(ksp_Au1,&rtol,&atol,&dtol,&maxits);CHKERRQ(ierr);
00735
00736 PetscPrintf(PETSC_COMM_WORLD,"Adjusting tolerances for ksp_Au2\n");
00737 ierr = KSPSetTolerances(ksp_Au2,rtol*1e-3,atol,dtol,maxits);CHKERRQ(ierr);
00738 }
00739
00740
00741 ierr = KSPSetInitialGuessNonzero(ksp_Au1,PETSC_TRUE);CHKERRQ(ierr);
00742 ierr = KSPSetInitialGuessNonzero(ksp_Au2,PETSC_TRUE);CHKERRQ(ierr);
00743
00744
00745 ierr = KSPSetUp(ksp_Au1);CHKERRQ(ierr);
00746 ierr = KSPSetUp(ksp_Au2);CHKERRQ(ierr);
00747
00748 #if defined(SUPERLU) || defined(BLOCKSOLVE)
00749 ierr = KSPGetTolerances(ksp_Au1,&rtol,&atol,&dtol,&maxits);CHKERRQ(ierr);
00750 PetscPrintf(PETSC_COMM_WORLD,"KSP for A*u1=divM:\n");
00751 PetscPrintf(PETSC_COMM_WORLD,"rtol: %g atol: %g dtol: %g maxits: %i\n",
00752 rtol,atol,dtol,maxits
00753 );
00754 ierr = KSPGetTolerances(ksp_Au2,&rtol,&atol,&dtol,&maxits);CHKERRQ(ierr);
00755 PetscPrintf(PETSC_COMM_WORLD,"KSP for Au2*u2=u2bnd:\n");
00756 PetscPrintf(PETSC_COMM_WORLD,"rtol: %g atol: %g dtol: %g maxits: %i\n",
00757 rtol,atol,dtol,maxits
00758 );
00759 #else
00760 PetscPrintf(PETSC_COMM_WORLD,"KSP for A*u1=divM:\n");
00761 ierr = KSPView(ksp_Au1,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
00762 PetscPrintf(PETSC_COMM_WORLD,"KSP for Au2*u2=u2bnd:\n");
00763 ierr = KSPView(ksp_Au2,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
00764 #endif
00765
00766 ierr = VecDuplicate(gdata->M,&gdata->VHdem);CHKERRQ(ierr);
00767
00768 #ifdef HDEMAGUEPOL
00769 ierr = VecDuplicate(utot,&u1bak);CHKERRQ(ierr);
00770 ierr = VecDuplicate(utot,&u2bak);CHKERRQ(ierr);
00771 ierr = VecDuplicate(utot,&du1dt);CHKERRQ(ierr);
00772 ierr = VecDuplicate(utot,&du2dt);CHKERRQ(ierr);
00773 ierr = VecZeroEntries(du1dt);CHKERRQ(ierr);
00774 ierr = VecZeroEntries(du2dt);CHKERRQ(ierr);
00775 #endif
00776
00777 ierr = BMatrix(gdata,&Bmat);CHKERRQ(ierr);
00778
00779 MagparFunctionLogReturn(0);
00780 }
00781
00782
00783 int Hdemag(GridData *gdata,Vec VHtotsum)
00784 {
00785 #ifdef HDEMAGUEPOL
00786 static PetscReal tubak=0.0;
00787 PetscReal dt;
00788 #endif
00789
00790 int its1,its2;
00791
00792 MagparFunctionInfoBegin;
00793
00794 int rank,size;
00795 ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr);
00796 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
00797
00798 if (doinit) {
00799 ierr = Hdemag_Init(gdata);CHKERRQ(ierr);
00800 doinit=0;
00801
00802 ierr = PetscGetTime(&t_t1);CHKERRQ(ierr);
00803 }
00804 if (!fieldon) {
00805 MagparFunctionInfoReturn(0);
00806 }
00807
00808 PetscLogDouble t_t3;
00809 t_t3=t_t1;
00810
00811
00812
00813
00814
00815
00816
00817 ierr = MatMult(AdivM,gdata->M,bu1);CHKERRQ(ierr);
00818
00819 #ifdef HDEMAGUEPOL
00820 dt=gdata->time-tubak;
00821 if (gdata->mode==0 && PetscAbsReal(dt) > 1e-8){
00822
00823 PetscReal dt2;
00824 dt2=dt*0.5;
00825 ierr = VecWAXPY(u1,dt2,du1dt,u1bak);CHKERRQ(ierr);
00826 }
00827 else {
00828 dt=0.0;
00829 }
00830 #endif
00831
00832 t_t2=t_t3;
00833 ierr = PetscGetTime(&t_t3);CHKERRQ(ierr);
00834
00835 PetscTruth oprofile;
00836 PetscOptionsHasName(PETSC_NULL,"-profile",&oprofile);
00837 if (oprofile) {
00838 PetscPrintf(PETSC_COMM_WORLD," timing: %s - div(M) - took %g s\n",__FUNCT__,t_t3-t_t2);
00839 } else {
00840 PetscInfo2(0," timing: %s - div(M) - took %g s\n",__FUNCT__,t_t3-t_t2);
00841 }
00842
00843
00844
00845
00846
00847 #ifndef U1DIRICHLET
00848
00849
00850
00851
00852 PetscReal u1a,*ta_u1;
00853 ierr = VecGetArray(u1,&ta_u1);CHKERRQ(ierr);
00854 u1a = -ta_u1[0];
00855 ierr = VecRestoreArray(u1,&ta_u1);CHKERRQ(ierr);
00856 if (fabs(u1a)>1e6) {
00857 ierr = VecShift(u1,u1a);CHKERRQ(ierr);
00858 PetscPrintf(PETSC_COMM_WORLD,"u1 shifted by %g\n",u1a);
00859 }
00860 #endif
00861
00862
00863
00864
00865 ierr = KSPSetInitialGuessNonzero(ksp_Au1,PETSC_TRUE);CHKERRQ(ierr);
00866
00867
00868
00869
00870
00871 ierr = KSPSolve(ksp_Au1,bu1,u1);CHKERRQ(ierr);
00872 ierr = KSPGetIterationNumber(ksp_Au1,(PetscInt*)&its1);CHKERRQ(ierr);
00873
00874 KSPConvergedReason reason;
00875 ierr = KSPGetConvergedReason(ksp_Au1,&reason);CHKERRQ(ierr);
00876
00877 PetscInfo2(0,"Au1*u1=divM: %i its, reason: %i\n",its1, reason);
00878 if (reason<0) {
00879 PetscReal rnorm;
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898 ierr = KSPGetResidualNorm(ksp_Au1,&rnorm);CHKERRQ(ierr);
00899 SETERRQ3(PETSC_ERR_CONV_FAILED,
00900 "Warning: Au1*u1=divM: KSP did not converge at t=%g ns - reason: %i, rnorm: %g\n",
00901 gdata->time*gdata->tscale*1e9,reason,rnorm
00902 );
00903 }
00904
00905 t_t2=t_t3;
00906 ierr = PetscGetTime(&t_t3);CHKERRQ(ierr);
00907
00908 if (oprofile) {
00909 PetscPrintf(PETSC_COMM_WORLD," timing: %s - u1 - took %g s\n",__FUNCT__,t_t3-t_t2);
00910 } else {
00911 PetscInfo2(0," timing: %s - u1 - took %g s\n",__FUNCT__,t_t3-t_t2);
00912 }
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922 if (its1>0) {
00923
00924
00925
00926
00927
00928 ierr = MatMult(ABu1,u1,u1bnd);CHKERRQ(ierr);
00929
00930 t_t2=t_t3;
00931 ierr = PetscGetTime(&t_t3);CHKERRQ(ierr);
00932
00933 if (oprofile) {
00934 PetscPrintf(PETSC_COMM_WORLD," timing: %s - u1 scatter - took %g s\n",__FUNCT__,t_t3-t_t2);
00935 } else {
00936 PetscInfo2(0," timing: %s - u1 scatter - took %g s\n",__FUNCT__,t_t3-t_t2);
00937 }
00938
00939
00940 ierr = MatMult(Bmat,u1bnd,u2bnd);CHKERRQ(ierr);
00941
00942 t_t2=t_t3;
00943 ierr = PetscGetTime(&t_t3);CHKERRQ(ierr);
00944
00945 if (oprofile) {
00946 PetscPrintf(PETSC_COMM_WORLD," timing: %s - u2=B*u1 - took %g s\n",__FUNCT__,t_t3-t_t2);
00947 } else {
00948 PetscInfo2(0," timing: %s - u2=B*u1 - took %g s\n",__FUNCT__,t_t3-t_t2);
00949 }
00950
00951
00952 ierr = MatMult(ABu2,u2bnd,bu2);CHKERRQ(ierr);
00953
00954 t_t2=t_t3;
00955 ierr = PetscGetTime(&t_t3);CHKERRQ(ierr);
00956
00957 if (oprofile) {
00958 PetscPrintf(PETSC_COMM_WORLD," timing: %s - u2 scatter - took %g s\n",__FUNCT__,t_t3-t_t2);
00959 } else {
00960 PetscInfo2(0," timing: %s - u2 scatter - took %g s\n",__FUNCT__,t_t3-t_t2);
00961 }
00962
00963 #ifdef HDEMAGUEPOL
00964
00965
00966
00967
00968
00969
00970
00971
00972 #endif
00973
00974
00975
00976
00977
00978 ierr = KSPSetInitialGuessNonzero(ksp_Au2,PETSC_TRUE);CHKERRQ(ierr);
00979
00980
00981
00982
00983
00984 ierr = KSPSolve(ksp_Au2,bu2,u2);CHKERRQ(ierr);
00985 ierr = KSPGetIterationNumber(ksp_Au2,(PetscInt*)&its2);CHKERRQ(ierr);
00986 ierr = KSPGetConvergedReason(ksp_Au2,&reason);CHKERRQ(ierr);
00987
00988 PetscInfo2(0,"Au2*u2=bu2: %i its, reason: %i\n",its2, reason);
00989 if (reason<0) {
00990 PetscReal rnorm;
00991
00992 ierr = KSPGetResidualNorm(ksp_Au2,&rnorm);CHKERRQ(ierr);
00993 PetscPrintf(PETSC_COMM_WORLD,
00994 "Warning: Au2*u2=bu2: KSP did not converge at t=%g ns - reason: %i, rnorm: %g\n",
00995 gdata->time*gdata->tscale*1e9,reason,rnorm
00996 );
00997 }
00998
00999 t_t2=t_t3;
01000 ierr = PetscGetTime(&t_t3);CHKERRQ(ierr);
01001
01002 if (oprofile) {
01003 PetscPrintf(PETSC_COMM_WORLD," timing: %s - u2 - took %g s\n",__FUNCT__,t_t3-t_t2);
01004 } else {
01005 PetscInfo2(0," timing: %s - u2 - took %g s\n",__FUNCT__,t_t3-t_t2);
01006 }
01007
01008
01009
01010
01011
01012 ierr = VecWAXPY(utot,1.0,u1,u2);CHKERRQ(ierr);
01013 ierr = MatMult(Agradu,utot,gdata->VHdem);CHKERRQ(ierr);
01014
01015 #ifdef HDEMAGUEPOL
01016 if (gdata->mode==0 && PetscAbsReal(dt) > 1e-8){
01017 dt=1.0/dt;
01018
01019
01020 ierr = VecCopy(u1,du1dt);CHKERRQ(ierr);
01021 ierr = VecAXPY(du1dt,c_mone,u1bak);CHKERRQ(ierr);
01022 ierr = VecScale(du1dt,dt);CHKERRQ(ierr);
01023 ierr = VecCopy(u1,u1bak);CHKERRQ(ierr);
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033 tubak=gdata->time;
01034 }
01035 #endif
01036
01037
01038 }
01039 else {
01040 PetscInfo2(0,
01041 "Info (t=%g ns): Skipped calculation of u2: %i\n",
01042 gdata->time*gdata->tscale*1e9,
01043 its1
01044 );
01045 }
01046
01047 ierr = VecAXPY(VHtotsum,1.0,gdata->VHdem);CHKERRQ(ierr);
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068 MagparFunctionProfReturn(0);
01069 }
01070
01071
01072 int Hdemag_Energy(GridData *gdata,Vec VMom,PetscReal *energy)
01073 {
01074 PetscReal e;
01075
01076 MagparFunctionInfoBegin;
01077
01078 if (!fieldon) {
01079 *energy=0.0;
01080 MagparFunctionInfoReturn(0);
01081 }
01082
01083 ierr = VecDot(VMom,gdata->VHdem,&e);CHKERRQ(ierr);
01084 e /= -2.0;
01085
01086 *energy=e;
01087
01088 MagparFunctionProfReturn(0);
01089 }
01090