50int main(
int argc,
char *argv[])
53 const char *mesh_file_1 =
"../../data/square-disc.mesh";
54 const char *mesh_file_2 =
"../../data/inline-quad.mesh";
56 bool visualization =
true;
59 double rel_tol = 1.e-8;
62 args.
AddOption(&mesh_file_1,
"-m1",
"--mesh",
64 args.
AddOption(&mesh_file_2,
"-m2",
"--mesh",
67 "Finite element order (polynomial degree) or -1 for"
68 " isoparametric space.");
69 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
71 "Enable or disable GLVis visualization.");
72 args.
AddOption(&r1_levels,
"-r1",
"--refine-serial",
73 "Number of times to refine the mesh uniformly in serial.");
74 args.
AddOption(&r2_levels,
"-r2",
"--refine-serial",
75 "Number of times to refine the mesh uniformly in serial.");
76 args.
AddOption(&rel_tol,
"-rt",
"--relative tolerance",
77 "Tolerance for Schwarz iteration convergence criterion.");
87 const int nmeshes = 2;
92 Array <Mesh*> mesharr(2);
93 mesharr[0] =
new Mesh(mesh_file_1, 1, 1);
94 mesharr[1] =
new Mesh(mesh_file_2, 1, 1);
95 int dim = mesharr[0]->Dimension();
101 for (
int lev = 0; lev < r1_levels; lev++) { mesharr[0]->UniformRefinement(); }
102 for (
int lev = 0; lev < r2_levels; lev++) { mesharr[1]->UniformRefinement(); }
107 Array <FiniteElementCollection*> fecarr(nmeshes);
108 Array <FiniteElementSpace*> fespacearr(nmeshes);
109 for (
int i = 0; i< nmeshes; i ++)
115 else if (mesharr[i]->GetNodes())
117 fecarr[i] = mesharr[i]->GetNodes()->OwnFEC();
118 cout <<
"Using isoparametric FEs: " << fecarr[0]->Name() << endl;
132 if (mesharr[0]->bdr_attributes.
Size())
136 fespacearr[0]->GetEssentialTrueDofs(ess_bdr, ess_tdof_list1);
139 if (mesharr[1]->bdr_attributes.
Size())
143 fespacearr[1]->GetEssentialTrueDofs(ess_bdr, ess_tdof_list2);
151 for (
int i = 0; i< nmeshes; i ++)
168 Vector mesh_nodes_1 = *mesharr[0]->GetNodes();
170 Vector mesh_nodes_2 = *mesharr[1]->GetNodes();
175 if (strcmp(mesh_file_1,
"../../data/square-disc.mesh") == 0 &&
176 strcmp(mesh_file_2,
"../../data/inline-quad.mesh") == 0 )
178 for (
int i = 0; i < mesh_nodes_2.
Size(); i++)
180 mesh_nodes_2(i) = 0.5 + 0.5*(mesh_nodes_2(i)-0.5);
182 mesharr[1]->SetNodes(mesh_nodes_2);
186 finder1.
Setup(*mesharr[0]);
187 finder2.
Setup(*mesharr[1]);
189 Array<int> ess_tdof_list1_int, ess_tdof_list2_int;
191 ess_tdof_list1, ess_tdof_list2,
192 ess_tdof_list1_int, ess_tdof_list2_int,
dim);
196 const int number_boundary_1 = ess_tdof_list1_int.
Size(),
197 number_boundary_2 = ess_tdof_list2_int.
Size(),
198 number_true_1 = mesh_nodes_1.
Size()/
dim,
199 number_true_2 = mesh_nodes_2.
Size()/
dim;
201 MFEM_VERIFY(number_boundary_1 != 0 ||
202 number_boundary_2 != 0,
" Please use overlapping grids.");
205 for (
int i = 0; i < number_boundary_1; i++)
207 int idx = ess_tdof_list1_int[i];
208 for (
int d = 0; d <
dim; d++)
210 bnd1(i+d*number_boundary_1) = mesh_nodes_1(idx + d*number_true_1);
215 for (
int i = 0; i < number_boundary_2; i++)
217 int idx = ess_tdof_list2_int[i];
218 for (
int d = 0; d <
dim; d++)
220 bnd2(i+d*number_boundary_2) = mesh_nodes_2(idx + d*number_true_2);
224 Vector interp_vals1(number_boundary_1), interp_vals2(number_boundary_2);
230 Array <BilinearForm*> a_ar(2);
250 int NiterSchwarz = 100;
253 for (
int i = 0; i < nmeshes; i ++)
263 a_ar[0]->FormLinearSystem(ess_tdof_list1, x1, *b_ar[0], A1, X1, B1);
264 a_ar[1]->FormLinearSystem(ess_tdof_list2, x2, *b_ar[1], A2, X2, B2);
269 PCG(*A1, M1, B1, X1, 0, 200, 1e-12, 0.0);
271 PCG(*A2, M2, B2, X2, 0, 200, 1e-12, 0.0);
274 a_ar[0]->RecoverFEMSolution(X1, *b_ar[0], x1);
275 a_ar[1]->RecoverFEMSolution(X2, *b_ar[1], x2);
281 double dxmax = std::numeric_limits<float>::min();
282 double x1inf = x1.Normlinf();
284 for (
int i = 0; i < number_boundary_1; i++)
286 int idx = ess_tdof_list1_int[i];
287 double dx = std::abs(x1(idx)-interp_vals1(i))/x1inf;
288 if (dx > dxmax) { dxmax = dx; }
289 x1(idx) = interp_vals1(i);
292 for (
int i = 0; i < number_boundary_2; i++)
294 int idx = ess_tdof_list2_int[i];
295 double dx = std::abs(x2(idx)-interp_vals2(i))/x2inf;
296 if (dx > dxmax) { dxmax = dx; }
297 x2(idx) = interp_vals2(i);
303 std::cout << std::setprecision(8) <<
305 ", Relative residual: " << dxmax << endl;
306 if (dxmax < rel_tol) {
break; }
314 for (
int ip = 0; ip<mesharr.
Size(); ++ip)
317 sol_sock.precision(8);
318 sol_sock <<
"parallel " << mesharr.
Size() <<
" " << ip <<
"\n";
319 if (ip==0) { sol_sock <<
"solution\n" << *mesharr[ip] << x1 << flush; }
320 if (ip==1) { sol_sock <<
"solution\n" << *mesharr[ip] << x2 << flush; }
321 sol_sock <<
"window_title 'Overlapping grid solution'\n"
322 <<
"window_geometry "
323 << 0 <<
" " << 0 <<
" " << 450 <<
" " << 350 <<
"\n"
324 <<
"keys jmcA]]]" << endl;
331 for (
int i = 0; i < nmeshes; i++)
334 delete fespacearr[i];
335 if (order > 0) {
delete fecarr[i]; }