47 int number_boundary = ess_tdof_list.
Size(),
50 Vector bnd(number_boundary*dim);
52 for (
int i = 0; i < number_boundary; i++)
54 int idx = ess_tdof_list[i];
55 for (
int d = 0; d <
dim; d++)
57 bnd(i+d*number_boundary) = vxyz(idx + d*number_true);
59 colorv[i] = (
unsigned int)color;
67 for (
int i = 0; i < number_boundary; i++)
69 int idx = ess_tdof_list[i];
70 if (code_out[i] != 2) { ess_tdof_list_int.
Append(idx); }
74 int main(
int argc,
char *argv[])
78 MPI_Init(&argc, &argv);
79 MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
80 MPI_Comm_rank(MPI_COMM_WORLD, &myid);
85 Array <int> np_list(lim_meshes), rs_levels(lim_meshes),
86 rp_levels(lim_meshes);
87 mesh_file_list[0] =
"../../data/square-disc.mesh";
88 mesh_file_list[1] =
"../../data/inline-quad.mesh";
89 mesh_file_list[2] =
"../../data/inline-quad.mesh";
91 bool visualization =
true;
95 double rel_tol = 1.e-8;
99 args.
AddOption(&mesh_file_list[0],
"-m1",
"--mesh",
100 "Mesh file to use.");
101 args.
AddOption(&mesh_file_list[1],
"-m2",
"--mesh",
102 "Mesh file to use.");
103 args.
AddOption(&mesh_file_list[2],
"-m3",
"--mesh",
104 "Mesh file to use.");
106 "Finite element order (polynomial degree) or -1 for"
107 " isoparametric space.");
108 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
109 "--no-visualization",
110 "Enable or disable GLVis visualization.");
111 args.
AddOption(&rs_levels[0],
"-r1",
"--refine-serial",
112 "Number of times to refine the mesh 1 uniformly in serial.");
113 args.
AddOption(&rs_levels[1],
"-r2",
"--refine-serial",
114 "Number of times to refine the mesh 2 uniformly in serial.");
115 args.
AddOption(&rs_levels[2],
"-r3",
"--refine-serial",
116 "Number of times to refine the mesh 3 uniformly in serial.");
117 args.
AddOption(&rp_levels[0],
"-rp1",
"--refine-parallel",
118 "Number of times to refine the mesh 1 uniformly in parallel.");
119 args.
AddOption(&rp_levels[1],
"-rp2",
"--refine-parallel",
120 "Number of times to refine the mesh 2 uniformly in parallel.");
121 args.
AddOption(&rp_levels[2],
"-rp3",
"--refine-parallel",
122 "Number of times to refine the mesh 3 uniformly in parallel.");
123 args.
AddOption(&np_list[0],
"-np1",
"--np1",
124 "number of MPI ranks for mesh 1");
125 args.
AddOption(&np_list[1],
"-np2",
"--np2",
126 "number of MPI ranks for mesh 2");
127 args.
AddOption(&np_list[2],
"-np3",
"--np3",
128 "number of MPI ranks for mesh 3");
131 args.
AddOption(&rel_tol,
"-rt",
"--relative tolerance",
132 "Tolerance for Schwarz iteration convergence criterion.");
146 MPI_Comm *comml =
new MPI_Comm;
149 for (
int i = 0; i < nmeshes; i++)
152 if (myid < npsum) { color = i;
break; }
155 MPI_Comm_split(MPI_COMM_WORLD, color, myid, comml);
156 int myidlocal, numproclocal;
157 MPI_Comm_rank(*comml, &myidlocal);
158 MPI_Comm_size(*comml, &numproclocal);
161 MFEM_VERIFY(np_list.Sum() == num_procs,
" The individual mpi ranks for each"
162 " of the meshes do not add up to"
163 " the total ranks specified.");
168 Mesh *mesh =
new Mesh(mesh_file_list[color], 1, 1);
169 int dim = mesh->Dimension();
174 for (
int lev = 0; lev < rs_levels[color]; lev++) { mesh->UniformRefinement(); }
180 pmesh =
new ParMesh(*comml, *mesh);
181 for (
int l = 0; l < rp_levels[color]; l++)
200 cout <<
"Using isoparametric FEs: " << fec->
Name() << endl;
211 cout <<
"Number of finite element unknowns: " << size << endl;
243 pmesh->
SetCurvature(order,
false, dim, Ordering::byNODES);
250 if (strcmp(mesh_file_list[0],
"../../data/square-disc.mesh") == 0 &&
251 strcmp(mesh_file_list[1],
"../../data/inline-quad.mesh") == 0 &&
252 strcmp(mesh_file_list[2],
"../../data/inline-quad.mesh") == 0 )
258 for (
int i = 0; i < vxyz.
Size(); i++)
260 vxyz(i) = 0.5 + 0.5*(vxyz(i)-0.5);
264 else if (nmeshes == 3)
269 const int pts_cnt = vxyz.
Size()/
dim;
270 for (
int i = 0; i < pts_cnt; i++)
272 vxyz(i) = 0.41 + 0.4*(vxyz(i)-0.5);
274 for (
int i = 0; i < pts_cnt; i++)
276 vxyz(i+pts_cnt) = 0.5 + 0.5*(vxyz(i+pts_cnt)-0.5);
282 const int pts_cnt = vxyz.
Size()/
dim;
283 for (
int i = 0; i < pts_cnt; i++)
285 vxyz(i) = 0.6 + 0.4*(vxyz(i)-0.5);
287 for (
int i = 0; i < pts_cnt; i++)
289 vxyz(i+pts_cnt) = 0.5 + 0.6*(vxyz(i+pts_cnt)-0.5);
302 finder.
Setup(*pmesh, color);
306 ess_tdof_list, ess_tdof_list_int, dim);
310 const int number_boundary = ess_tdof_list_int.
Size(),
313 int number_boundary_g = number_boundary;
314 MPI_Allreduce(&number_boundary, &number_boundary_g, 1, MPI_INT, MPI_SUM,
316 MFEM_VERIFY(number_boundary_g != 0,
" Please use overlapping grids.");
319 colorv.
SetSize(number_boundary);
321 MPI_Barrier(MPI_COMM_WORLD);
322 Vector bnd(number_boundary*dim);
323 for (
int i = 0; i < number_boundary; i++)
325 int idx = ess_tdof_list_int[i];
326 for (
int d = 0; d <
dim; d++)
328 bnd(i+d*number_boundary) = vxyz(idx + d*number_true);
330 colorv[i] = (
unsigned int)color;
332 Vector interp_vals1(number_boundary);
352 int NiterSchwarz = 100;
383 double dxmax = std::numeric_limits<float>::min();
386 MPI_Allreduce(&xinf, &xinfg, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
389 for (
int i = 0; i < number_boundary; i++)
391 int idx = ess_tdof_list_int[i];
392 double dx = std::abs(xt(idx)-interp_vals1(i))/xinfg;
393 if (dx > dxmax) { dxmax = dx; }
394 xt(idx) = interp_vals1(i);
397 double dxmaxg = dxmax;
398 MPI_Allreduce(&dxmax, &dxmaxg, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
404 std::cout << std::setprecision(8) <<
406 ", Relative residual: " << dxmaxg << endl;
409 if (dxmaxg < rel_tol) {
break; }
418 sol_sock <<
"parallel " << num_procs <<
" " << myid <<
"\n";
419 sol_sock.precision(8);
420 sol_sock <<
"solution\n" << *pmesh << x << flush;
427 if (order > 0) {
delete fec; }
int Size() const
Return the logical size of the array.
Class for domain integration L(v) := (f, v)
virtual void GetEssentialTrueDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_tdof_list, int component=-1)
Conjugate gradient method.
A coefficient that is constant across space and time.
virtual void SetCurvature(int order, bool discont=false, int space_dim=-1, int ordering=1)
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
Pointer to an Operator of a specified type.
HYPRE_BigInt GlobalTrueVSize() const
int Size() const
Returns the size of the vector.
Abstract parallel finite element space.
double Normlinf() const
Returns the l_infinity norm of the vector.
struct schwarz_common schwarz
The BoomerAMG solver in hypre.
void SetTrueVector()
Shortcut for calling GetTrueDofs() with GetTrueVector() as argument.
void SetPrintLevel(int print_lvl)
virtual void SetFromTrueDofs(const Vector &tv)
Set the GridFunction from the given true-dof vector.
void Parse()
Parse the command-line options. Note that this function expects all the options provided through the ...
OversetFindPointsGSLIB enables use of findpts for arbitrary number of overlapping grids...
int Append(const T &el)
Append element 'el' to array, resize if necessary.
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
void SetMaxIter(int max_it)
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
void PrintUsage(std::ostream &out) const
Print the usage message.
const Vector & GetTrueVector() const
Read only access to the (optional) internal true-dof Vector.
void FindPoints(const Vector &point_pos, Array< unsigned int > &point_id)
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
void SetRelTol(double rtol)
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
void AddOption(bool *var, const char *enable_short_name, const char *enable_long_name, const char *disable_short_name, const char *disable_long_name, const char *description, bool required=false)
Add a boolean option and set 'var' to receive the value. Enable/disable tags are used to set the bool...
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
virtual const char * Name() const
virtual const Array< unsigned int > & GetCode() const
void PrintOptions(std::ostream &out) const
Print the options.
void Interpolate(const Vector &point_pos, Array< unsigned int > &point_id, const GridFunction &field_in, Vector &field_out)
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
void GetNodes(Vector &node_coord) const
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
Arbitrary order H1-conforming (continuous) finite elements.
void GetInterdomainBoundaryPoints(FindPointsGSLIB &finder1, FindPointsGSLIB &finder2, Vector &mesh_nodes_1, Vector &mesh_nodes_2, Array< int > ess_tdof_list1, Array< int > ess_tdof_list2, Array< int > &ess_tdof_list1_int, Array< int > &ess_tdof_list2_int, const int dim)
void SetNodes(const Vector &node_coord)
Class for parallel grid function.
Class for parallel meshes.
void Setup(Mesh &m, const int meshid, GridFunction *gfmax=NULL, const double bb_t=0.1, const double newt_tol=1.0e-12, const int npt_max=256)
bool Good() const
Return true if the command line options were parsed successfully.