Skip to content
Snippets Groups Projects
Commit 7dbd7f7c authored by Axel Modave's avatar Axel Modave
Browse files

add model HelmholtzDDMwithCrosspoints

parent 22c99dec
No related branches found
No related tags found
No related merge requests found
Pipeline #5764 passed
Showing
with 48961 additions and 0 deletions
File added
A non-overlapping HABC-based domain decomposition method with cross-point treatment for 2D Helmholtz problems.
A. Modave, A. Royer, X. Antoine, X. Geuzaine. An optimized Schwarz domain decomposition method with cross-point treatment for time-harmonic acoustic scattering. https://hal.archives-ouvertes.fr/hal-02432422
Model developed by Axel Modave, based on GetDDM codes.
Quick start
-----------
Open `main.pro' with Gmsh.
\ No newline at end of file
BC_Dir = 1;
BC_Neu = 2;
DefineConstant[
BC_SCATT = {BC_Dir, Highlight "Blue",
Choices {BC_Dir = "Sound-soft scat. (Dirichlet BC)",
BC_Neu = "Sound-hard scat. (Neumann BC)"},
Name "Input/01Type of solution"},
// Geometry
R_INT = {1, Min 0.01, Step 0.01, Name "Input/1Model/40Internal radius"},
R_EXT = {4, Min 0.01, Step 0.01, Name "Input/1Model/41External radius"},
// Subdomains
Npie_DOM = {5, Min 3, Max 20, Step 1, Name "Input/1Model/50Number of azimutal divisions"},
Nlay_DOM = {3, Min 3, Max 20, Step 1, Name "Input/1Model/51Number of radial divisions"},
THETA_INC = {0, Min 0., Max 2*Pi, Step 0.1, Name "Input/1Model/52Rotation of pie"},
TWIST = {0, Min 0, Max 0.3, Step 0.1, Name "Input/1Model/52 TWIST"},
// Frequency
WAVENUMBER = {4*Pi, Min 1, Max 24, Step 1, Name "Input/03Wavenumber"},
N_LAMBDA = {10, Min 5, Max 30, Step 1, Name "Input/04Points per wavelength"}
];
LAMBDA = (2*Pi)/WAVENUMBER;
FREQ = WAVENUMBER/(2*Pi);
LC = LAMBDA/N_LAMBDA;
N_DOM = Npie_DOM*Nlay_DOM;
R_SCA = R_INT;
For iDom In {0:N_DOM-1}
TAG_DOM~{iDom} = 1000 + iDom;
For iEdge In {0:3}
TAG_BND~{iDom}~{iEdge} = 2000 + 4*iDom + iEdge;
EndFor
For iCorner In {0:3}
TAG_CRN~{iDom}~{iCorner} = 3000 + 4*iDom + iCorner;
EndFor
EndFor
Include "circularDom.dat";
Mesh.CharacteristicLengthMin = LC;
Mesh.CharacteristicLengthMax = LC;
// =================================================================================================
// Build POINTS, RADIAL LINES, CIRCULAR LINES and SURFACES
// =================================================================================================
If(Npie_DOM == 1)
// Circular lines
pCenter = newp;
Point(pCenter) = {0,0,0};
For iLay In {0:Nlay_DOM}
radius = R_INT + iLay * (R_EXT-R_INT)/Nlay_DOM;
p~{iLay}~{0} = newp;
Point(p~{iLay}~{0}) = { radius, 0, 0};
p~{iLay}~{1} = newp;
Point(p~{iLay}~{1}) = {-radius, 0, 0};
l_curve~{iLay}~{0} = newl;
Circle(l_curve~{iLay}~{0}) = {p~{iLay}~{0}, pCenter, p~{iLay}~{1}};
l_curve~{iLay}~{1} = newl;
Circle(l_curve~{iLay}~{1}) = {p~{iLay}~{1}, pCenter, p~{iLay}~{0}};
EndFor
// Surfaces
For iLay In {0:Nlay_DOM-1}
ll = newll;
Line Loop(ll) = {l_curve~{iLay+1}~{0}, l_curve~{iLay+1}~{1}, -l_curve~{iLay}~{0}, -l_curve~{iLay}~{1} };
omega~{iLay}~{0} = news;
Plane Surface(omega~{iLay}~{0}) = {ll};
EndFor
Else
// Points
radiusTwist~{0} = -TWIST;
radiusTwist~{1} = TWIST;
radiusTwist~{2} = -TWIST;
radiusTwist~{3} = TWIST;
radiusTwist~{4} = -TWIST;
radiusTwist~{5} = TWIST;
radiusTwist~{6} = -TWIST;
radiusTwist~{7} = TWIST;
pCenter = newp;
Point(pCenter) = {0,0,0};
For iPie In {0:Npie_DOM-1}
For iLay In {0:Nlay_DOM}
theta = iPie * (2*Pi/Npie_DOM) - THETA_INC + radiusTwist~{iLay};
radius = R_INT + iLay * (R_EXT-R_INT)/Nlay_DOM;
p~{iLay}~{iPie} = newp;
Point(p~{iLay}~{iPie}) = {radius*Cos(theta), radius*Sin(theta), 0};
EndFor
EndFor
// Radial lines
For iPie In {0:Npie_DOM-1}
For iLay In {0:Nlay_DOM-1}
l_straight~{iLay}~{iPie} = newl;
Line(l_straight~{iLay}~{iPie}) = {p~{iLay}~{iPie}, p~{iLay+1}~{iPie}};
EndFor
EndFor
// Circular lines
For iPie In {0:Npie_DOM-1}
For iLay In {0:Nlay_DOM}
iPieNext = (iPie+1)%Npie_DOM;
l_curve~{iLay}~{iPie} = newl;
Circle(l_curve~{iLay}~{iPie}) = {p~{iLay}~{iPie}, pCenter, p~{iLay}~{iPieNext}};
EndFor
EndFor
// Surfaces
For iPie In {0:Npie_DOM-1}
For iLay In {0:Nlay_DOM-1}
iPieNext = (iPie+1)%Npie_DOM;
ll = newll;
Line Loop(ll) = { l_straight~{iLay}~{iPie}, l_curve~{iLay+1}~{iPie},
-l_straight~{iLay}~{iPieNext}, -l_curve~{iLay }~{iPie} };
omega~{iLay}~{iPie} = news;
Plane Surface(omega~{iLay}~{iPie}) = {ll};
EndFor
EndFor
EndIf
// =================================================================================================
// Generate MESH for each subdomain and reference domain
// =================================================================================================
// Mesh
If(StrCmp(OnelabAction, "check")) // only mesh if not in onelab check mode
Mesh 2;
EndIf
For iPie In {0:Npie_DOM-1}
For iLay In {0:Nlay_DOM-1}
iDom = iLay + Nlay_DOM*iPie;
iPieNext = (iPie+1)%Npie_DOM;
Delete Physicals;
If(Npie_DOM == 1)
Physical Line(TAG_BND~{iDom}~{1}) = { l_curve~{iLay+1}~{0}, l_curve~{iLay+1}~{1} }; // Up
Physical Line(TAG_BND~{iDom}~{3}) = { l_curve~{iLay }~{0}, l_curve~{iLay }~{1} }; // Down
Else
Physical Point(TAG_CRN~{iDom}~{0}) = { p~{iLay}~{iPie} };
Physical Point(TAG_CRN~{iDom}~{1}) = { p~{iLay+1}~{iPie} };
Physical Point(TAG_CRN~{iDom}~{2}) = { p~{iLay+1}~{iPieNext} };
Physical Point(TAG_CRN~{iDom}~{3}) = { p~{iLay}~{iPieNext} };
Physical Line(TAG_BND~{iDom}~{0}) = { l_straight~{iLay}~{iPie} }; // Right
Physical Line(TAG_BND~{iDom}~{1}) = { l_curve~{iLay+1}~{iPie} }; // Up
Physical Line(TAG_BND~{iDom}~{2}) = {-l_straight~{iLay}~{iPieNext} }; // Left
Physical Line(TAG_BND~{iDom}~{3}) = { l_curve~{iLay }~{iPie} }; // Down
EndIf
Physical Surface(TAG_DOM~{iDom}) = omega~{iLay}~{iPie};
Printf("Saving subdomain %g...", iDom);
Save StrCat(MSH_NAME, Sprintf("_%g.msh", iDom));
Printf("Done.");
EndFor
EndFor
Delete Physicals;
For iPie In {0:Npie_DOM-1}
For iLay In {0:Nlay_DOM-1}
iDom = iLay + Nlay_DOM*iPie;
iPieNext = (iPie+1)%Npie_DOM;
If(Npie_DOM == 1)
If(iLay == 0)
Physical Line(TAG_BND~{iDom}~{3}) = { l_curve~{iLay }~{0}, l_curve~{iLay }~{1} }; // Down
EndIf
If(iLay == Nlay_DOM-1)
Physical Line(TAG_BND~{iDom}~{1}) = { l_curve~{iLay+1}~{0}, l_curve~{iLay+1}~{1} }; // Up
EndIf
Else
If(iLay == 0)
Physical Line(TAG_BND~{iDom}~{3}) = { l_curve~{iLay }~{iPie} }; // Down
EndIf
If(iLay == Nlay_DOM-1)
Physical Line(TAG_BND~{iDom}~{1}) = { l_curve~{iLay+1}~{iPie} }; // Up
EndIf
EndIf
Physical Surface(TAG_DOM~{iDom}) = omega~{iLay}~{iPie};
EndFor
EndFor
Printf("Saving domain");
Save StrCat(MSH_NAME, Sprintf(".msh"));
Printf("Done.");
Include "circularDom.dat";
// ====================================================================================================
// FUNCTIONS
// ====================================================================================================
Function{
R[] = Sqrt[X[]*X[]+Y[]*Y[]];
f_inc[] = Complex[Cos[WAVENUMBER*X[]], Sin[WAVENUMBER*X[]]];
dfdx_inc[] = WAVENUMBER * Complex[-Sin[WAVENUMBER*X[]], Cos[WAVENUMBER*X[]]];
// Dirichlet
If(BC_SCATT == BC_Dir)
f_ref[] = AcousticFieldSoftCylinder[XYZ[]]{WAVENUMBER, R_SCA};
f_dir[] = -f_inc[];
EndIf
// Neumann
If(BC_SCATT == BC_Neu)
f_ref[] = AcousticFieldHardCylinder[XYZ[]]{WAVENUMBER, R_SCA, 0, 0, 50};
f_neu[] = dfdx_inc[] * (X[]/R[]);
EndIf
}
// ====================================================================================================
// LISTS ABC/TBC
// ====================================================================================================
// Is there an ABC for main domain? (1=yes, 0=no)
isEdgeABC~{0} = 1;
isEdgeABC~{1} = 1;
isEdgeABC~{2} = 1;
isEdgeABC~{3} = 1;
isEdgeRad~{0} = 1;
isEdgeRad~{1} = 1;
isEdgeRad~{2} = 1;
isEdgeRad~{3} = 1;
ListOfSubdom = {};
For iPie In {0:Npie_DOM-1}
For iLay In {0:Nlay_DOM-1}
iDom = iLay + Nlay_DOM*iPie;
If (iDom % MPI_Size == MPI_Rank)
ListOfSubdom += iDom;
EndIf
iPiePrev = (iPie+Npie_DOM-1)%Npie_DOM;
iPieNext = (iPie+1)%Npie_DOM;
iDomNeigh~{iDom}~{0} = iLay + Nlay_DOM*iPiePrev; // Right
iDomNeigh~{iDom}~{1} = (iLay+1) + Nlay_DOM*iPie; // Top
iDomNeigh~{iDom}~{2} = iLay + Nlay_DOM*iPieNext; // Left
iDomNeigh~{iDom}~{3} = (iLay-1) + Nlay_DOM*iPie; // Down
iEdgeNeigh~{iDom}~{0} = 2;
iEdgeNeigh~{iDom}~{1} = 3;
iEdgeNeigh~{iDom}~{2} = 0;
iEdgeNeigh~{iDom}~{3} = 1;
isEdgeRad~{iDom}~{0} = 0;
isEdgeRad~{iDom}~{1} = 1;
isEdgeRad~{iDom}~{2} = 0;
isEdgeRad~{iDom}~{3} = 1;
// Is there an ABC or TBC? (1=yes, 0=no)
For iEdge In {0:3}
isEdgeABC~{iDom}~{iEdge} = 0;
isEdgeTBC~{iDom}~{iEdge} = 1;
EndFor
If(iLay == 0)
isEdgeTBC~{iDom}~{3} = 0;
EndIf
If(iLay == Nlay_DOM-1)
isEdgeABC~{iDom}~{1} = 1;
isEdgeTBC~{iDom}~{1} = 0;
isEdgeRad~{iDom}~{1} = isEdgeRad~{1};
EndIf
If(Npie_DOM == 1)
isEdgeTBC~{iDom}~{0} = 0;
isEdgeTBC~{iDom}~{2} = 0;
EndIf
// List of Edges for Absorbing/Transmission Boundary Condition
ListOfEdgesWithABC~{iDom} = {};
ListOfEdgesWithTBC~{iDom} = {};
For iEdge In {0:3}
If(isEdgeABC~{iDom}~{iEdge} == 1)
ListOfEdgesWithABC~{iDom} += iEdge;
EndIf
If(isEdgeTBC~{iDom}~{iEdge} == 1)
ListOfEdgesWithTBC~{iDom} += iEdge;
EndIf
EndFor
EndFor
EndFor
// ====================================================================================================
// GROUPS
// ====================================================================================================
Group {
// === REFERENCE CASE ===
Omega = Region[{}];
GammaD = Region[{}];
GammaD0 = Region[{}];
GammaN = Region[{}];
GammaN0 = Region[{}];
GammaPoint = Region[{}];
For iEdge In {0:3}
SigmaMain~{iEdge} = Region[{}];
SigmaMainSides~{iEdge} = Region[{}];
SigmaMainSide~{iEdge}~{0} = Region[{}];
SigmaMainSide~{iEdge}~{1} = Region[{}];
EndFor
For iCorner In {0:3}
CornerMain~{iCorner} = Region[{}];
EndFor
For iPie In {0:Npie_DOM-1}
For iLay In {0:Nlay_DOM-1}
iDom = iLay + Nlay_DOM*iPie;
// DOMAIN
Omega += Region[TAG_DOM~{iDom}];
// BOUNDARY (Dirichlet/Neumann BC)
If(iLay == 0)
If(BC_SCATT == BC_Dir)
GammaD += Region[TAG_BND~{iDom}~{3}];
EndIf
If(BC_SCATT == BC_Neu)
GammaN += Region[TAG_BND~{iDom}~{3}];
EndIf
EndIf
// BOUNDARY (Absorbing BC)
If(iLay == Nlay_DOM-1)
SigmaMain~{1} += Region[{TAG_BND~{iDom}~{1}}];
EndIf
EndFor
EndFor
SigmaMain = Region[{ SigmaMain~{0}, SigmaMain~{1}, SigmaMain~{2}, SigmaMain~{3} }];
CornerMain = Region[{ CornerMain~{0}, CornerMain~{1}, CornerMain~{2}, CornerMain~{3} }];
// === DDM CASE ===
For iPie In {0:Npie_DOM-1}
For iLay In {0:Nlay_DOM-1}
iDom = iLay + Nlay_DOM*iPie;
// DOMAIN
Omega~{iDom} = Region[TAG_DOM~{iDom}];
// SOURCE
GammaPoint~{iDom} = Region[{}];
// BOUNDARY (Dirichlet/Neumann BC)
GammaD0~{iDom} = Region[{}];
GammaN0~{iDom} = Region[{}];
GammaD~{iDom} = Region[{}];
GammaN~{iDom} = Region[{}];
If(iLay == 0)
If(BC_SCATT == BC_Dir)
GammaD~{iDom} = Region[ TAG_BND~{iDom}~{3} ]; // Down
EndIf
If(BC_SCATT == BC_Neu)
GammaN~{iDom} = Region[ TAG_BND~{iDom}~{3} ]; // Down
EndIf
EndIf
// BOUNDARY (Absorbing BC + Transmission BC)
For iEdge In {0:3}
Sigma~{iDom}~{iEdge} = Region[{}];
SigmaSide~{iDom}~{iEdge}~{0} = Region[{}];
SigmaSide~{iDom}~{iEdge}~{1} = Region[{}];
GammaD~{iDom}~{iEdge} = Region[{}];
GammaD0~{iDom}~{iEdge} = Region[{}];
GammaN~{iDom}~{iEdge} = Region[{}];
GammaN0~{iDom}~{iEdge} = Region[{}];
If((isEdgeABC~{iDom}~{iEdge} == 1) || (isEdgeTBC~{iDom}~{iEdge} == 1))
iCornerSide~{0} = iEdge;
iCornerSide~{1} = (iEdge+1)%4;
iEdgeSide~{0} = (iEdge+3)%4;
iEdgeSide~{1} = (iEdge+1)%4;
Sigma~{iDom}~{iEdge} = Region[{TAG_BND~{iDom}~{iEdge}}];
SigmaSide~{iDom}~{iEdge}~{0} = Region[{TAG_CRN~{iDom}~{iCornerSide~{0}}}];
SigmaSide~{iDom}~{iEdge}~{1} = Region[{TAG_CRN~{iDom}~{iCornerSide~{1}}}];
For iSide In {0:1}
If((isEdgeABC~{iDom}~{iEdgeSide~{iSide}} == 0) && (isEdgeTBC~{iDom}~{iEdgeSide~{iSide}} == 0))
If(BC_SCATT == BC_Dir)
GammaD~{iDom}~{iEdge} = Region[{TAG_CRN~{iDom}~{iCornerSide~{iSide}}}];
EndIf
If(BC_SCATT == BC_Neu)
GammaN~{iDom}~{iEdge} = Region[{TAG_CRN~{iDom}~{iCornerSide~{iSide}}}];
EndIf
EndIf
EndFor
EndIf
EndFor
Sigma~{iDom} = Region[{ Sigma~{iDom}~{0}, Sigma~{iDom}~{1}, Sigma~{iDom}~{2}, Sigma~{iDom}~{3} }];
// CORNER (Absorbing BC + Transmission BC)
For iCorner In {0:3}
Corner~{iDom}~{iCorner} = Region[{TAG_CRN~{iDom}~{iCorner}}];
EndFor
Corner~{iDom} = Region[{ Corner~{iDom}~{0}, Corner~{iDom}~{1}, Corner~{iDom}~{2}, Corner~{iDom}~{3} }];
EndFor
EndFor
}
This diff is collapsed.
DefineConstant[
MSH_BASE_NAME = "mesh",
DIR = "out/"
];
MSH_NAME = StrCat(DIR, MSH_BASE_NAME);
// =================================================================================================
// SPECIFIC PROBLEM
// =================================================================================================
PBM_SCATT_CIRC = 1;
PBM_SCATT_RECT = 2;
PBM_MARMOUSI = 3;
DefineConstant[
FLAG_PBM = {PBM_SCATT_RECT, Name "Input/01Benchmark", Highlight "Blue",
GmshOption "Reset", Autocheck 0,
Choices {PBM_SCATT_CIRC = "Scattering in circular domain",
PBM_SCATT_RECT = "Scattering in rectangular domain",
PBM_MARMOUSI = "Benchmark Marmousi"} }
];
If (FLAG_PBM == PBM_SCATT_CIRC)
LinkGeo = "circularDom.geo";
LinkPro = "circularDom.pro";
EndIf
If ((FLAG_PBM == PBM_SCATT_RECT) || (FLAG_PBM == PBM_MARMOUSI))
LinkGeo = "rectangularDom.geo";
LinkPro = "rectangularDom.pro";
EndIf
LinkDDM = "ddmHelmholtzCrossPoints.pro";
ERROR_NO = 0;
ERROR_ANA = 1;
ERROR_NUM = 2;
DefineConstant[
FLAG_ERROR = {ERROR_NUM, Name "Input/02Error", Autocheck 1,
Choices {ERROR_NO = "No",
ERROR_ANA = "... vs analytic reference",
ERROR_NUM = "... vs numerical reference"} },
ORDER = {1,
Name "Input/05Polynomial order",
Choices {1 = "First-order", 2 = "Second-order"}}
];
Include "main.dat" ;
CreateDir Str(DIR);
Solver.AutoMesh = -1;
SetOrder ORDER;
Mesh.ElementOrder = ORDER;
Mesh.SecondOrderLinear = 0;
Include Str[LinkGeo];
Include "main.dat" ;
// =================================================================================================
// GENERAL OPTIONS
// =================================================================================================
DefineConstant[
SOLVER = {"gmres", Choices {"gmres", "fgmres", "bcgs", "print", "jacobi"},
Name "Iterative Solver/0Solver"},
TOLlog10 = {-6, Max -1, Min -16, Step -1,
Name "Iterative Solver/1Tolerance (log10)"},
TOL = 10^(TOLlog10),
MAXIT = {500, Min 1, Step 1, Max 100000,
Name "Iterative Solver/2Max. iterations"},
RESTART_MAXIT = {0, Choices {0,1}, Visible 0,
Name "Iterative Solver/31Force Restart = Max. iterations"},
RESTART = {RESTART_MAXIT ? MAXIT : MAXIT, Min 0, Max 100000, Step 1, Visible 0,
Name "Iterative Solver/30Restart", ReadOnly RESTART_MAXIT }
];
If(RESTART > MAXIT || RESTART == 0)
RESTART = MAXIT;
EndIf
// =================================================================================================
// JACOBIAN & INTEGRATION
// =================================================================================================
Jacobian {
{ Name JVol; Case {{ Region All; Jacobian Vol; }}}
{ Name JSur; Case {{ Region All; Jacobian Sur; }}}
{ Name JLin; Case {{ Region All; Jacobian Lin; }}}
}
If (ORDER==1)
NumGaussPointsPNT = 1;
NumGaussPointsLIN = 4; // NumberOfPoints
NumGaussPointsTRI = 6; // NumberOfPoints
EndIf
If (ORDER==2)
NumGaussPointsPNT = 1;
NumGaussPointsLIN = 6; // NumberOfPoints
NumGaussPointsTRI = 12; // NumberOfPoints
EndIf
Integration {
{ Name I1;
Case {
{ Type Gauss;
Case {
{ GeoElement Point; NumberOfPoints NumGaussPointsPNT; }
{ GeoElement Line; NumberOfPoints NumGaussPointsLIN; }
{ GeoElement Line2; NumberOfPoints NumGaussPointsLIN; }
{ GeoElement Triangle; NumberOfPoints NumGaussPointsTRI; }
{ GeoElement Triangle2; NumberOfPoints NumGaussPointsTRI; } // 1 3 4 6 7 12 13 16
{ GeoElement Quadrangle; NumberOfPoints 7; }
}
}
}
}
}
// =================================================================================================
// SPECIFIC
// =================================================================================================
Include Str[LinkPro];
Include Str[LinkDDM];
// =================================================================================================
// Geometry: Scattering case
If(FLAG_PBM == PBM_SCATT_RECT)
// Subdomains
DefineConstant[
Lx = {7.5, Min 0.01, Max 20, Step 0.01, Name "Input/1Model/40Domain length (Lx)"},
Ly = {7.5, Min 0.01, Max 20, Step 0.01, Name "Input/1Model/41Domain length (Ly)"},
X_SCA = { 1.25, Min -10, Max 10, Step 0.01, Name "Input/1Model/42Scatterer position (x)"},
Y_SCA = { 1.25, Min -10, Max 10, Step 0.01, Name "Input/1Model/43Scatterer position (y)"},
R_SCA = { 1., Min 0.01, Max 20, Step 0.01, Name "Input/1Model/44Scatterer radius"},
Nx_DOM = {3, Min 1, Max 10, Step 1, Name "Input/1Model/50Nx subdomains"},
Ny_DOM = {3, Min 1, Max 10, Step 1, Name "Input/1Model/51Ny subdomains"},
TWIST = {0, Min 0, Max 1.5, Step 0.5, Name "Input/1Model/52 TWIST"}
];
X0_DOM = -X_SCA;
Y0_DOM = -Y_SCA;
// X0_DOM = -Lx/Nx_DOM/2.;
// Y0_DOM = -Ly/Ny_DOM/2.;
DefineConstant[
// LAMBDA = {0.5, Min 0.1, Max 30, Step 0.1, Name "Input/03Wavelength"},
WAVENUMBER = {4*Pi, Min 1, Max 24, Step 1, Name "Input/03Wavenumber"},
N_LAMBDA = {10, Min 5, Max 30, Step 1, Name "Input/04Points per wavelength"}
];
//WAVENUMBER = (2*Pi)/LAMBDA;
LAMBDA = (2*Pi)/WAVENUMBER;
FREQ = WAVENUMBER/(2*Pi);
LC = LAMBDA/N_LAMBDA;
EndIf
// =================================================================================================
// Geometry: Marmousi case
If(FLAG_PBM == PBM_MARMOUSI)
// Subdomains
DefineConstant[
Nx_DOM = {15, Min 1, Max 10, Step 1, Name "Input/1Model/50Nx subdomains"},
Ny_DOM = {4, Min 1, Max 10, Step 1, Name "Input/1Model/51Ny subdomains"}
];
TWIST = 0;
Lx = 9192.;
Ly = 2904.;
X0_DOM = 0.;
Y0_DOM = -Ly;
R_SCA = 1000;
X_SOU = 4585.;
Y_SOU = -10.;
Lx_SDOM = Lx/Nx_DOM;
Ly_SDOM = Ly/Ny_DOM;
I_SOU = Ceil[(X_SOU-X0_DOM)/Lx_SDOM]-1;
J_SOU = Ceil[(Y_SOU-Y0_DOM)/Ly_SDOM]-1;
Idom_SOU = J_SOU*Nx_DOM + I_SOU;
//Printf("I_SOU: %g",I_SOU);
//Printf("J_SOU: %g",J_SOU);
//Printf("Idom_SOU: %g",Idom_SOU);
DefineConstant[
FREQ = {10, Min 0.1, Max 30, Step 0.1, Name "Input/03Frequency"}, //10
N_LAMBDA = {5, Name "Input/04Points per wavelength"} //10
];
// meshing for shortest wavelength
cMin = 1500.;
WAVENUMBER = 2*Pi*FREQ/cMin;
LAMBDA = 2*Pi/WAVENUMBER ;
LC = LAMBDA/N_LAMBDA;
EndIf
// =================================================================================================
N_DOM = Nx_DOM*Ny_DOM;
// =================================================================================================
If(FLAG_PBM == PBM_SCATT_RECT)
TAG_SCA = 1000;
EndIf
If(FLAG_PBM == PBM_MARMOUSI)
TAG_SOU = 1000;
EndIf
For iDom In {0:N_DOM-1}
TAG_DOM~{iDom} = 2000 + iDom;
For iEdge In {0:3}
TAG_BND~{iDom}~{iEdge} = 3000 + 4*iDom + iEdge;
EndFor
For iCorner In {0:3}
TAG_CRN~{iDom}~{iCorner} = 4000 + 4*iDom + iCorner;
EndFor
EndFor
Include "rectangularDom.dat";
Mesh.CharacteristicLengthMin = LC;
Mesh.CharacteristicLengthMax = LC;
// =================================================================================================
// Build SCATTERER or SOURCE
// =================================================================================================
If(FLAG_PBM == PBM_SCATT_RECT)
p0 = newp; Point(p0) = { 0, 0, 0};
p1 = newp; Point(p1) = { R_SCA, 0, 0};
p2 = newp; Point(p2) = { 0, R_SCA, 0};
p3 = newp; Point(p3) = {-R_SCA, 0, 0};
p4 = newp; Point(p4) = { 0,-R_SCA, 0};
c1 = newl; Circle(c1) = {p1, p0, p2};
c2 = newl; Circle(c2) = {p2, p0, p3};
c3 = newl; Circle(c3) = {p3, p0, p4};
c4 = newl; Circle(c4) = {p4, p0, p1};
llSca = newll; Line loop(llSca) = {-c1, -c2, -c3, -c4};
EndIf
If(FLAG_PBM == PBM_MARMOUSI)
p0 = newp; Point(p0) = {X_SOU, Y_SOU, 0};
Physical Point(TAG_SOU) = p0;
EndIf
// =================================================================================================
// Build POINTS, STRAIGHT LINES, RECTANGLES
// =================================================================================================
For i In {0:Nx_DOM}
For j In {0:Ny_DOM}
p~{i}~{j} = newp;
If((i == 1) && (j == 1))
xAdd = TWIST;
yAdd = 0;
ElseIf((i == 1) && (j == 2))
xAdd = 0;
yAdd = TWIST;
ElseIf((i == 2) && (j == 2))
xAdd = -TWIST;
yAdd = 0;
ElseIf((i == 2) && (j == 1))
xAdd = 0;
yAdd = -TWIST;
Else
xAdd = 0;
yAdd = 0;
EndIf
Point(p~{i}~{j}) = {X0_DOM + Lx*i/Nx_DOM + xAdd, Y0_DOM + Ly*j/Ny_DOM + yAdd, 0};
EndFor
EndFor
For i In {0:Nx_DOM}
For j In {0:Ny_DOM}
If (i < Nx_DOM)
lx~{i}~{j} = newl;
Line(lx~{i}~{j}) = {p~{i}~{j}, p~{i+1}~{j}};
EndIf
If (j < Ny_DOM)
ly~{i}~{j} = newl;
Line(ly~{i}~{j}) = {p~{i}~{j}, p~{i}~{j+1}};
EndIf
EndFor
EndFor
For i In {0:Nx_DOM-1}
For j In {0:Ny_DOM-1}
ll~{i}~{j} = newll;
Line loop(ll~{i}~{j}) = {lx~{i}~{j}, ly~{i+1}~{j}, -lx~{i}~{j+1}, -ly~{i}~{j}};
s~{i}~{j} = news;
If ((i == 0) && (j == 0) && (FLAG_PBM == PBM_SCATT_RECT))
Plane Surface(s~{i}~{j}) = {ll~{i}~{j}, llSca};
Else
Plane Surface(s~{i}~{j}) = {ll~{i}~{j}};
EndIf
If (FLAG_PBM == PBM_MARMOUSI)
If ((i == I_SOU) && (j == J_SOU))
Point {p0} In Surface {s~{i}~{j}};
EndIf
EndIf
EndFor
EndFor
// =================================================================================================
// Generate MESH for each subdomain and reference domain
// =================================================================================================
If(StrCmp(OnelabAction, "check"))
Mesh 2;
EndIf
For i In {0:Nx_DOM-1}
For j In {0:Ny_DOM-1}
idom = j*Nx_DOM + i;
Delete Physicals;
Physical Point(TAG_CRN~{idom}~{0}) = p~{i}~{j};
Physical Point(TAG_CRN~{idom}~{1}) = p~{i+1}~{j};
Physical Point(TAG_CRN~{idom}~{2}) = p~{i+1}~{j+1};
Physical Point(TAG_CRN~{idom}~{3}) = p~{i}~{j+1};
Physical Line(TAG_BND~{idom}~{0}) = lx~{i}~{j};
Physical Line(TAG_BND~{idom}~{1}) = ly~{i+1}~{j};
Physical Line(TAG_BND~{idom}~{2}) = lx~{i}~{j+1};
Physical Line(TAG_BND~{idom}~{3}) = ly~{i}~{j};
Physical Surface(TAG_DOM~{idom}) = s~{i}~{j};
If((i == 0) && (j == 0) && (FLAG_PBM == PBM_SCATT_RECT))
Physical Line(TAG_SCA) = {-c1, -c2, -c3, -c4};
EndIf
If(FLAG_PBM == PBM_MARMOUSI)
If((i == I_SOU) && (j == J_SOU))
Physical Point(TAG_SOU) = p0;
EndIf
EndIf
Printf("Saving subdomain %g...", idom);
Save StrCat(MSH_NAME, Sprintf("_%g.msh", idom));
Printf("Done.");
EndFor
EndFor
Delete Physicals;
If(FLAG_PBM == PBM_SCATT_RECT)
Physical Line(TAG_SCA) = {-c1, -c2, -c3, -c4};
EndIf
If(FLAG_PBM == PBM_MARMOUSI)
Physical Point(TAG_SOU) = p0;
EndIf
For i In {0:Nx_DOM-1}
For j In {0:Ny_DOM-1}
idom = j*Nx_DOM + i;
Physical Surface(TAG_DOM~{idom}) = s~{i}~{j};
If(j == 0)
Physical Line(TAG_BND~{idom}~{0}) = lx~{i}~{j};
EndIf
If(i == Nx_DOM-1)
Physical Line(TAG_BND~{idom}~{1}) = ly~{i+1}~{j};
EndIf
If(j == Ny_DOM-1)
Physical Line(TAG_BND~{idom}~{2}) = lx~{i}~{j+1};
EndIf
If(i == 0)
Physical Line(TAG_BND~{idom}~{3}) = ly~{i}~{j};
EndIf
EndFor
EndFor
Physical Point(TAG_CRN~{ 0*Nx_DOM + 0 }~{0}) = p~{0 }~{0 };
Physical Point(TAG_CRN~{ 0*Nx_DOM + (Nx_DOM-1) }~{1}) = p~{Nx_DOM}~{0 };
Physical Point(TAG_CRN~{ (Ny_DOM-1)*Nx_DOM + (Nx_DOM-1) }~{2}) = p~{Nx_DOM}~{Ny_DOM};
Physical Point(TAG_CRN~{ (Ny_DOM-1)*Nx_DOM + 0 }~{3}) = p~{0 }~{Ny_DOM};
Printf("Saving domain ...");
Save StrCat(MSH_NAME, Sprintf(".msh"));
Printf("Done.");
Include "rectangularDom.dat";
// =================================================================================================
// FUNCTIONS
// =================================================================================================
Function{
If (FLAG_PBM == PBM_SCATT_RECT)
f_inc[] = Complex[Cos[WAVENUMBER*X[]], Sin[WAVENUMBER*X[]]];
f_ref[] = AcousticFieldSoftCylinder[XYZ[]]{WAVENUMBER, R_SCA};
f_dir[] = -f_inc[];
EndIf
If (FLAG_PBM == PBM_MARMOUSI)
f_inc[] = 0;
f_ref[] = 0;
velocityField[] = InterpolationBilinear[ $1, $2 ]{ ListFromFile["rectangularDomMarmousi.dat"] };
cData[] = velocityField[ X[], Y[] ];
f_dir[] = -f_inc[];
f_sou = 1;
For iDom In {0:N_DOM-1}
f_sou~{iDom} = 1;
EndFor
EndIf
}
// =================================================================================================
// LISTS ABC/TBC
// =================================================================================================
// Is there an ABC for main domain? (1=yes, 0=no)
isEdgeABC~{0} = 1;
isEdgeABC~{1} = 1;
isEdgeABC~{2} = 1;
isEdgeABC~{3} = 1;
isEdgeRad~{0} = 0;
isEdgeRad~{1} = 0;
isEdgeRad~{2} = 0;
isEdgeRad~{3} = 0;
ListOfSubdom = {};
For xdom In {0:Nx_DOM-1}
For ydom In {0:Ny_DOM-1}
iDom = ydom*Nx_DOM + xdom;
If (iDom % MPI_Size == MPI_Rank)
ListOfSubdom += iDom;
EndIf
iDomNeigh~{iDom}~{0} = (ydom-1)*Nx_DOM + xdom; // Down
iDomNeigh~{iDom}~{1} = ydom*Nx_DOM + (xdom+1); // Right
iDomNeigh~{iDom}~{2} = (ydom+1)*Nx_DOM + xdom; // Top
iDomNeigh~{iDom}~{3} = ydom*Nx_DOM + (xdom-1); // Left
iEdgeNeigh~{iDom}~{0} = 2;
iEdgeNeigh~{iDom}~{1} = 3;
iEdgeNeigh~{iDom}~{2} = 0;
iEdgeNeigh~{iDom}~{3} = 1;
// Is there an ABC or TBC? (1=yes, 0=no)
For iEdge In {0:3}
isEdgeABC~{iDom}~{iEdge} = 0;
isEdgeTBC~{iDom}~{iEdge} = 1;
isEdgeRad~{iDom}~{iEdge} = 0;
EndFor
If(ydom == 0)
isEdgeABC~{iDom}~{0} = 1;
isEdgeTBC~{iDom}~{0} = 0;
EndIf
If(xdom == Nx_DOM-1)
isEdgeABC~{iDom}~{1} = 1;
isEdgeTBC~{iDom}~{1} = 0;
EndIf
If(ydom == Ny_DOM-1)
isEdgeABC~{iDom}~{2} = 1;
isEdgeTBC~{iDom}~{2} = 0;
EndIf
If(xdom == 0)
isEdgeABC~{iDom}~{3} = 1;
isEdgeTBC~{iDom}~{3} = 0;
EndIf
// List of Edges for Absorbing/Transmission Boundary Condition
ListOfEdgesWithABC~{iDom} = {};
ListOfEdgesWithTBC~{iDom} = {};
For iEdge In {0:3}
If(isEdgeABC~{iDom}~{iEdge} == 1)
ListOfEdgesWithABC~{iDom} += iEdge;
EndIf
If(isEdgeTBC~{iDom}~{iEdge} == 1)
ListOfEdgesWithTBC~{iDom} += iEdge;
EndIf
EndFor
EndFor
EndFor
// =================================================================================================
// GROUPS
// =================================================================================================
Group {
// === REFERENCE CASE ===
// DOMAIN
Omega = Region[{}];
// SOURCE
GammaPoint = Region[{}];
// BOUNDARY (Dirichlet BC)
GammaD0 = Region[{}];
GammaN0 = Region[{}];
GammaD = Region[{}];
GammaN = Region[{}];
// BOUNDARY (Absorbing BC)
For iEdge In {0:3}
SigmaMain~{iEdge} = Region[{}];
SigmaMainSide~{iEdge}~{0} = Region[{}];
SigmaMainSide~{iEdge}~{1} = Region[{}];
EndFor
SigmaMain = Region[{}];
// CORNER (Absorbing BC)
CornerMain~{0} = Region[{TAG_CRN~{ 0*Nx_DOM + 0 }~{0}}];
CornerMain~{1} = Region[{TAG_CRN~{ 0*Nx_DOM + (Nx_DOM-1) }~{1}}];
CornerMain~{2} = Region[{TAG_CRN~{ (Ny_DOM-1)*Nx_DOM + (Nx_DOM-1) }~{2}}];
CornerMain~{3} = Region[{TAG_CRN~{ (Ny_DOM-1)*Nx_DOM + 0 }~{3}}];
CornerMain = Region[{ CornerMain~{0}, CornerMain~{1}, CornerMain~{2}, CornerMain~{3}}];
If(FLAG_PBM == PBM_SCATT_RECT)
GammaD += Region[{TAG_SCA}];
EndIf
If(FLAG_PBM == PBM_MARMOUSI)
GammaPoint += Region[{TAG_SOU}];
EndIf
For xdom In {0:Nx_DOM-1}
For ydom In {0:Ny_DOM-1}
iDom = ydom*Nx_DOM + xdom;
// DOMAIN
Omega += Region[TAG_DOM~{iDom}];
// BOUNDARY (Absorbing BC)
For iEdge In {0:3}
If(ydom == 0)
SigmaMain~{0} += Region[{TAG_BND~{iDom}~{0}}];
SigmaMain += Region[{TAG_BND~{iDom}~{0}}];
EndIf
If(xdom == Nx_DOM-1)
SigmaMain~{1} += Region[{TAG_BND~{iDom}~{1}}];
SigmaMain += Region[{TAG_BND~{iDom}~{1}}];
EndIf
If(ydom == Ny_DOM-1)
SigmaMain~{2} += Region[{TAG_BND~{iDom}~{2}}];
SigmaMain += Region[{TAG_BND~{iDom}~{2}}];
EndIf
If(xdom == 0)
SigmaMain~{3} += Region[{TAG_BND~{iDom}~{3}}];
SigmaMain += Region[{TAG_BND~{iDom}~{3}}];
EndIf
EndFor
EndFor
EndFor
For iEdge In {0:3}
iCornerSide1 = iEdge;
iCornerSide2 = (iEdge+1)%4;
SigmaMainSide~{iEdge}~{0} = Region[{CornerMain~{iCornerSide1}}];
SigmaMainSide~{iEdge}~{1} = Region[{CornerMain~{iCornerSide2}}];
EndFor
// === DDM CASE ===
For i0 In {0:#ListOfSubdom()-1}
iDom = ListOfSubdom(i0);
// DOMAIN
Omega~{iDom} = Region[TAG_DOM~{iDom}];
// SOURCE
GammaPoint~{iDom} = Region[{}];
If(FLAG_PBM == PBM_MARMOUSI)
If(iDom == Idom_SOU)
GammaPoint~{iDom} += Region[{TAG_SOU}];
EndIf
EndIf
// BOUNDARY (Dirichlet/Neumann BC)
GammaD0~{iDom} = Region[{}];
GammaN0~{iDom} = Region[{}];
GammaD~{iDom} = Region[{}];
GammaN~{iDom} = Region[{}];
If((FLAG_PBM == PBM_SCATT_RECT) && (iDom == 0))
GammaD~{iDom} = Region[{TAG_SCA}];
EndIf
TrOmegaGammaD~{iDom} = ElementsOf[ Omega~{iDom}, OnOneSideOf GammaD~{iDom} ];
// BOUNDARY (Absorbing BC + Transmission BC)
For iEdge In {0:3}
iCornerSide1 = iEdge;
iCornerSide2 = (iEdge+1)%4;
Sigma~{iDom}~{iEdge} = Region[{TAG_BND~{iDom}~{iEdge}}];
SigmaSide~{iDom}~{iEdge}~{0} = Region[{TAG_CRN~{iDom}~{iCornerSide1}}];
SigmaSide~{iDom}~{iEdge}~{1} = Region[{TAG_CRN~{iDom}~{iCornerSide2}}];
GammaD~{iDom}~{iEdge} = Region[{}];
GammaD0~{iDom}~{iEdge} = Region[{}];
GammaN~{iDom}~{iEdge} = Region[{}];
GammaN0~{iDom}~{iEdge} = Region[{}];
EndFor
Sigma~{iDom} = Region[{ Sigma~{iDom}~{0}, Sigma~{iDom}~{1}, Sigma~{iDom}~{2}, Sigma~{iDom}~{3} }];
// CORNER (Absorbing BC + Transmission BC)
For iCorner In {0:3}
Corner~{iDom}~{iCorner} = Region[{TAG_CRN~{iDom}~{iCorner}}];
EndFor
Corner~{iDom} = Region[{ Corner~{iDom}~{0}, Corner~{iDom}~{1}, Corner~{iDom}~{2}, Corner~{iDom}~{3} }];
EndFor
}
Source diff could not be displayed: it is too large. Options to address this: view the blob.
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment