123 std::ostringstream error_message;
124 error_message <<
"The elastic mesh must be set.";
126 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
130 std::ostringstream error_message;
131 error_message <<
"The Lagrange multiplier mesh must be set.";
133 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
143 unsigned n_solid_dof_types = 0;
144 unsigned n_dof_types = 0;
146 if (this->is_master_block_preconditioner())
149 n_solid_dof_types = this->ndof_types_in_mesh(0);
152 n_dof_types = n_solid_dof_types + this->ndof_types_in_mesh(1);
156 n_dof_types = this->ndof_types();
157 n_solid_dof_types = n_dof_types - (n_dof_types / 3);
160 if (n_dof_types % 3 != 0)
162 std::ostringstream error_message;
163 error_message <<
"This preconditioner requires DIM*3 types of DOF";
165 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
170 Dim = n_dof_types / 3;
174 CRDoubleMatrix* cr_matrix_pt =
dynamic_cast<CRDoubleMatrix*
>(matrix_pt());
176 if (cr_matrix_pt == 0)
178 std::ostringstream error_message;
179 error_message <<
"FSIPreconditioner only works with"
180 <<
" CRDoubleMatrix matrices" << std::endl;
182 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
201 Vector<unsigned> dof_list_for_block_setup(n_dof_types);
202 for (
unsigned dim_i = 0; dim_i <
Dim; dim_i++)
205 dof_list_for_block_setup[dim_i] = 2 * dim_i;
208 dof_list_for_block_setup[dim_i +
Dim] = 2 * dim_i + 1;
211 dof_list_for_block_setup[dim_i + 2 *
Dim] = 2 *
Dim + dim_i;
222 this->block_setup(dof_list_for_block_setup);
226 Vector<unsigned> dof_list_for_subsidiary_prec(n_solid_dof_types);
240 for (
unsigned dim_i = 0; dim_i <
Dim; dim_i++)
243 dof_list_for_subsidiary_prec[2 * dim_i] = dim_i;
246 dof_list_for_subsidiary_prec[2 * dim_i + 1] = dim_i +
Dim;
250 DenseMatrix<CRDoubleMatrix*> solid_matrix_pt(
251 n_solid_dof_types, n_solid_dof_types, 0);
253 for (
unsigned row_i = 0; row_i < n_solid_dof_types; row_i++)
255 for (
unsigned col_i = 0; col_i < n_solid_dof_types; col_i++)
257 solid_matrix_pt(row_i, col_i) =
new CRDoubleMatrix;
258 this->get_block(row_i, col_i, *solid_matrix_pt(row_i, col_i));
265 Scaling = CRDoubleMatrixHelpers::inf_norm(solid_matrix_pt);
273 for (
unsigned d = 0; d <
Dim; d++)
276 unsigned block_i = 2 * d + 1;
279 double* s_values = solid_matrix_pt(block_i, block_i)->value();
280 int* s_column_index = solid_matrix_pt(block_i, block_i)->column_index();
281 int* s_row_start = solid_matrix_pt(block_i, block_i)->row_start();
282 int s_nrow_local = solid_matrix_pt(block_i, block_i)->nrow_local();
283 int s_first_row = solid_matrix_pt(block_i, block_i)->first_row();
286 for (
int i = 0; i < s_nrow_local; i++)
289 for (
int j = s_row_start[i]; j < s_row_start[i + 1] && !found; j++)
291 if (s_column_index[j] == i + s_first_row)
301 std::ostringstream error_message;
302 error_message <<
"The diagonal entry for the constained block("
303 << block_i <<
"," << block_i <<
")\n"
304 <<
"on local row " << i <<
" does not exist."
306 throw OomphLibError(error_message.str(),
307 OOMPH_CURRENT_FUNCTION,
308 OOMPH_EXCEPTION_LOCATION);
319 ExactBlockPreconditioner<CRDoubleMatrix>* s_prec_pt =
320 new ExactBlockPreconditioner<CRDoubleMatrix>;
326 Vector<Vector<unsigned>> doftype_to_doftype_map(n_solid_dof_types,
327 Vector<unsigned>(1, 0));
329 for (
unsigned i = 0; i < n_solid_dof_types; i++)
331 doftype_to_doftype_map[i][0] = i;
334 s_prec_pt->turn_into_subsidiary_block_preconditioner(
335 this, dof_list_for_subsidiary_prec, doftype_to_doftype_map);
339 s_prec_pt->set_subsidiary_preconditioner_function(
344 for (
unsigned d = 0; d <
Dim; d++)
347 unsigned block_i = 2 * d + 1;
350 unsigned dof_block_i =
Dim + d;
351 this->set_replacement_dof_block(
352 dof_block_i, dof_block_i, solid_matrix_pt(block_i, block_i));
355 s_prec_pt->Preconditioner::setup(matrix_pt());
361 GeneralPurposeBlockPreconditioner<CRDoubleMatrix>* s_prec_pt = 0;
368 s_prec_pt =
new BlockDiagonalPreconditioner<CRDoubleMatrix>;
373 BlockTriangularPreconditioner<CRDoubleMatrix>*
374 block_triangular_prec_pt =
375 new BlockTriangularPreconditioner<CRDoubleMatrix>;
376 block_triangular_prec_pt->upper_triangular();
378 s_prec_pt = block_triangular_prec_pt;
383 BlockTriangularPreconditioner<CRDoubleMatrix>*
384 block_triangular_prec_pt =
385 new BlockTriangularPreconditioner<CRDoubleMatrix>;
386 block_triangular_prec_pt->lower_triangular();
388 s_prec_pt = block_triangular_prec_pt;
393 std::ostringstream error_msg;
395 <<
"There is no such block based preconditioner.\n"
396 <<
"Candidates are:\n"
397 <<
"PseudoElasticPreconditioner::Block_diagonal_preconditioner\n"
398 <<
"PseudoElasticPreconditioner::Block_upper_triangular_"
400 <<
"PseudoElasticPreconditioner::Block_lower_triangular_"
403 error_msg.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
414 Vector<Vector<unsigned>> doftype_to_doftype_map(
Dim,
415 Vector<unsigned>(2, 0));
416 Vector<unsigned> s_prec_dof_to_block_map(
Dim, 0);
418 unsigned tmp_index = 0;
419 for (
unsigned d = 0; d <
Dim; d++)
421 s_prec_dof_to_block_map[d] = d;
422 doftype_to_doftype_map[d][0] = tmp_index++;
423 doftype_to_doftype_map[d][1] = tmp_index++;
426 s_prec_pt->turn_into_subsidiary_block_preconditioner(
427 this, dof_list_for_subsidiary_prec, doftype_to_doftype_map);
431 s_prec_pt->set_subsidiary_preconditioner_function(
436 for (
unsigned d = 0; d <
Dim; d++)
439 unsigned block_i = 2 * d + 1;
442 unsigned dof_block_i =
Dim + d;
443 this->set_replacement_dof_block(
444 dof_block_i, dof_block_i, solid_matrix_pt(block_i, block_i));
447 s_prec_pt->set_dof_to_block_map(s_prec_dof_to_block_map);
448 s_prec_pt->Preconditioner::setup(matrix_pt());
454 for (
unsigned row_i = 0; row_i < n_solid_dof_types; row_i++)
456 for (
unsigned col_i = 0; col_i < n_solid_dof_types; col_i++)
458 delete solid_matrix_pt(row_i, col_i);
459 solid_matrix_pt(row_i, col_i) = 0;
465 for (
unsigned d = 0; d <
Dim; d++)
467 CRDoubleMatrix* b_pt =
new CRDoubleMatrix;
468 this->get_block(2 *
Dim + d, 2 * d + 1, *b_pt);
475 (*Lagrange_multiplier_subsidiary_preconditioner_function_pt)();
561 std::ostringstream error_message;
562 error_message <<
"The elastic mesh must be set.";
564 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
568 std::ostringstream error_message;
569 error_message <<
"The Lagrange multiplier mesh must be set.";
571 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
576 unsigned n_solid_dof_types = 0;
577 unsigned n_dof_types = 0;
580 if (this->is_master_block_preconditioner())
583 n_solid_dof_types = this->ndof_types_in_mesh(0);
586 n_dof_types = n_solid_dof_types + this->ndof_types_in_mesh(1);
590 n_dof_types = this->ndof_types();
591 n_solid_dof_types = n_dof_types - (n_dof_types / 3);
594 if (n_dof_types % 3 != 0)
596 std::ostringstream error_message;
597 error_message <<
"This preconditioner requires DIM*3 types of DOF";
599 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
604 Dim = n_dof_types / 3;
607 CRDoubleMatrix* cr_matrix_pt =
dynamic_cast<CRDoubleMatrix*
>(matrix_pt());
610 if (cr_matrix_pt == 0)
612 std::ostringstream error_message;
613 error_message <<
"FSIPreconditioner only works with"
614 <<
" CRDoubleMatrix matrices" << std::endl;
616 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
625 Vector<unsigned> dof_list_for_subsidiary_prec(n_solid_dof_types);
626 for (
unsigned i = 0; i < n_solid_dof_types; i++)
628 dof_list_for_subsidiary_prec[i] = i;
634 Vector<unsigned> dof_list(n_solid_dof_types);
635 for (
unsigned i = 0; i < n_solid_dof_types; i++)
660 Vector<unsigned> dof_list(n_solid_dof_types);
661 for (
unsigned i = 0; i < n_solid_dof_types; i++)
665 s_prec_pt->turn_into_subsidiary_block_preconditioner(
this, dof_list);
672 s_prec_pt->Preconditioner::setup(matrix_pt());
682 Vector<unsigned> dof_list(n_solid_dof_types);
683 for (
unsigned i = 0; i < n_solid_dof_types; i++)
687 s_prec_pt->turn_into_subsidiary_block_preconditioner(
this, dof_list);
716 s_prec_pt->Preconditioner::setup(matrix_pt());
722 for (
unsigned d = 0; d <
Dim; d++)
724 CRDoubleMatrix* b_pt =
new CRDoubleMatrix;
725 this->get_block(2 *
Dim + d,
Dim + d, *b_pt);
732 (*Lagrange_multiplier_subsidiary_preconditioner_function_pt)();
820 if (this->ndof_types() % 2 != 0)
822 std::ostringstream error_message;
824 <<
"This SUBSIDIARY preconditioner requires an even number of "
827 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
832 unsigned ndof_types = this->ndof_types();
833 Vector<unsigned> dof_to_block_map(ndof_types, 0);
834 for (
unsigned i = ndof_types / 2; i < ndof_types; i++)
836 dof_to_block_map[i] = 1;
839 this->block_setup(dof_to_block_map);
842 CRDoubleMatrix* s11_pt =
new CRDoubleMatrix;
843 this->get_block(1, 1, *s11_pt);
846 double* s11_values = s11_pt->value();
847 int* s11_column_index = s11_pt->column_index();
848 int* s11_row_start = s11_pt->row_start();
849 int s11_nrow_local = s11_pt->nrow_local();
850 int s11_first_row = s11_pt->first_row();
851 for (
int i = 0; i < s11_nrow_local; i++)
854 for (
int j = s11_row_start[i]; j < s11_row_start[i + 1] && !found; j++)
856 if (s11_column_index[j] == i + s11_first_row)
864 VectorMatrix<BlockSelector> required_blocks(2, 2);
865 const bool want_block =
true;
866 for (
unsigned b_i = 0; b_i < 2; b_i++)
868 for (
unsigned b_j = 0; b_j < 2; b_j++)
870 required_blocks[b_i][b_j].select_block(b_i, b_j, want_block);
874 required_blocks[1][1].set_replacement_block_pt(s11_pt);
876 CRDoubleMatrix s_prec_pt = this->get_concatenated_block(required_blocks);