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: distortmesh.c 2962 2010-02-04 19:50:44Z scholz $\n\n";
00025 static char const Td[] = "$Today: " __FILE__ " " __DATE__ " " __TIME__ " $\n\n";
00026
00027 #include "init.h"
00028
00029 int DistortMesh(GridData *gdata)
00030 {
00031 PetscTruth flg;
00032
00033 MagparFunctionLogBegin;
00034
00035 int rank,size;
00036 ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr);
00037 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
00038
00039 if (rank) {
00040 MagparFunctionLogReturn(0);
00041 }
00042
00043
00044
00045 PetscReal mesh_scale[ND];
00046 int nmax;
00047
00048 nmax=ND;
00049 ierr = PetscOptionsGetRealArray(PETSC_NULL,"-mesh_scale",mesh_scale,&nmax,&flg);CHKERRQ(ierr);
00050 if (flg!=PETSC_TRUE) {
00051
00052 mesh_scale[0]=mesh_scale[1]=mesh_scale[2]=1.0;
00053 PetscPrintf(PETSC_COMM_WORLD,"Option -mesh_scale not found or incorrect number of values given.\nUsing default value '%g,%g,%g'!\n",
00054 mesh_scale[0],mesh_scale[1],mesh_scale[2]
00055 );
00056 }
00057 else if (nmax!=ND) {
00058
00059 SETERRQ1(PETSC_ERR_ARG_CORRUPT,
00060 "Option -mesh_scale has incorrect number of values: %i!\n",
00061 nmax
00062 );
00063 }
00064 else {
00065 PetscPrintf(PETSC_COMM_WORLD,"Scaling mesh: '%g,%g,%g'!\n",
00066 mesh_scale[0],mesh_scale[1],mesh_scale[2]
00067 );
00068 for (int i=0; i<gdata->ln_vert; i++) {
00069 for (int j=0; j<ND; j++) {
00070 gdata->vertxyz[ND*i+j] *= mesh_scale[j];
00071 }
00072 }
00073 }
00074
00075
00076
00077
00078 PetscReal shift[ND];
00079 nmax=ND;
00080 ierr = PetscOptionsGetRealArray(PETSC_NULL,"-shift",shift,&nmax,&flg);CHKERRQ(ierr);
00081 if (flg!=PETSC_TRUE) {
00082
00083 shift[0]=shift[1]=shift[2]=0;
00084 PetscPrintf(PETSC_COMM_WORLD,"Option -shift not found, using default value '%g,%g,%g'!\n",
00085 shift[0],shift[1],shift[2]
00086 );
00087 }
00088 else if (nmax!=ND) {
00089
00090 SETERRQ1(PETSC_ERR_ARG_CORRUPT,
00091 "Option -shift has incorrect number of values: %i!\n",
00092 nmax
00093 );
00094 }
00095 else {
00096 PetscPrintf(PETSC_COMM_WORLD,"Shifting mesh: '%g,%g,%g'!\n",
00097 shift[0],shift[1],shift[2]
00098 );
00099 for (int i=0; i<gdata->ln_vert; i++) {
00100 for (int j=0; j<ND; j++) {
00101 gdata->vertxyz[ND*i+j] += shift[j];
00102 }
00103 }
00104 }
00105
00106
00107
00108
00109 int meshdist;
00110 ierr = PetscOptionsGetInt(PETSC_NULL,"-meshdist",(PetscInt*)&meshdist,&flg);CHKERRQ(ierr);
00111 if (flg!=PETSC_TRUE) {
00112
00113 meshdist=0;
00114 PetscPrintf(PETSC_COMM_WORLD,
00115 "Option -meshdist not found, using default value %i!\n",
00116 meshdist
00117 );
00118 }
00119
00120 PetscPrintf(PETSC_COMM_WORLD,"meshdist: %i\n",meshdist);
00121 if (meshdist==0) {
00122 PetscPrintf(PETSC_COMM_WORLD,"mesh undistorted\n");
00123 MagparFunctionLogReturn(0);
00124 }
00125
00126 PetscReal distpar;
00127 ierr = PetscOptionsGetReal(PETSC_NULL,"-distpar",&distpar,&flg);CHKERRQ(ierr);
00128 if (flg!=PETSC_TRUE) {
00129
00130 distpar=0;
00131 PetscPrintf(PETSC_COMM_WORLD,
00132 "Option -distpar not found, using default value %g!\n",
00133 distpar
00134 );
00135 }
00136
00137
00138
00139
00140
00141 PetscReal elenmax,elenmin;
00142 elenmax=0.0;
00143 elenmin=1.0/D_EPS;
00144
00145 for (int i=0; i<gdata->ln_ele; i++) {
00146
00147 int *t_v;
00148 t_v=gdata->elevert+i*NV;
00149
00150 PetscReal *x1,*x2,*x3,*x4;
00151 x1=gdata->vertxyz+t_v[0]*ND;
00152 x2=gdata->vertxyz+t_v[1]*ND;
00153 x3=gdata->vertxyz+t_v[2]*ND;
00154 x4=gdata->vertxyz+t_v[3]*ND;
00155
00156
00157 PetscReal edge[ND];
00158 my_dcopy(ND,x1,1,edge,1);
00159 my_daxpy(ND,-1.0,x2,1,edge,1);
00160
00161 PetscReal elen;
00162 elen=my_dnrm2(ND,edge,1);
00163 elenmax=PetscMax(elenmax,elen);
00164 elenmin=PetscMin(elenmin,elen);
00165
00166 my_dcopy(ND,x1,1,edge,1);
00167 my_daxpy(ND,-1.0,x3,1,edge,1);
00168 elen=my_dnrm2(ND,edge,1);
00169 elenmax=PetscMax(elenmax,elen);
00170 elenmin=PetscMin(elenmin,elen);
00171
00172 my_dcopy(ND,x1,1,edge,1);
00173 my_daxpy(ND,-1.0,x4,1,edge,1);
00174 elen=my_dnrm2(ND,edge,1);
00175 elenmax=PetscMax(elenmax,elen);
00176 elenmin=PetscMin(elenmin,elen);
00177
00178 my_dcopy(ND,x2,1,edge,1);
00179 my_daxpy(ND,-1.0,x3,1,edge,1);
00180 elen=my_dnrm2(ND,edge,1);
00181 elenmax=PetscMax(elenmax,elen);
00182 elenmin=PetscMin(elenmin,elen);
00183
00184 my_dcopy(ND,x2,1,edge,1);
00185 my_daxpy(ND,-1.0,x4,1,edge,1);
00186 elen=my_dnrm2(ND,edge,1);
00187 elenmax=PetscMax(elenmax,elen);
00188 elenmin=PetscMin(elenmin,elen);
00189
00190 my_dcopy(ND,x3,1,edge,1);
00191 my_daxpy(ND,-1.0,x4,1,edge,1);
00192 elen=my_dnrm2(ND,edge,1);
00193 elenmax=PetscMax(elenmax,elen);
00194 elenmin=PetscMin(elenmin,elen);
00195 }
00196
00197 PetscPrintf(PETSC_COMM_WORLD,"distorting mesh - meshdist: %i distpar: %g elenmin: %g\n",
00198 meshdist,distpar,elenmin
00199 );
00200
00201 PetscRandom rctx;
00202 ierr = PetscRandomCreate(PETSC_COMM_WORLD,&rctx);CHKERRQ(ierr);
00203 ierr = PetscRandomSetFromOptions(rctx);CHKERRQ(ierr);
00204
00205 for (int i=0; i<gdata->ln_vert; i++) {
00206 PetscReal randist[ND];
00207 PetscReal norm;
00208
00209
00210
00211
00212
00213 do {
00214 PetscRandomGetValue(rctx,&randist[0]); randist[0] = randist[0]*2.0-1.0;
00215 PetscRandomGetValue(rctx,&randist[1]); randist[1] = randist[1]*2.0-1.0;
00216 PetscRandomGetValue(rctx,&randist[2]); randist[2] = randist[2]*2.0-1.0;
00217 } while ((norm=my_dnrm2(ND,randist,1)) > 1.0);
00218
00219 switch (meshdist) {
00220 case 1:
00221 if (gdata->vertbndg2bnd[gdata->vertl2g[i]] == C_INT) {
00222 gdata->vertxyz[ND*i+0] += randist[0]/norm*distpar*elenmin;
00223 gdata->vertxyz[ND*i+1] += randist[1]/norm*distpar*elenmin;
00224 gdata->vertxyz[ND*i+2] += randist[2]/norm*distpar*elenmin;
00225 }
00226 break;
00227 case 2:
00228 if (gdata->vertbndg2bnd[gdata->vertl2g[i]] >= 0) {
00229 gdata->vertxyz[ND*i+0] += randist[0]/norm*distpar*elenmin;
00230 gdata->vertxyz[ND*i+1] += randist[1]/norm*distpar*elenmin;
00231 gdata->vertxyz[ND*i+2] += randist[2]/norm*distpar*elenmin;
00232 }
00233 break;
00234 case 3:
00235 gdata->vertxyz[ND*i+0] += randist[0]/norm*distpar*elenmin;
00236 gdata->vertxyz[ND*i+1] += randist[1]/norm*distpar*elenmin;
00237 gdata->vertxyz[ND*i+2] += randist[2]/norm*distpar*elenmin;
00238 break;
00239 }
00240 }
00241 ierr = PetscRandomDestroy(rctx);CHKERRQ(ierr);
00242
00243 MagparFunctionLogReturn(0);
00244 }
00245