📄 gf_helmholtz.c
字号:
double xxs, yys, zzs, r, phi_r, phi ; double c1, c2, cr, ci, c, s ; double k0r, kr, bjn, byn, sbjn, sbyn, Pl; double P[NBR_MAX_EXP], jsph[NBR_MAX_EXP], ysph[NBR_MAX_EXP]; int ns, Nd, i_FMM, j_FMM ; GetDP_Begin("GF_GradHelmholtz"); if(Current.NbrHar != 2) Msg(GERROR, "Wrong Number of Harmonics in 'GF_GradHelmholtz'"); V->Type = VECTOR ; switch((int)Fct->Para[0]){ case _2D : switch(Current.FMM.Flag_GF){ case FMM_DIRECT: xxs = Current.x-Current.xs ; yys = Current.y-Current.ys ; r = sqrt(SQU(xxs)+SQU(yys)) ; k0r = Fct->Para[1]*r; if (!r) Cal_ZeroValue(V); else { c1 = Fct->Para[1]/4/r ; cr = c1 * y1(k0r); ci = c1 * j1(k0r); V->Val[0] = xxs * cr ; V->Val[MAX_DIM ] = xxs * ci ; V->Val[1] = yys * cr ; V->Val[MAX_DIM+1] = yys * ci ; } break ; case FMM_AGGREGATION : /* SCALAR -> Grad in Disaggregation */ Nd = Current.FMM.NbrDir ; r = sqrt( SQU(Current.xs-Current.FMM.Xgc)+ SQU(Current.ys-Current.FMM.Ygc)) ; phi_r = atan2(Current.ys- Current.FMM.Ygc, Current.xs-Current.FMM.Xgc) ; kr = Fct->Para[1]*r; if (r==0) for (i_FMM = 0 ; i_FMM < Nd ; i_FMM++){ V[i_FMM].Type = SCALAR ; V[i_FMM].Val[0] = 1. ; V[i_FMM].Val[MAX_DIM] = 0. ; } else for (i_FMM = 0 ; i_FMM < Nd ; i_FMM++){ phi = Current.FMM.Phi[i_FMM] ; V[i_FMM].Type = SCALAR ; V[i_FMM].Val[0] = cos(kr*sin(phi+phi_r)) ; V[i_FMM].Val[MAX_DIM] = -sin(kr*sin(phi+phi_r)) ; } break; case FMM_DISAGGREGATION : /* Grad -> VECTOR */ Nd = Current.FMM.NbrDir ; xxs = Current.x - Current.FMM.Xgc ; yys = Current.y - Current.FMM.Ygc ; r = sqrt(SQU(xxs)+SQU(yys)) ; phi_r = atan2(yys, xxs) ; k0r = Fct->Para[1]*r ; for (i_FMM = 0 ; i_FMM < Nd ; i_FMM++){ phi = Current.FMM.Phi[i_FMM]; cr = -Fct->Para[1] * sin(k0r*sin(phi+phi_r)) ; ci = Fct->Para[1] * cos(k0r*sin(phi+phi_r)) ; V[i_FMM].Type = VECTOR ; V[i_FMM].Val[0] = cr*sin(phi) ; V[i_FMM].Val[1] = cr*cos(phi) ; V[i_FMM].Val[MAX_DIM] = ci*sin(phi) ; V[i_FMM].Val[MAX_DIM+1] = ci*cos(phi) ; } break; case FMM_TRANSLATION : Nd = Current.FMM.NbrDir ; ns = (Nd-1)/2 ; cr = 1./4./Nd ; k0r = Fct->Para[1] * sqrt( SQU(Current.x - Current.xs)+ SQU(Current.y - Current.ys)) ; phi_r = atan2(Current.y - Current.ys, Current.x - Current.xs) ; for (i_FMM = 0 ; i_FMM < Nd ; i_FMM++){ phi = Current.FMM.Phi[i_FMM]; V[i_FMM].Type = SCALAR ; V[i_FMM].Val[0] = -cr*yn(0,k0r); V[i_FMM].Val[MAX_DIM] = -cr*jn(0,k0r); for (j_FMM = 1 ; j_FMM <= ns ; j_FMM++){ c = cos(j_FMM*(phi+phi_r-PI)); s = sin(j_FMM*(phi+phi_r-PI)); bjn = jn(j_FMM,k0r); byn = yn(j_FMM,k0r); V[i_FMM].Val[0] += -2.*cr* (j_FMM%2 ? bjn*s : byn*c) ; V[i_FMM].Val[MAX_DIM] += -2.*cr* (j_FMM%2 ? -byn*s : bjn*c) ; } } break; default : Msg(GERROR, "Case 2D: Bad Flag_GF 'GF_GradHelmholtz' (%d)", Current.FMM.Flag_GF); break; } break; case _3D : switch(Current.FMM.Flag_GF){ case FMM_DIRECT : xxs = Current.x-Current.xs ; yys = Current.y-Current.ys ; zzs = Current.z-Current.zs ; r = sqrt(SQU(xxs)+SQU(yys)+SQU(zzs)) ; kr = Fct->Para[1] * r ; if (!r) Cal_ZeroValue(V); else { c1 = - ONE_OVER_FOUR_PI / CUB(r) ; c2 = ONE_OVER_FOUR_PI * Fct->Para[1] / SQU(r) ; cr = c1 * cos(kr) - c2 * sin(kr) ; ci = -c1 * sin(kr) - c2 * cos(kr) ; V->Val[0] = xxs * cr ; V->Val[MAX_DIM ] = xxs * ci ; V->Val[1] = yys * cr ; V->Val[MAX_DIM+1] = yys * ci ; V->Val[2] = zzs * cr ; V->Val[MAX_DIM+2] = zzs * ci ; } break ; case FMM_AGGREGATION : /* 3D GF_GradHelmholtz Grad-> Aggreg == VECTOR */ Nd = Current.FMM.NbrDir ; xxs = Current.xs-Current.FMM.Xgc ; yys = Current.ys-Current.FMM.Ygc ; zzs = Current.zs-Current.FMM.Zgc ; for (i_FMM = 0 ; i_FMM < Nd ; i_FMM++){ kr = Fct->Para[1]*(xxs*Current.FMM.Kdir[i_FMM][0] + yys*Current.FMM.Kdir[i_FMM][1] + zzs*Current.FMM.Kdir[i_FMM][2] ) ; V[i_FMM].Type = VECTOR ; V[i_FMM].Val[0] = - Fct->Para[1] * Current.FMM.Kdir[i_FMM][0]* sin(kr) ; V[i_FMM].Val[1] = - Fct->Para[1] * Current.FMM.Kdir[i_FMM][1]* sin(kr) ; V[i_FMM].Val[2] = - Fct->Para[1] * Current.FMM.Kdir[i_FMM][2]* sin(kr) ; V[i_FMM].Val[MAX_DIM] = - Fct->Para[1] * Current.FMM.Kdir[i_FMM][0]* cos(kr) ; V[i_FMM].Val[MAX_DIM +1] = - Fct->Para[1] * Current.FMM.Kdir[i_FMM][1]* cos(kr) ; V[i_FMM].Val[MAX_DIM +2] = - Fct->Para[1] * Current.FMM.Kdir[i_FMM][2]* cos(kr) ; } break; case FMM_DISAGGREGATION : /*3D GF_GradHelmholtz: Grad in Aggreg -> Disagg == SCALAR */ Nd = Current.FMM.NbrDir ; xxs = Current.x-Current.FMM.Xgc ; yys = Current.y-Current.FMM.Ygc ; zzs = Current.z-Current.FMM.Zgc ; for (i_FMM = 0 ; i_FMM < Nd ; i_FMM++){ kr = Fct->Para[1] * (xxs*Current.FMM.Kdir[i_FMM][0] + yys*Current.FMM.Kdir[i_FMM][1] + zzs*Current.FMM.Kdir[i_FMM][2] ) ; V[i_FMM].Type = SCALAR ; V[i_FMM].Val[0] = cos(kr) ; V[i_FMM].Val[MAX_DIM] = sin(kr) ; } break; case FMM_TRANSLATION: /* 3D GF_GradHelmholtz*/ Nd = Current.FMM.NbrDir ; ns = (int)sqrt((double)Nd/2) ; cr = - Fct->Para[1] * ONE_OVER_FOUR_PI * ns/2/Nd ; /* Remaining factors of GF & Integration */ xxs = -Current.x + Current.xs ; yys = -Current.y + Current.ys ; zzs = -Current.z + Current.zs ; r = sqrt( SQU(xxs) + SQU(yys) + SQU(zzs) ) ; k0r = Fct->Para[1] * r ; Spherical_j_nArray(0, k0r, ns+1, jsph) ; Spherical_y_nArray(0, k0r, ns+1, ysph) ; for (i_FMM = 0 ; i_FMM < Nd ; i_FMM++){ V[i_FMM].Type = SCALAR ; V[i_FMM].Val[0] = V[i_FMM].Val[MAX_DIM] = 0. ; kr = (xxs*Current.FMM.Kdir[i_FMM][0] + yys*Current.FMM.Kdir[i_FMM][1] + zzs*Current.FMM.Kdir[i_FMM][2])/r ; LegendreRecursive( ns, 0, kr, P); for (j_FMM = 0 ; j_FMM <= ns ; j_FMM++){ s = ((j_FMM/2)%2)? -1 : 1 ; sbjn = jsph[j_FMM] ; sbyn = ysph[j_FMM] ; Pl = (2*j_FMM+1) * P[j_FMM] ; V[i_FMM].Val[0] += s * Pl * ((j_FMM%2) ? sbjn : sbyn ) ; V[i_FMM].Val[MAX_DIM] += s * Pl * ((j_FMM%2) ? (-sbyn): sbjn ) ; } V[i_FMM].Val[0] *= cr*Current.FMM.Weight[i_FMM]; V[i_FMM].Val[MAX_DIM] *= cr*Current.FMM.Weight[i_FMM]; } break; default : Msg(GERROR, "Case 3D: Bad Flag_GF 'GF_GradHelmholtz' (%d)", Current.FMM.Flag_GF); break; } break; default : Msg(GERROR, "Bad Parameter for 'GF_GradHelmholtz' (%d)", (int)Fct->Para[0]); break; } GetDP_End ;} /* ------------------------------------------------------------------------ *//* G F _ N P x G r a d H e l m h o l t z *//* ------------------------------------------------------------------------ */void GF_NPxGradHelmholtz (F_ARG) { double nx, ny, nz, N[3] ; struct Value ValGrad ; GetDP_Begin("GF_NPxHelmholtz"); /* Vectorial product N[] /\ Grad G */ if(Current.NbrHar != 2) Msg(GERROR, "Wrong Number of Harmonics in 'GF_NPxGradHelmholtz'"); V->Type = VECTOR ; if (Current.Element->Num == Current.ElementSource->Num) { Cal_ZeroValue(V); return ; } switch((int)Fct->Para[0]){ case _3D : switch(Current.FMM.Flag_GF){ case FMM_DIRECT : Geo_CreateNormal(Current.Element->Type, Current.Element->x,Current.Element->y,Current.Element->z, N); nx = N[0]; ny = N[1]; nz = N[2]; GF_GradHelmholtz(Fct, &ValGrad, &ValGrad) ; V->Val[0] = N[1]*ValGrad.Val[2] - N[2]*ValGrad.Val[1]; V->Val[1] =-N[0]*ValGrad.Val[2] + N[2]*ValGrad.Val[0]; V->Val[2] = N[0]*ValGrad.Val[1] - N[1]*ValGrad.Val[0]; V->Val[MAX_DIM ] = N[1]*ValGrad.Val[MAX_DIM+2] - N[2]*ValGrad.Val[MAX_DIM+1]; V->Val[MAX_DIM+1] =-N[0]*ValGrad.Val[MAX_DIM+2] + N[2]*ValGrad.Val[MAX_DIM]; V->Val[MAX_DIM+2] = N[0]*ValGrad.Val[MAX_DIM+1] - N[1]*ValGrad.Val[MAX_DIM]; break ; default: Msg(GERROR, "Case 3D: Bad Flag_GF 'GF_NPxGradLaplace' (%d)", Current.FMM.Flag_GF); break; } break; default : Msg(GERROR, "Bad Parameter for 'GF_NPxGradHelmholtz' (%d)", (int)Fct->Para[0]); break; } GetDP_End ;}/* ------------------------------------------------------------------------ *//* G F _ N S x G r a d H e l m h o l t z *//* ------------------------------------------------------------------------ */void GF_NSxGradHelmholtz (F_ARG) { double x1x0, x2x0, y1y0, y2y0, z1z0, z2z0, xxs, yys, zzs, r ; double nx, ny, nz, n, c1, c2, cr, ci ; double phi_r, phi ; double c, s, kr, bjn, byn ; int ns, Nd, i_FMM, j_FMM ; GetDP_Begin("GF_NSxGradHelmholtz"); if(Current.NbrHar != 2) Msg(GERROR, "Wrong Number of Harmonics in 'GF_NSxGradHelmholtz'"); V->Type = SCALAR ; switch((int)Fct->Para[0]){ case _2D : switch(Current.FMM.Flag_GF){ case FMM_DIRECT : xxs = Current.x-Current.xs ; yys = Current.y-Current.ys ; r = sqrt(SQU(xxs)+SQU(yys)) ; if(Current.Element->Num == NO_ELEMENT) Current.Element = Current.ElementSource ; ny = - Current.Element->x[1] + Current.Element->x[0] ; nx = Current.Element->y[1] - Current.Element->y[0] ; n = sqrt(SQU(nx)+SQU(ny)) ; nx = nx / n ; ny = ny / n ; if (!r) Cal_ZeroValue(V); else { c1 = Fct->Para[1]/4/r ; cr = c1 * y1(Fct->Para[1]*r); ci = c1 * j1(Fct->Para[1]*r); V->Val[0] = nx * xxs * cr + ny * yys * cr ; V->Val[MAX_DIM ] = nx * xxs * ci + ny * yys * ci ; } break ; case FMM_AGGREGATION : Nd = Current.FMM.NbrDir ; r = sqrt( SQU(Current.xs-Current.FMM.Xgc)+ SQU(Current.ys-Current.FMM.Ygc)) ; phi_r = atan2(Current.ys- Current.FMM.Ygc, Current.xs-Current.FMM.Xgc) ; kr = Fct->Para[1]*r; if (r==0) for (i_FMM = 0 ; i_FMM < Nd ; i_FMM++){ V[i_FMM].Type = SCALAR ; V[i_FMM].Val[0] = 1. ; V[i_FMM].Val[MAX_DIM] = 0. ; } else for (i_FMM = 0 ; i_FMM < Nd ; i_FMM++){ phi = Current.FMM.Phi[i_FMM] ; V[i_FMM].Type = SCALAR ; V[i_FMM].Val[0] = cos(kr*sin(phi+phi_r)) ; V[i_FMM].Val[MAX_DIM] = -sin(kr*sin(phi+phi_r)) ; } break; case FMM_DISAGGREGATION : /* Disaggregation: SCALAR product with Normal */ if(Current.Element->Num == NO_ELEMENT) Current.Element = Current.ElementSource ; ny = - Current.Element->x[1] + Current.Element->x[0] ; nx = Current.Element->y[1] - Current.Element->y[0] ; n = sqrt(SQU(nx)+SQU(ny)) ; nx = nx / n ; ny = ny / n ; Nd = Current.FMM.NbrDir ; xxs = Current.x - Current.FMM.Xgc ; yys = Current.y - Current.FMM.Ygc ; r = sqrt(SQU(xxs)+SQU(yys)) ; phi_r = atan2(yys, xxs) ; kr = Fct->Para[1] * r; for (i_FMM = 0 ; i_FMM < Nd ; i_FMM++){ phi = Current.FMM.Phi[i_FMM]; cr = - Fct->Para[1] * sin(kr*sin(phi+phi_r)) ; ci = Fct->Para[1] * cos(kr*sin(phi+phi_r)) ; V[i_FMM].Type = SCALAR ; V[i_FMM].Val[0] = nx*cr*sin(phi) + ny*cr*cos(phi) ; V[i_FMM].Val[MAX_DIM] = nx*ci*sin(phi) + ny*ci*cos(phi) ; } break; case FMM_TRANSLATION : Nd = Current.FMM.NbrDir ; ns = (Nd-1)/2 ; cr = 1./4./Nd ; kr = Fct->Para[1] * sqrt( SQU(Current.x - Current.xs)+ SQU(Current.y - Current.ys)) ; phi_r = atan2(Current.y - Current.ys, Current.x - Current.xs) ; for (i_FMM = 0 ; i_FMM < Nd ; i_FMM++){ phi = Current.FMM.Phi[i_FMM]; V[i_FMM].Type = SCALAR ; V[i_FMM].Val[0] = -cr*yn(0,kr); V[i_FMM].Val[MAX_DIM] = -cr*jn(0,kr); for (j_FMM = 1 ; j_FMM <= ns ; j_FMM++){ c = cos(j_FMM*(phi+phi_r-PI)); s = sin(j_FMM*(phi+phi_r-PI)); bjn = jn(j_FMM,kr); byn = yn(j_FMM,kr); V[i_FMM].Val[0] += -2.*cr* (j_FMM%2 ? bjn*s : byn*c) ; V[i_FMM].Val[MAX_DIM] += -2.*cr* (j_FMM%2 ? -byn*s : bjn*c) ; } } break; default : Msg(GERROR, "Case 2D: Bad Flag_GF 'GF_NSxGradHelmholtz' (%d)", Current.FMM.Flag_GF); break; } break; case _3D : switch(Current.FMM.Flag_GF){ case FMM_DIRECT : xxs = Current.x-Current.xs ; yys = Current.y-Current.ys ; zzs = Current.z-Current.zs ; r = sqrt(SQU(xxs)+SQU(yys)+SQU(zzs)) ; if (!r) Cal_ZeroValue(V); else { x1x0 = Current.Element->x[1] - Current.Element->x[0] ; y1y0 = Current.Element->y[1] - Current.Element->y[0] ; z1z0 = Current.Element->z[1] - Current.Element->z[0] ; x2x0 = Current.Element->x[2] - Current.Element->x[0] ; y2y0 = Current.Element->y[2] - Current.Element->y[0] ; z2z0 = Current.Element->z[2] - Current.Element->z[0] ; nx = y1y0 * z2z0 - z1z0 * y2y0 ; ny = z1z0 * x2x0 - x1x0 * z2z0 ; nz = x1x0 * y2y0 - y1y0 * x2x0 ; n = sqrt(SQU(nx)+SQU(ny)+SQU(nz)) ; nx = nx/n ; ny = ny/n ; nz = nz/n ; c1 = - ONE_OVER_FOUR_PI / CUB(r) ; c2 = ONE_OVER_FOUR_PI * Fct->Para[1] / SQU(r) ; cr = (c1 * cos(Fct->Para[1]*r) - c2 * sin(Fct->Para[1]*r)) ; ci = (c1 * sin(Fct->Para[1]*r) + c2 * cos(Fct->Para[1]*r)) ; V->Val[0] =nx * xxs * cr + ny * yys * cr + nz * zzs * cr ; V->Val[MAX_DIM ] = nx* xxs * ci + ny * yys * ci + nz * zzs * ci; } break ; default : Msg(GERROR, "Case 3D: Bad Flag_GF 'GF_NSxGradHelmholtz' (%d)", Current.FMM.Flag_GF); break; } break; default : Msg(GERROR, "Bad Parameter for 'GF_NSxGradHelmholtz' (%d)", (int)Fct->Para[0]); break; } GetDP_End ;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -