00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "field/field.h"
00025 #include "init/init.h"
00026 #include "util/util.h"
00027
00028 int VertBSA(GridData *gdata,Vec vertbsa)
00029 {
00030 MagparFunctionLogBegin;
00031
00032
00033
00034
00035 for (int i=0; i<gdata->ln_ele; i++) {
00036
00037 for (int j=0; j<NV; j++) {
00038 PetscReal t_omega;
00039 ierr = SolidAngle(
00040 gdata->vertxyz+gdata->elevert[NV*i+j]*ND,
00041 gdata->vertxyz+gdata->elevert[NV*i+(j+1+NV)%NV]*ND,
00042 gdata->vertxyz+gdata->elevert[NV*i+(j+2+NV)%NV]*ND,
00043 gdata->vertxyz+gdata->elevert[NV*i+(j+3+NV)%NV]*ND,
00044 &t_omega
00045 );CHKERRQ(ierr);
00046
00047 int v;
00048 v=gdata->elevert[NV*i+j];
00049 ierr = VecSetValue(
00050 vertbsa,
00051 v,
00052 t_omega,
00053 ADD_VALUES);CHKERRQ(ierr);
00054 }
00055 }
00056
00057 ierr = VecAssemblyBegin(vertbsa);CHKERRQ(ierr);
00058 ierr = VecAssemblyEnd(vertbsa);CHKERRQ(ierr);
00059
00060 MagparFunctionLogReturn(0);
00061 }
00062
00063
00064 int BMatrix(GridData *gdata,Mat *Bmat)
00065 {
00066 MagparFunctionLogBegin;
00067
00068 int rank,size;
00069 ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr);
00070 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
00071
00072 PetscPrintf(PETSC_COMM_WORLD,"Using dense boundary matrix\n");
00073
00074 PetscPrintf(PETSC_COMM_WORLD,
00075 "Size of dense B matrix: %i x %i = %g matrix elements = %g MB.\n",
00076 gdata->n_vert_bnd,
00077 gdata->n_vert_bnd,
00078 1.0*gdata->n_vert_bnd*gdata->n_vert_bnd,
00079 (gdata->n_vert_bnd/1024.0*gdata->n_vert_bnd/1024.0*sizeof(PetscReal))
00080 );
00081
00082
00083
00084 int ln_bmatrixrows,rowstart,rowend;
00085 ln_bmatrixrows=gdata->n_vert_bnd/size;
00086 rowstart=rank*(gdata->n_vert_bnd/size);
00087 rowend=rowstart+gdata->n_vert_bnd/size-1;
00088 if ((gdata->n_vert_bnd%size)/(rank+1)>=1) {
00089 ln_bmatrixrows++;
00090 rowstart+=rank;
00091 rowend+=rank+1;
00092 }
00093 else {
00094 rowstart+=gdata->n_vert_bnd%size;
00095 rowend+=gdata->n_vert_bnd%size;
00096 }
00097 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
00098 "<%i>local rows of boundary matrix: %i (from %i to %i)\n",
00099 rank,ln_bmatrixrows,
00100 rowstart,rowend
00101 );
00102 PetscSynchronizedFlush(PETSC_COMM_WORLD);
00103 assert(ln_bmatrixrows==rowend-rowstart+1);
00104
00105 Mat B;
00106
00107 PetscPrintf(PETSC_COMM_WORLD,
00108 "Allocating %i MB of memory for boundary matrix on each processor (total %i MB)\n",
00109 (gdata->n_vert_bnd/1024*gdata->n_vert_bnd/1024*sizeof(PetscReal)+1)/size+1,
00110 (gdata->n_vert_bnd/1024*gdata->n_vert_bnd/1024*sizeof(PetscReal)+2)
00111 );
00112
00113 ierr = MatCreateMPIDense(PETSC_COMM_WORLD,
00114 ln_bmatrixrows,ln_bmatrixrows,
00115 gdata->n_vert_bnd,gdata->n_vert_bnd,
00116 PETSC_NULL,
00117 &B);CHKERRQ(ierr);
00118 ierr = MatSetFromOptions(B);CHKERRQ(ierr);
00119
00120 PetscPrintf(PETSC_COMM_WORLD,"Calculating boundary matrix...\n");
00121
00122 int zeroes=0;
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 int i;
00139 for (i=0; i<gdata->n_vert; i++) {
00140 ierr = ProgressBar(i,gdata->n_vert,10);
00141
00142 if (gdata->vertbndg2bnd[i]==C_INT) continue;
00143
00144
00145
00146 for (int j=0; j<gdata->ln_bnd_fac; j++) {
00147
00148 if (gdata->bndfacvert[j*NN+0]==i ||
00149 gdata->bndfacvert[j*NN+1]==i ||
00150 gdata->bndfacvert[j*NN+2]==i
00151 ) continue;
00152
00153 PetscReal matele[ND];
00154 ierr = Bele(
00155 gdata->vertxyz+ND*i,
00156 gdata->vertxyz+ND*gdata->bndfacvert[j*NN+0],
00157 gdata->vertxyz+ND*gdata->bndfacvert[j*NN+1],
00158 gdata->vertxyz+ND*gdata->bndfacvert[j*NN+2],
00159 matele
00160 );CHKERRQ(ierr);
00161
00162 if (PetscAbsReal(matele[0])+PetscAbsReal(matele[1])+PetscAbsReal(matele[2])<D_EPS)
00163 continue;
00164
00165 for (int k=0;k<NN;k++) {
00166
00167 ierr = MatSetValue(B,
00168 gdata->vertbndg2bnd[i],
00169 gdata->vertbndg2bnd[gdata->bndfacvert[j*NN+k]],
00170 matele[k],
00171 ADD_VALUES);CHKERRQ(ierr);
00172 }
00173 }
00174
00175
00176 if (i % 100 == 99) {
00177 ierr = MatAssemblyBegin(B,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr);
00178 ierr = MatAssemblyEnd(B,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr);
00179 }
00180
00181 }
00182 ierr = ProgressBar(1,1,10);
00183
00184 if (size>1) {
00185 ierr = PetscGetTime(&t_t2);CHKERRQ(ierr);
00186 PetscPrintf(PETSC_COMM_WORLD,"<%i> took %g s\n",rank,t_t2-t_t1);
00187 PetscPrintf(PETSC_COMM_WORLD,"waiting for other processors to complete...");
00188 }
00189
00190
00191 for (;i<gdata->n_vert;i++) {
00192 if (i % 100 == 99) {
00193 ierr = MatAssemblyBegin(B,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr);
00194 ierr = MatAssemblyEnd(B,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr);
00195 }
00196 }
00197
00198
00199 int tzeroes=0;
00200 ierr=MPI_Allreduce((int*)&zeroes,(int*)&tzeroes,1,MPI_INT,MPI_SUM,PETSC_COMM_WORLD);CHKERRQ(ierr);
00201 PetscInfo3(0,
00202 "total zero entries: %i (%i) of %i\n",
00203 (tzeroes+gdata->n_vert_bnd)/3,
00204 tzeroes,
00205 gdata->n_vert_bnd*gdata->n_vert_bnd
00206 );
00207
00208 ierr = PetscGetTime(&t_t2);CHKERRQ(ierr);
00209 PetscPrintf(PETSC_COMM_WORLD,
00210 "boundary matrix calculation took %g s = %g min\n",
00211 t_t2-t_t1,
00212 (t_t2-t_t1)/60.0
00213 );
00214
00215
00216
00217 Vec vertbsa;
00218 ierr = VecCreate(PETSC_COMM_WORLD,&vertbsa);CHKERRQ(ierr);
00219 ierr = VecSetSizes(vertbsa,gdata->ln_vert,gdata->n_vert);CHKERRQ(ierr);
00220 ierr = VecSetFromOptions(vertbsa);CHKERRQ(ierr);
00221
00222 ierr = VertBSA(gdata,vertbsa);CHKERRQ(ierr);
00223
00224 PetscReal *t_array;
00225 ierr = VecGetArray(vertbsa,&t_array);CHKERRQ(ierr);
00226
00227 for (i=0; i<gdata->ln_vert; i++) {
00228
00229
00230 if (gdata->vertbndg2bnd[gdata->vertl2g[i]]==C_INT) continue;
00231
00232 PetscReal matele;
00233 matele=t_array[i]/(4.0*PETSC_PI)-1.0;
00234 ierr = MatSetValue(B,
00235 gdata->vertbndg2bnd[gdata->vertl2g[i]],
00236 gdata->vertbndg2bnd[gdata->vertl2g[i]],
00237 matele,
00238 ADD_VALUES);CHKERRQ(ierr);
00239 }
00240
00241 ierr = VecRestoreArray(vertbsa,&t_array);CHKERRQ(ierr);
00242 ierr = VecDestroy(vertbsa);CHKERRQ(ierr);
00243
00244 PetscPrintf(PETSC_COMM_WORLD,"B matrix assembly complete\n");
00245 ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
00246 ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
00247 ierr = PrintMatInfoAll(B);CHKERRQ(ierr);
00248
00249
00250 ierr = MatScale(B,-1.0);CHKERRQ(ierr);
00251
00252 *Bmat=B;
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273 ierr = PetscGetTime(&t_t2);CHKERRQ(ierr);
00274
00275 MagparFunctionLogReturn(0);
00276 }
00277