13 #include "../../general/tic_toc.hpp" 21 #include "moonolith_aabb.hpp" 22 #include "moonolith_serial_hash_grid.hpp" 23 #include "moonolith_stream_utils.hpp" 24 #include "par_moonolith_config.hpp" 31 struct MortarAssembler::Impl
34 std::shared_ptr<FiniteElementSpace>
source;
35 std::shared_ptr<FiniteElementSpace> destination;
36 std::vector<std::shared_ptr<MortarIntegrator>> integrators;
37 std::shared_ptr<SparseMatrix> coupling_matrix;
38 std::shared_ptr<SparseMatrix> mass_matrix;
40 bool assemble_mass_and_coupling_together{
true};
41 int max_solver_iterations{400};
43 bool is_vector_fe()
const 45 bool is_vector_fe =
false;
46 for (
auto i_ptr : integrators)
48 if (i_ptr->is_vector_fe())
58 BilinearFormIntegrator * new_mass_integrator()
const 62 return new VectorFEMassIntegrator();
66 return new MassIntegrator();
75 impl_->assemble_mass_and_coupling_together = value;
80 impl_->max_solver_iterations = max_solver_iterations;
84 const std::shared_ptr<MortarIntegrator> &integrator)
86 impl_->integrators.push_back(integrator);
91 impl_->verbose = verbose;
96 std::vector<::moonolith::AABB<Dim, double>> &element_boxes)
102 element_boxes.resize(mesh.
GetNE());
105 for (
int i = 0; i < mesh.
GetNE(); ++i)
108 MinCol(
pts, &element_boxes[i].min_[0],
false);
109 MaxCol(
pts, &element_boxes[i].max_[0],
false);
114 std::vector<moonolith::Integer> &pairs)
122 std::vector<::moonolith::AABB<1, double>> src_boxes, dest_boxes;
126 ::moonolith::SerialHashGrid<1, double> grid;
127 return grid.detect(src_boxes, dest_boxes, pairs);
131 std::vector<::moonolith::AABB<2, double>> src_boxes, dest_boxes;
135 ::moonolith::SerialHashGrid<2, double> grid;
136 return grid.detect(src_boxes, dest_boxes, pairs);
140 std::vector<::moonolith::AABB<3, double>> src_boxes, dest_boxes;
144 ::moonolith::SerialHashGrid<3, double> grid;
145 return grid.detect(src_boxes, dest_boxes, pairs);
156 const std::shared_ptr<FiniteElementSpace> &
source,
157 const std::shared_ptr<FiniteElementSpace> &destination)
161 impl_->destination = destination;
174 const bool verbose = impl_->verbose;
176 const auto &source_mesh = *impl_->source->GetMesh();
177 const auto &destination_mesh = *impl_->destination->GetMesh();
179 int dim = source_mesh.Dimension();
181 std::vector<::moonolith::Integer> pairs;
190 assert(
false &&
"NOT Supported!");
199 B = make_shared<SparseMatrix>(impl_->destination->GetNDofs(),
200 impl_->source->GetNDofs());
203 std::unique_ptr<BilinearFormIntegrator> mass_integr(impl_->new_mass_integrator());
205 if(impl_->assemble_mass_and_coupling_together) {
206 impl_->mass_matrix = make_shared<SparseMatrix>(impl_->destination->GetNDofs(), impl_->destination->GetNDofs());
214 double local_element_matrices_sum = 0.0;
216 long n_intersections = 0;
217 long n_candidates = 0;
221 for (
auto i_ptr : impl_->integrators)
223 max_q_order = std::max(i_ptr->GetQuadratureOrder(), max_q_order);
226 bool intersected =
false;
227 for (
auto it = begin(pairs); it != end(pairs); )
229 const int source_index = *it++;
230 const int destination_index = *it++;
232 auto &source_fe = *impl_->source->GetFE(source_index);
233 auto &destination_fe = *impl_->destination->GetFE(destination_index);
236 *impl_->destination->GetElementTransformation(destination_index);
242 const int src_order = src_order_mult * source_fe.GetOrder();
243 const int dest_order = dest_order_mult * destination_fe.GetOrder();
245 int contraction_order = src_order + dest_order;
247 if(impl_->assemble_mass_and_coupling_together) {
248 contraction_order = std::max(contraction_order, 2 * dest_order);
251 const int order = contraction_order + dest_order_mult * destination_Trans.
OrderW() + max_q_order;
254 cut->SetIntegrationOrder(order);
258 if (cut->BuildQuadrature(*impl_->source, source_index, *impl_->destination,
259 destination_index, source_ir, destination_ir))
261 impl_->source->GetElementVDofs(source_index, source_vdofs);
262 impl_->destination->GetElementVDofs(destination_index, destination_vdofs);
265 *impl_->source->GetElementTransformation(source_index);
268 for (
auto i_ptr : impl_->integrators)
272 i_ptr->AssembleElementMatrix(source_fe, source_ir, source_Trans,
273 destination_fe, destination_ir,
274 destination_Trans, cumulative_elemmat);
279 i_ptr->AssembleElementMatrix(source_fe, source_ir, source_Trans,
280 destination_fe, destination_ir,
281 destination_Trans, elemmat);
282 cumulative_elemmat += elemmat;
286 local_element_matrices_sum += Sum(cumulative_elemmat);
288 B->AddSubMatrix(destination_vdofs, source_vdofs, cumulative_elemmat,
291 if(impl_->assemble_mass_and_coupling_together) {
292 mass_integr->SetIntRule(&destination_ir);
293 mass_integr->AssembleElementMatrix(destination_fe, destination_Trans, elemmat);
294 impl_->mass_matrix->AddSubMatrix(destination_vdofs, destination_vdofs, elemmat, skip_zeros);
309 if(impl_->assemble_mass_and_coupling_together) {
310 impl_->mass_matrix->Finalize();
315 mfem::out <<
"local_element_matrices_sum: " << local_element_matrices_sum
317 mfem::out <<
"B in R^(" << B->Height() <<
" x " << B->Width() <<
")" 320 mfem::out <<
"n_intersections: " << n_intersections
321 <<
", n_candidates: " << n_candidates <<
'\n';
338 if (!impl_->coupling_matrix)
346 Vector temp(impl_->coupling_matrix->Height());
347 impl_->coupling_matrix->Mult(src_fun, temp);
350 Dinv.
SetMaxIter(impl_->max_solver_iterations);
359 Dinv.
Mult(temp, dest_fun);
366 const bool verbose = impl_->verbose;
372 mfem::out <<
"\nAssembling coupling operator..." << endl;
377 if (!
Assemble(impl_->coupling_matrix))
389 if(!impl_->assemble_mass_and_coupling_together) {
397 impl_->mass_matrix = std::shared_ptr<SparseMatrix>(b_form.LoseMat());
402 Vector brs(impl_->coupling_matrix->Height());
403 impl_->coupling_matrix->GetRowSums(brs);
405 Vector drs(impl_->mass_matrix->Height());
406 impl_->mass_matrix->GetRowSums(drs);
408 mfem::out <<
"sum(B): " << brs.Sum() << std::endl;
409 mfem::out <<
"sum(D): " << drs.Sum() << std::endl;
Conjugate gradient method.
Class for an integration rule - an Array of IntegrationPoint.
Class for grid function - Vector with associated FE space.
int order_multiplier(const Geometry::Type type, const int dim)
bool Apply(const GridFunction &src_fun, GridFunction &dest_fun)
transfer a function from source to destination. It requires that the Update function is called before...
void SetVerbose(const bool verbose)
Expose process details with verbose output.
int Dimension() const
Dimension of the reference space used within the elements.
bool HashGridDetectIntersections(const Mesh &src, const Mesh &dest, std::vector< moonolith::Integer > &pairs)
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
Data type dense matrix using column-major storage.
bool Update()
assembles the various components necessary for the transfer. To be called before calling the Apply fu...
double RealTime()
Return the number of real seconds elapsed since the stopwatch was started.
void GetPointMatrix(int i, DenseMatrix &pointmat) const
void Stop()
Stop the stopwatch.
void source(const Vector &x, Vector &f)
MortarAssembler(const std::shared_ptr< FiniteElementSpace > &source, const std::shared_ptr< FiniteElementSpace > &destination)
constructs the object with source and destination spaces
virtual void SetPrintLevel(int print_lvl)
Legacy method to set the level of verbosity of the solver output.
bool Transfer(const GridFunction &src_fun, GridFunction &dest_fun)
transfer a function from source to destination. if the transfer is to be performed multiple times use...
void SetMaxIter(int max_it)
void Start()
Start the stopwatch. The elapsed time is not cleared.
void SetAssembleMassAndCouplingTogether(const bool value)
Control if the Mass matrix is computed together with the coupling operator every time.
void SetRelTol(double rtol)
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
std::shared_ptr< Cut > NewCut(const int dim)
void SetMaxSolverIterations(const int max_solver_iterations)
Control the maximum numbers of conjugate gradients steps for mass matrix inversion.
int GetNE() const
Returns number of elements.
void BuildBoxes(const Mesh &mesh, std::vector<::moonolith::AABB< Dim, double >> &element_boxes)
void AddMortarIntegrator(const std::shared_ptr< MortarIntegrator > &integrator)
This method must be called before Assemble or Transfer. It will assemble the operator in all intersec...
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
bool Assemble(std::shared_ptr< SparseMatrix > &B)
assembles the coupling matrix B. B : source -> destination If u is a coefficient associated with sour...
void pts(int iphi, int t, double x[])