Wrapper for HSL MA42 frontal solver.
Solver: Takes pointer to problem and returns the results Vector which contains the solution of the linear system defined by the problem's fully assembled Jacobian and residual Vector.
130 if (problem_pt->communicator_pt()->nproc() > 1)
132 std::ostringstream error_message;
134 <<
"HSL_MA42 solver cannot be used in parallel.\n"
135 <<
"Please change to another linear solver.\n"
136 <<
"If you want to use a frontal solver then try MumpsSolver\n";
145 unsigned long n_el = problem_pt->mesh_pt()->nelement();
148 N_dof = problem_pt->ndof();
151 LinearAlgebraDistribution dist(problem_pt->communicator_pt(),
N_dof,
false);
172 double cntl[2], rinfo[2];
175 int ndf, nmaxe = 2, nrhs = 1, lrhs = 1;
179 int*
last =
new int[n_dof];
181 double** dx =
new double*;
182 *dx =
new double[n_dof];
185 int exact_lenbuf[3] = {0, 0, 0};
186 bool exact_lenbuf_available =
false;
190 int lenbuf0_recommendation = 0;
191 int lenbuf1_recommendation = 0;
192 int lenbuf2_recommendation = 0;
199 int exact_lenfle[3] = {0, 0, 0};
200 bool exact_lenfle_available =
false;
204 int lenfle0_recommendation = 0;
205 int lenfle1_recommendation = 0;
206 int lenfle2_recommendation = 0;
214 double front0_recommendation = 0;
215 double front1_recommendation = 0;
220 bool exact_nfront_available =
false;
226 AssemblyHandler*
const assembly_handler_pt =
227 problem_pt->assembly_handler_pt();
234 bool not_done =
true;
244 for (
unsigned long e = 0;
e < n_el;
e++)
247 GeneralisedElement* elem_pt = problem_pt->mesh_pt()->element_pt(
e);
253 int nvar = assembly_handler_pt->ndof(elem_pt);
261 ivar =
new int[nvar];
263 for (
int i = 0;
i < nvar;
i++)
266 ivar[
i] = 1 + assembly_handler_pt->eqn_number(elem_pt,
i);
278 int only_eqn = assembly_handler_pt->eqn_number(elem_pt, 0);
281 ivar[0] = 1 + only_eqn;
285 if (only_eqn != (n_dof - 1))
287 dummy_eqn = only_eqn + 1;
291 dummy_eqn = only_eqn - 1;
293 ivar[1] = 1 + dummy_eqn;
307 throw NewtonSolverError(
true);
319 for (
unsigned long e = 0;
e < n_el;
e++)
322 GeneralisedElement* elem_pt = problem_pt->mesh_pt()->element_pt(
e);
328 int nvar = assembly_handler_pt->ndof(elem_pt);
335 ivar =
new int[nvar];
337 for (
int i = 0;
i < nvar;
i++)
340 ivar[
i] = 1 + assembly_handler_pt->eqn_number(elem_pt,
i);
352 int only_eqn = assembly_handler_pt->eqn_number(elem_pt, 0);
355 ivar[0] = 1 + only_eqn;
359 if (only_eqn != (n_dof - 1))
361 dummy_eqn = only_eqn + 1;
365 dummy_eqn = only_eqn - 1;
367 ivar[1] = 1 + dummy_eqn;
380 throw NewtonSolverError(
true);
393 front0_recommendation = ifsize[0];
394 front1_recommendation = ifsize[1];
395 if (!exact_nfront_available)
400 if (n_dof < nfront[0]) nfront[0] = n_dof;
401 if (n_dof < nfront[1]) nfront[1] = n_dof;
408 lenbuf0_recommendation = ifsize[2] + ndf;
413 lenbuf1_recommendation = ifsize[3];
418 lenbuf1_recommendation = 0;
420 lenbuf2_recommendation = ifsize[4];
429 oomph_info <<
"Using direct access files" << std::endl;
450 lenbuf[0] =
int(
ceil(factor *
double(10 * (nfront[0] + 1))));
454 lenbuf[1] =
int(
ceil(factor *
double(10 * (nfront[0]))));
461 lenbuf[2] =
int(
ceil(factor *
double(10 * (2 * nfront[0] + 5))));
465 if (exact_lenfle_available)
467 lenfle[0] = exact_lenfle[0];
468 lenfle[1] = exact_lenfle[1];
469 lenfle[2] = exact_lenfle[2];
473 lenfle0_recommendation = ifsize[2] + ndf;
474 lenfle1_recommendation = ifsize[3];
475 lenfle2_recommendation = ifsize[4];
488 oomph_info <<
"Not using direct access files" << std::endl;
492 if (exact_lenbuf_available)
494 lenbuf[0] = exact_lenbuf[0];
495 lenbuf[1] = exact_lenbuf[1];
496 lenbuf[2] = exact_lenbuf[2];
521 oomph_info <<
"\n FRONT SIZE (min and actual): " << ifsize[0] <<
" "
522 << nfront[0] << std::endl;
530 int lw = 1 + lenbuf[0] + lenbuf[1] + nfront[0] * nfront[1];
531 if (lrhs * nfront[0] > nrhs * nfront[1])
533 lw += lrhs * nfront[0];
537 lw += nrhs * nfront[1];
540 int liw = lenbuf[2] + 2 * nfront[0] + 4 * nfront[1];
553 W =
new (std::nothrow)
double[
Lw];
556 throw OomphLibError(
"Out of memory in allocation of w\n",
573 IW =
new (std::nothrow)
int[
Liw];
576 throw OomphLibError(
"Out of memory in allocation of iw\n",
585 double temp = (lenbuf[0] *
sizeof(
double) + lenbuf[2] *
sizeof(
int)) /
587 oomph_info <<
"\n ESTIMATED MEMORY USAGE " << temp <<
"Mb" << std::endl;
593 for (
unsigned long e = 0;
e < n_el;
e++)
596 GeneralisedElement* elem_pt = problem_pt->mesh_pt()->element_pt(
e);
599 int nvar = assembly_handler_pt->ndof(elem_pt);
609 ivar =
new int[nvar];
611 for (
int i = 0;
i < nvar;
i++)
614 ivar[
i] = 1 + assembly_handler_pt->eqn_number(elem_pt,
i);
627 int only_eqn = assembly_handler_pt->eqn_number(elem_pt, 0);
630 ivar[0] = 1 + only_eqn;
634 if (only_eqn != (n_dof - 1))
636 dummy_eqn = only_eqn + 1;
640 dummy_eqn = only_eqn - 1;
642 ivar[1] = 1 + dummy_eqn;
648 Vector<double> residuals(nvar);
652 assembly_handler_pt->get_jacobian(elem_pt, residuals, jacobian);
657 double onlyjac = jacobian(0, 0);
658 jacobian.resize(2, 2);
659 jacobian(0, 0) = onlyjac;
660 jacobian(1, 0) = 0.0;
661 jacobian(0, 1) = 0.0;
662 jacobian(1, 1) = 0.0;
664 double onlyres = residuals[0];
666 residuals[0] = onlyres;
681 double** avar =
new double*[nvar];
682 double*
tmp =
new double[nvar * nmaxe];
683 for (
int i = 0;
i < nvar;
i++)
685 avar[
i] = &
tmp[
i * nmaxe];
687 double** rhs =
new double*[1];
688 rhs[0] =
new double[nmaxe];
691 for (
int i = 0;
i < nmaxe;
i++)
693 rhs[0][
i] = residuals[
i];
694 for (
int j = 0;
j < nvar;
j++)
697 avar[
j][
i] = jacobian(
i,
j);
739 oomph_info <<
"lenbuf[] too small -- can recover..."
742 else if (
Info[0] == -12)
745 oomph_info <<
"nfront[] too small -- can recover..."
748 else if (
Info[0] == -17)
751 oomph_info <<
"lenfle[] too small -- can recover..."
758 oomph_info <<
"Can't recover from this error" << std::endl;
760 throw NewtonSolverError(
true);
781 problem_pt->sign_of_jacobian() =
Info[1];
809 exact_lenbuf[0] =
Info[4];
810 exact_lenbuf[1] =
Info[5];
811 exact_lenbuf[2] =
Info[6];
812 exact_lenbuf_available =
true;
818 exact_nfront_available =
true;
821 exact_lenfle[0] = lenbuf[0] *
Info[9];
822 exact_lenfle[1] = lenbuf[1] *
Info[10];
823 exact_lenfle[2] = lenbuf[2] *
Info[11];
824 exact_lenfle_available =
true;
832 for (
int i = 0;
i < n_dof;
i++) result[
i] = dx[0][
i];
839 double temp = (
Info[4] *
sizeof(
double) +
Info[6] *
sizeof(
int)) /
841 oomph_info <<
" TOTAL MEMORY USED " << temp <<
"Mb" << std::endl;
844 oomph_info <<
"lenbuf[]: " << lenbuf[0] <<
" " << lenbuf[1] <<
" "
845 << lenbuf[2] <<
" " << std::endl;
846 oomph_info <<
"lenbuf[] factors required and initially specified:"
855 oomph_info <<
"nfront[] factors required and initially specified:"
863 oomph_info <<
"lenfle[]: " << lenfle[0] <<
" " << lenfle[1] <<
" "
864 << lenfle[2] <<
" " << std::endl;
865 oomph_info <<
"lenfle[] factors required and initially specified:"
868 <<
Info[9] * lenbuf[0] /
double(lenfle0_recommendation)
871 <<
Info[10] * lenbuf[1] /
double(lenfle1_recommendation)
874 <<
Info[11] * lenbuf[2] /
double(lenfle2_recommendation)
void build_distribution(const LinearAlgebraDistribution *const dist_pt)
Definition: linear_algebra_distribution.h:507
void reorder_elements(Problem *const &problem_pt)
Function to reorder the elements based on Sloan's algorithm.
Definition: frontal_solver.cc:969
void solve_for_one_dof(Problem *const &problem_pt, DoubleVector &result)
Definition: frontal_solver.cc:48
bool Enable_resolve
Definition: linear_solver.h:73
#define MA42ID(ICNTL, CNTL, ISAVE)
Definition: frontal.h:28
#define MA42PD(ISTRM, LENBUF, LENFLE, ICNTL, ISAVE, INFO)
#define MA42BD(NVAR, IVAR, NDF, LAST, NMAXE, AVAR, NRHS, RHS, LRHS, LX, X, NFRONT, LENBUF, LW, W, LIW, IW, ICNTL, CNTL, ISAVE, INFO, RINFO)
Definition: frontal.h:117
#define MA42JD(NVAR, IVAR, NDF, LAST, NMAXE, IFSIZE, ICNTL, ISAVE, INFO)
#define MA42AD(NVAR, IVAR, NDF, LAST, LENLST, ICNTL, ISAVE, INFO)
Definition: frontal.h:32
static constexpr const last_t last
Definition: IndexedViewHelper.h:48
Eigen::Matrix< Scalar, Dynamic, Dynamic, ColMajor > tmp
Definition: level3_impl.h:365
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 ceil(const bfloat16 &a)
Definition: BFloat16.h:644
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2