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)();
481 ExactPreconditionerFactory::create_exact_preconditioner();
562 std::ostringstream error_message;
563 error_message <<
"The elastic mesh must be set.";
565 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
569 std::ostringstream error_message;
570 error_message <<
"The Lagrange multiplier mesh must be set.";
572 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
577 unsigned n_solid_dof_types = 0;
578 unsigned n_dof_types = 0;
581 if (this->is_master_block_preconditioner())
584 n_solid_dof_types = this->ndof_types_in_mesh(0);
587 n_dof_types = n_solid_dof_types + this->ndof_types_in_mesh(1);
591 n_dof_types = this->ndof_types();
592 n_solid_dof_types = n_dof_types - (n_dof_types / 3);
595 if (n_dof_types % 3 != 0)
597 std::ostringstream error_message;
598 error_message <<
"This preconditioner requires DIM*3 types of DOF";
600 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
605 Dim = n_dof_types / 3;
608 CRDoubleMatrix* cr_matrix_pt =
dynamic_cast<CRDoubleMatrix*
>(matrix_pt());
611 if (cr_matrix_pt == 0)
613 std::ostringstream error_message;
614 error_message <<
"FSIPreconditioner only works with"
615 <<
" CRDoubleMatrix matrices" << std::endl;
617 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
626 Vector<unsigned> dof_list_for_subsidiary_prec(n_solid_dof_types);
627 for (
unsigned i = 0; i < n_solid_dof_types; i++)
629 dof_list_for_subsidiary_prec[i] = i;
635 Vector<unsigned> dof_list(n_solid_dof_types);
636 for (
unsigned i = 0; i < n_solid_dof_types; i++)
661 Vector<unsigned> dof_list(n_solid_dof_types);
662 for (
unsigned i = 0; i < n_solid_dof_types; i++)
666 s_prec_pt->turn_into_subsidiary_block_preconditioner(
this, dof_list);
673 s_prec_pt->Preconditioner::setup(matrix_pt());
683 Vector<unsigned> dof_list(n_solid_dof_types);
684 for (
unsigned i = 0; i < n_solid_dof_types; i++)
688 s_prec_pt->turn_into_subsidiary_block_preconditioner(
this, dof_list);
717 s_prec_pt->Preconditioner::setup(matrix_pt());
723 for (
unsigned d = 0; d <
Dim; d++)
725 CRDoubleMatrix* b_pt =
new CRDoubleMatrix;
726 this->get_block(2 *
Dim + d,
Dim + d, *b_pt);
733 (*Lagrange_multiplier_subsidiary_preconditioner_function_pt)();
740 ExactPreconditionerFactory::create_exact_preconditioner();
822 if (this->ndof_types() % 2 != 0)
824 std::ostringstream error_message;
826 <<
"This SUBSIDIARY preconditioner requires an even number of "
829 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
834 unsigned ndof_types = this->ndof_types();
835 Vector<unsigned> dof_to_block_map(ndof_types, 0);
836 for (
unsigned i = ndof_types / 2; i < ndof_types; i++)
838 dof_to_block_map[i] = 1;
841 this->block_setup(dof_to_block_map);
844 CRDoubleMatrix* s11_pt =
new CRDoubleMatrix;
845 this->get_block(1, 1, *s11_pt);
848 double* s11_values = s11_pt->value();
849 int* s11_column_index = s11_pt->column_index();
850 int* s11_row_start = s11_pt->row_start();
851 int s11_nrow_local = s11_pt->nrow_local();
852 int s11_first_row = s11_pt->first_row();
853 for (
int i = 0; i < s11_nrow_local; i++)
856 for (
int j = s11_row_start[i]; j < s11_row_start[i + 1] && !found; j++)
858 if (s11_column_index[j] == i + s11_first_row)
866 VectorMatrix<BlockSelector> required_blocks(2, 2);
867 const bool want_block =
true;
868 for (
unsigned b_i = 0; b_i < 2; b_i++)
870 for (
unsigned b_j = 0; b_j < 2; b_j++)
872 required_blocks[b_i][b_j].select_block(b_i, b_j, want_block);
876 required_blocks[1][1].set_replacement_block_pt(s11_pt);
878 CRDoubleMatrix s_prec_pt = this->get_concatenated_block(required_blocks);
891 ExactPreconditionerFactory::create_exact_preconditioner();