47 {
return elem_pt->
ndof();}
70 {
return *(problem_pt->
dof_pt(i)+
t);}
79 const unsigned &ieqn_local)
116 double*
const ¶meter_pt,
129 double*
const ¶meter_pt,
159 std::ostringstream error_stream;
162 "There is no bifurcation parameter associated with the current assembly handler.\n" 164 "Eigenfunction are only calculated by the Fold, PitchFork and Hopf Handlers" 168 OOMPH_CURRENT_FUNCTION,
169 OOMPH_EXCEPTION_LOCATION);
182 std::ostringstream error_stream;
185 "There is no eigenfunction associated with the current assembly handler.\n" 187 "Eigenfunction are only calculated by the Fold, PitchFork and Hopf Handlers" 191 OOMPH_CURRENT_FUNCTION,
192 OOMPH_EXCEPTION_LOCATION);
201 Vector<std::pair<unsigned,unsigned> >
202 const &history_index,
234 {
return elem_pt->
ndof();}
275 if(matrix.size() != 1)
278 "ExplicitTimeSteps should return one matrix",
279 OOMPH_CURRENT_FUNCTION,
280 OOMPH_EXCEPTION_LOCATION);
299 {
return elem_pt->
ndof();}
316 "An eigenproblem does not have a get_residuals function",
317 OOMPH_CURRENT_FUNCTION,
318 OOMPH_EXCEPTION_LOCATION);
329 "An eigenproblem does not have a get_jacobian function",
330 OOMPH_CURRENT_FUNCTION,
331 OOMPH_EXCEPTION_LOCATION);
345 if(matrix.size() != 2)
347 throw OomphLibError(
"EigenProblems should return two matrices",
348 OOMPH_CURRENT_FUNCTION,
349 OOMPH_EXCEPTION_LOCATION);
353 unsigned n_var = elem_pt->
ndof();
360 if(Sigma_real != 0.0)
363 for(
unsigned i=0;
i<n_var;
i++)
365 for(
unsigned j=0;j<n_var;j++)
367 matrix[0](
i,j) -= Sigma_real*matrix[1](i,j);
379 if(Alpha_pt!=0) {
delete Alpha_pt;}
380 if(E_pt!=0) {
delete E_pt;}
396 throw OomphLibError(
"The result vector must not be distributed",
397 OOMPH_CURRENT_FUNCTION,
398 OOMPH_EXCEPTION_LOCATION);
411 unsigned n_dof = problem_pt->
ndof();
416 this->build_distribution(dist);
421 result.
build(this->distribution_pt(),0.0);
425 DoubleVector a(this->distribution_pt(),0.0), b(this->distribution_pt(),0.0);
428 if(Alpha_pt!=0) {
delete Alpha_pt;}
429 Alpha_pt =
new DoubleVector(this->distribution_pt(),0.0);
432 Linear_solver_pt->enable_resolve();
435 Linear_solver_pt->solve(problem_pt,a);
442 for(
unsigned n=0;n<(n_dof-1);++n) {y[n] = handler_pt->
Y[n];}
452 for(
unsigned long e = 0;
e<n_element;
e++)
456 unsigned n_var = elem_pt->
ndof();
465 for(
unsigned n=0;n<n_var;n++)
468 for(
unsigned m=0;m<n_var;m++)
478 Linear_solver_pt->resolve(Jy,*Alpha_pt);
481 DoubleVector y_minus_alpha(this->distribution_pt(),0.0);
482 for(
unsigned n=0;n<n_dof;n++)
484 y_minus_alpha[n] = y[n] - (*Alpha_pt)[n];
489 double dof_length=0.0, a_length=0.0, alpha_length=0.0;
490 for(
unsigned n=0;n<n_dof;n++)
492 if(std::fabs(problem_pt->
dof(n)) > dof_length)
493 {dof_length = std::fabs(problem_pt->
dof(n));}
494 if(std::fabs(a[n]) > a_length) {a_length = std::fabs(a[n]);}
495 if(std::fabs(y_minus_alpha[n]) > alpha_length)
496 {alpha_length = std::fabs(y_minus_alpha[n]);}
499 double a_mult = dof_length/a_length;
500 double alpha_mult = dof_length/alpha_length;
507 Jprod_alpha(this->distribution_pt(),0.0);
510 for(
unsigned long e = 0;
e<n_element;
e++)
514 unsigned n_var = handler_pt->
ndof(elem_pt);
525 for(
unsigned n=0;n<n_var;n++)
528 dof_bac[n] = problem_pt->
dof(eqn_number);
539 for(
unsigned n=0;n<n_var;n++)
542 problem_pt->
dof(eqn_number) = dof_bac[n];
544 problem_pt->
dof(eqn_number) += alpha_mult*y_minus_alpha[
eqn_number];
550 handler_pt->
get_jacobian(elem_pt,res_elemental,jac_alpha);
553 for(
unsigned n=0;n<n_var;n++)
556 problem_pt->
dof(eqn_number) = dof_bac[n];
564 for(
unsigned n=0;n<(n_var-1);n++)
567 double prod_a=0.0, prod_alpha=0.0;
568 for(
unsigned m=0;m<(n_var-1);m++)
570 unsigned unknown = handler_pt->
eqn_number(elem_pt,m);
571 prod_a += (jac_a(n,m) - jac(n,m))*y[unknown];
572 prod_alpha += (jac_alpha(n,m) - jac(n,m))*y[unknown];
575 Jprod_alpha[
eqn_number] += prod_alpha/alpha_mult;
579 Jprod_alpha[n_dof-1] = 0.0;
580 Jprod_a[n_dof-1] = 0.0;
585 for(
unsigned n=0;n<n_dof-1;n++)
587 b[n] = result[n_dof+n] - Jprod_a[n];
590 b[n_dof-1] = result[n_dof-1];
593 if(E_pt!=0) {
delete E_pt;}
596 Linear_solver_pt->resolve(b,f);
597 Linear_solver_pt->resolve(Jprod_alpha,*E_pt);
600 const double e_final = (*E_pt)[n_dof-1];
602 const double d_final = f[n_dof-1]/e_final;
604 for(
unsigned n=0;n<n_dof-1;n++)
606 result[n] = a[n] - (*Alpha_pt)[n]*d_final + d_final*y[n];
607 result[n_dof+n] = f[n] - (*E_pt)[n]*d_final;
610 result[n_dof-1] = a[n_dof-1] - (*Alpha_pt)[n_dof-1]*d_final;
614 static_cast<int>(std::fabs(e_final)/e_final);
623 Linear_solver_pt->disable_resolve();
624 delete Alpha_pt; Alpha_pt=0;
630 Problem_pt = problem_pt;
644 throw OomphLibError(
"The required vectors have not been stored",
645 OOMPH_CURRENT_FUNCTION,
646 OOMPH_EXCEPTION_LOCATION);
650 Problem*
const problem_pt = Problem_pt;
659 unsigned n_dof = problem_pt->
ndof();
667 throw OomphLibError(
"The result vector must not be distributed",
668 OOMPH_CURRENT_FUNCTION,
669 OOMPH_EXCEPTION_LOCATION);
676 OOMPH_CURRENT_FUNCTION,
677 OOMPH_EXCEPTION_LOCATION);
688 DoubleVector a(this->distribution_pt(),0.0), b(this->distribution_pt(),0.0);
691 for(
unsigned n=0;n<(n_dof-1);n++) {a[n] = rhs[n];}
695 Linear_solver_pt->enable_resolve();
702 Linear_solver_pt->resolve(input_a,a);
706 double dof_length=0.0, a_length=0.0;
707 for(
unsigned n=0;n<n_dof;n++)
709 if(std::fabs(problem_pt->
dof(n)) > dof_length)
710 {dof_length = std::fabs(problem_pt->
dof(n));}
712 if(std::fabs(a[n]) > a_length) {a_length = std::fabs(a[n]);}
714 double a_mult = dof_length/a_length;
722 for(
unsigned long e = 0;
e<n_element;
e++)
726 unsigned n_var = handler_pt->
ndof(elem_pt);
737 for(
unsigned n=0;n<n_var;n++)
740 dof_bac[n] = problem_pt->
dof(eqn_number);
751 for(
unsigned n=0;n<n_var;n++)
754 problem_pt->
dof(eqn_number) = dof_bac[n];
760 for(
unsigned n=0;n<(n_var-1);n++)
764 for(
unsigned m=0;m<(n_var-1);m++)
766 unsigned unknown = handler_pt->
eqn_number(elem_pt,m);
767 prod_a += (jac_a(n,m) - jac(n,m))*handler_pt->
Y[unknown];
773 Jprod_a[n_dof-1] = 0.0;
776 for(
unsigned n=0;n<n_dof-1;n++)
778 b[n] = rhs[n_dof+n] - Jprod_a[n];
782 b[n_dof-1] = rhs[n_dof-1];
786 Linear_solver_pt->resolve(b,f);
789 const double d_final = f[n_dof-1]/(*E_pt)[n_dof-1];
791 for(
unsigned n=0;n<n_dof-1;n++)
793 result[n] = a[n] - (*Alpha_pt)[n]*d_final + d_final*handler_pt->
Y[n];
794 result[n_dof+n] = f[n] - (*E_pt)[n]*d_final;
797 result[n_dof-1] = a[n_dof-1] - (*Alpha_pt)[n_dof-1]*d_final;
799 Linear_solver_pt->disable_resolve();
817 double*
const ¶meter_pt) :
818 Solve_which_system(Full_augmented), Parameter_pt(parameter_pt)
837 for(
unsigned e=0;
e<n_element;
e++)
841 unsigned n_var = elem_pt->
ndof();
842 for(
unsigned n=0;n<n_var;n++)
867 linear_solver_pt->
solve(problem_pt,x);
878 linear_solver_pt->
resolve(input_x,x);
891 problem_pt->
Dof_pt.push_back(parameter_pt);
896 for(
unsigned n=0;n<
Ndof;n++) {length += x[n]*x[n];}
897 length = sqrt(length);
901 for(
unsigned n=0;n<
Ndof;n++)
903 problem_pt->
Dof_pt.push_back(&
Y[n]);
904 Y[n] =
Phi[n] = -x[n]/length;
920 double*
const ¶meter_pt,
942 for(
unsigned e=0;
e<n_element;
e++)
946 unsigned n_var = elem_pt->
ndof();
947 for(
unsigned n=0;n<n_var;n++)
955 problem_pt->
Dof_pt.push_back(parameter_pt);
960 for(
unsigned n=0;n<
Ndof;n++)
961 {length += eigenvector[n]*eigenvector[n];}
962 length = sqrt(length);
966 for(
unsigned n=0;n<
Ndof;n++)
968 problem_pt->
Dof_pt.push_back(&
Y[n]);
969 Y[n] =
Phi[n] = eigenvector[n]/length;
985 double*
const ¶meter_pt,
1008 for(
unsigned e=0;
e<n_element;
e++)
1012 unsigned n_var = elem_pt->
ndof();
1013 for(
unsigned n=0;n<n_var;n++)
1021 problem_pt->
Dof_pt.push_back(parameter_pt);
1025 double length = 0.0;
1026 for(
unsigned n=0;n<
Ndof;n++)
1027 {length += eigenvector[n]*normalisation[n];}
1028 length = sqrt(length);
1032 for(
unsigned n=0;n<
Ndof;n++)
1034 problem_pt->
Dof_pt.push_back(&
Y[n]);
1035 Y[n] = eigenvector[n]/length;
1036 Phi[n] = normalisation[n];
1055 unsigned raw_ndof = elem_pt->
ndof();
1060 return (2*raw_ndof + 1);
1064 return (raw_ndof+1);
1072 std::ostringstream error_stream;
1073 error_stream <<
"The Solve_which_system flag can only take values 0, 1, 2" 1076 OOMPH_CURRENT_FUNCTION,
1077 OOMPH_EXCEPTION_LOCATION);
1087 const unsigned &ieqn_local)
1090 unsigned raw_ndof = elem_pt->
ndof();
1092 unsigned long global_eqn=0;
1094 if(ieqn_local < raw_ndof)
1096 global_eqn = elem_pt->
eqn_number(ieqn_local);
1100 else if(ieqn_local==raw_ndof)
1108 global_eqn =
Ndof + 1 + elem_pt->
eqn_number(ieqn_local - 1 - raw_ndof);
1122 unsigned raw_ndof = elem_pt->
ndof();
1142 residuals[raw_ndof] = 0.0;
1157 for(
unsigned i=0;
i<raw_ndof;
i++)
1159 residuals[raw_ndof+1+
i] = 0.0;
1160 for(
unsigned j=0;j<raw_ndof;j++)
1162 residuals[raw_ndof+1+
i] += jacobian(
i,j)*
Y[elem_pt->
eqn_number(j)];
1168 residuals[raw_ndof] +=
1169 (
Phi[global_eqn]*
Y[global_eqn])/
Count[global_eqn];
1175 std::ostringstream error_stream;
1176 error_stream <<
"The Solve_which_system flag can only take values 0, 1, 2" 1179 OOMPH_CURRENT_FUNCTION,
1180 OOMPH_EXCEPTION_LOCATION);
1195 unsigned augmented_ndof =
ndof(elem_pt);
1197 unsigned raw_ndof = elem_pt->
ndof();
1221 const double FD_step = 1.0e-8;
1226 double init = *unknown_pt;
1238 for(
unsigned n=0;n<raw_ndof;n++)
1240 jacobian(n,augmented_ndof-1) = (newres[n] - residuals[n])/FD_step;
1251 for(
unsigned n=0;n<raw_ndof;n++)
1254 jacobian(augmented_ndof-1,n)
1273 for(
unsigned n=0;n<raw_ndof;n++)
1275 for(
unsigned m=0;m<raw_ndof;m++)
1277 jacobian(raw_ndof+1+n,raw_ndof+1+m) = jacobian(n,m);
1282 const double FD_step = 1.0e-8;
1287 double init = *unknown_pt;
1297 for(
unsigned n=0;n<raw_ndof;n++)
1299 jacobian(n,raw_ndof) = (newres[n] - residuals[n])/FD_step;
1302 for(
unsigned l=0;l<raw_ndof;l++)
1304 jacobian(raw_ndof+1+n,raw_ndof)
1305 += (newjac(n,l) - jacobian(n,l))*
Y[elem_pt->
eqn_number(l)]/
1318 for(
unsigned n=0;n<raw_ndof;n++)
1320 unsigned long global_eqn =
eqn_number(elem_pt,n);
1323 double init = *unknown_pt;
1331 for(
unsigned k=0;k<raw_ndof;k++)
1334 for(
unsigned l=0;l<raw_ndof;l++)
1336 jacobian(raw_ndof+1+k,n)
1337 += (newjac(k,l) - jacobian(k,l))*
Y[elem_pt->
eqn_number(l)]/
1347 for(
unsigned n=0;n<raw_ndof;n++)
1349 unsigned global_eqn = elem_pt->
eqn_number(n);
1350 jacobian(raw_ndof,raw_ndof+1+n)
1351 =
Phi[global_eqn]/
Count[global_eqn];
1376 std::ostringstream error_stream;
1377 error_stream <<
"The Solve_which_system flag can only take values 0, 1, 2" 1380 OOMPH_CURRENT_FUNCTION,
1381 OOMPH_EXCEPTION_LOCATION);
1394 double*
const ¶meter_pt,
1398 unsigned raw_ndof = elem_pt->
ndof();
1418 dres_dparam[raw_ndof] = 0.0;
1430 dres_dparam[raw_ndof] = 0.0;
1433 for(
unsigned i=0;
i<raw_ndof;
i++)
1435 dres_dparam[raw_ndof+1+
i] = 0.0;
1436 for(
unsigned j=0;j<raw_ndof;j++)
1438 dres_dparam[raw_ndof+1+
i] += djac_dparam(
i,j)*
1446 std::ostringstream error_stream;
1447 error_stream <<
"The Solve_which_system flag can only take values 0, 1, 2" 1450 OOMPH_CURRENT_FUNCTION,
1451 OOMPH_EXCEPTION_LOCATION);
1462 double*
const ¶meter_pt,
1466 std::ostringstream error_stream;
1468 "This function has not been implemented because it is not required\n";
1469 error_stream <<
"in standard problems.\n";
1471 "If you find that you need it, you will have to implement it!\n\n";
1474 OOMPH_CURRENT_FUNCTION,
1475 OOMPH_EXCEPTION_LOCATION);
1489 std::ostringstream error_stream;
1491 "This function has not been implemented because it is not required\n";
1492 error_stream <<
"in standard problems.\n";
1494 "If you find that you need it, you will have to implement it!\n\n";
1497 OOMPH_CURRENT_FUNCTION,
1498 OOMPH_EXCEPTION_LOCATION);
1509 eigenfunction.resize(1);
1512 eigenfunction[0].build(&dist,0.0);
1514 for(
unsigned n=0;n<
Ndof;n++)
1516 eigenfunction[0][n] =
Y[n];
1533 if(block_fold_solver_pt)
1538 delete block_fold_solver_pt;
1612 for(
unsigned n=0;n<
Ndof;n++)
1634 if(B_pt!=0) {
delete B_pt;}
1635 if(C_pt!=0) {
delete C_pt;}
1636 if(D_pt!=0) {
delete D_pt;}
1637 if(dJy_dparam_pt!=0) {
delete dJy_dparam_pt;}
1647 std::cout <<
"Block pitchfork solve" << std::endl;
1656 this->build_distribution(aug_dist);
1662 OOMPH_CURRENT_FUNCTION,
1663 OOMPH_EXCEPTION_LOCATION);
1692 Linear_solver_pt->enable_resolve();
1694 Linear_solver_pt->solve(problem_pt,x1);
1699 if(B_pt!=0) {
delete B_pt;}
1700 B_pt =
new DoubleVector(Linear_solver_pt->distribution_pt(),0.0);
1701 if(C_pt!=0) {
delete C_pt;}
1702 C_pt =
new DoubleVector(Linear_solver_pt->distribution_pt(),0.0);
1703 if(D_pt!=0) {
delete D_pt;}
1704 D_pt =
new DoubleVector(Linear_solver_pt->distribution_pt(),0.0);
1706 if(dJy_dparam_pt!=0) {
delete dJy_dparam_pt;}
1719 for(
unsigned n=0;n<n_dof_local;n++) {F[n] = dRdparam[n];}
1724 #ifdef OOMPH_HAS_MPI 1729 if((problem_pt->
distributed()) && (my_rank!=0)) {offset=0;}
1731 for(
unsigned n=0;n<n_dof_local;n++)
1732 {(*dJy_dparam_pt)[n] = dRdparam[n_dof_local + offset + n];}
1739 Linear_solver_pt->resolve(F,*C_pt);
1740 Linear_solver_pt->resolve(psi,*D_pt);
1743 double psi_d = psi.
dot(*D_pt);
1744 double psi_c = psi.
dot(*C_pt);
1745 double psi_x1 = psi.
dot(x1);
1748 const double Psi = psi_d/psi_c;
1757 double parameter_residual = result[n_dof_local];
1758 #ifdef OOMPH_HAS_MPI 1762 MPI_Bcast(¶meter_residual,1,MPI_DOUBLE,0,
1767 double x2 = (psi_x1 - parameter_residual)/psi_c;
1771 D_and_X1[0].build(Linear_solver_pt->distribution_pt(),0.0);
1772 D_and_X1[1].build(Linear_solver_pt->distribution_pt(),0.0);
1775 const unsigned n_dof_local_linear_solver =
1776 Linear_solver_pt->distribution_pt()->nrow_local();
1777 for(
unsigned n=0;n<n_dof_local_linear_solver;n++)
1779 const double C_ = (*C_pt)[n];
1780 D_and_X1[0][n] = (*D_pt)[n] - Psi*C_;
1781 D_and_X1[1][n] = x1[n] - x2*C_;
1792 #ifdef OOMPH_HAS_MPI 1799 handler_pt->
Y,D_and_X1,Jprod_D_and_X1);
1807 for(
unsigned n=0;n<n_dof_local;n++)
1809 G[n] = result[n_dof_local+offset+n]
1810 - Jprod_D_and_X1[1][n] - x2*dRdparam[n_dof_local+offset+n];
1811 Jprod_D_and_X1[0][n] *= -1.0;
1812 Jprod_D_and_X1[0][n] -= Psi*dRdparam[n_dof_local+offset+n];
1818 Jprod_D_and_X1[0].redistribute(Linear_solver_pt->distribution_pt());
1819 Jprod_D_and_X1[1].redistribute(Linear_solver_pt->distribution_pt());
1822 Linear_solver_pt->resolve(Jprod_D_and_X1[0],*B_pt);
1824 DoubleVector x3(Linear_solver_pt->distribution_pt(),0.0);
1825 Linear_solver_pt->resolve(G,x3);
1828 double l_x3 = psi.
dot(x3);
1829 double l_b = psi.
dot(*B_pt);
1834 double sigma_residual = result[2*(n_dof_local+offset)-1];
1835 #ifdef OOMPH_HAS_MPI 1839 MPI_Bcast(&sigma_residual,1,MPI_DOUBLE,0,
1845 const double delta_sigma = (l_x3 - sigma_residual)/l_b;
1846 const double delta_lambda = x2 - delta_sigma*Psi;
1852 DoubleVector res1(Linear_solver_pt->distribution_pt());
1853 DoubleVector res2(Linear_solver_pt->distribution_pt());
1855 for(
unsigned n=0;n<n_dof_local_linear_solver;n++)
1858 x1[n] - delta_lambda*(*C_pt)[n] - delta_sigma*(*D_pt)[n];
1859 res2[n] = x3[n] - delta_sigma*(*B_pt)[n];
1867 for(
unsigned n=0;n<n_dof_local;n++)
1869 result[n] = res1[n];
1870 result[n_dof_local + offset + n] = res2[n];
1875 #ifdef OOMPH_HAS_MPI 1879 result[n_dof_local] = delta_lambda;
1880 result[2*n_dof_local+1] = delta_sigma;
1888 static_cast<int>(std::fabs(psi_c*l_b)/(psi_c*l_b));
1900 Linear_solver_pt->disable_resolve();
1901 delete B_pt; B_pt=0;
1902 delete C_pt; C_pt=0;
1903 delete D_pt; D_pt=0;
1904 delete dJy_dparam_pt; dJy_dparam_pt = 0;
1920 std::cout <<
"Block pitchfork resolve" << std::endl;
1924 throw OomphLibError(
"The required vectors have not been stored",
1925 OOMPH_CURRENT_FUNCTION,
1926 OOMPH_EXCEPTION_LOCATION);
1952 result.
build(&aug_dist,0.0);
1988 DoubleVector x1(Linear_solver_pt->distribution_pt(),0.0);
1989 DoubleVector x3(Linear_solver_pt->distribution_pt(),0.0);
1993 const unsigned n_dof_local = input_x1.
nrow_local();
1996 for(
unsigned n=0;n<n_dof_local;n++) {input_x1[n] = rhs_local[n];}
1998 input_x1.
redistribute(Linear_solver_pt->distribution_pt());
2001 Linear_solver_pt->enable_resolve();
2003 Linear_solver_pt->resolve(input_x1,x1);
2011 double psi_d = psi.
dot(*D_pt);
2012 double psi_c = psi.
dot(*C_pt);
2013 double psi_x1 = psi.
dot(x1);
2016 const double Psi = psi_d/psi_c;
2020 double parameter_residual = rhs_local[n_dof_local];
2021 #ifdef OOMPH_HAS_MPI 2025 MPI_Bcast(¶meter_residual,1,MPI_DOUBLE,0,
2030 double x2 = (psi_x1 - parameter_residual)/psi_c;
2035 X1[0].build(Linear_solver_pt->distribution_pt(),0.0);
2037 const unsigned n_dof_local_linear_solver =
2038 Linear_solver_pt->distribution_pt()->nrow_local();
2039 for(
unsigned n=0;n<n_dof_local_linear_solver;n++)
2041 X1[0][n] = x1[n] - x2*(*C_pt)[n];
2051 #ifdef OOMPH_HAS_MPI 2060 #ifdef OOMPH_HAS_MPI 2065 if((problem_pt->
distributed()) && (my_rank!=0)) {offset=0;}
2073 for(
unsigned n=0;n<n_dof_local;n++)
2075 Mod_Jprod_X1[n] = rhs_local[n_dof_local+offset+n] - Jprod_X1[0][n]
2076 - x2*(*dJy_dparam_pt)[n];
2080 Mod_Jprod_X1.
redistribute(Linear_solver_pt->distribution_pt());
2083 Linear_solver_pt->resolve(Mod_Jprod_X1,x3);
2086 double l_x3 = psi.
dot(x3);
2087 double l_b = psi.
dot(*B_pt);
2092 double sigma_residual = rhs_local[2*(n_dof_local+offset)-1];
2093 #ifdef OOMPH_HAS_MPI 2097 MPI_Bcast(&sigma_residual,1,MPI_DOUBLE,0,
2103 const double delta_sigma = (l_x3 - sigma_residual)/l_b;
2104 const double delta_lambda = x2 - delta_sigma*Psi;
2107 DoubleVector res1(Linear_solver_pt->distribution_pt());
2108 DoubleVector res2(Linear_solver_pt->distribution_pt());
2110 for(
unsigned n=0;n<n_dof_local_linear_solver;n++)
2112 res1[n] = x1[n] - delta_lambda*(*C_pt)[n] - delta_sigma*(*D_pt)[n];
2113 res2[n] = x3[n] - delta_sigma*(*B_pt)[n];
2121 for(
unsigned n=0;n<n_dof_local;n++)
2123 result[n] = res1[n];
2124 result[n_dof_local + offset + n] = res2[n];
2129 #ifdef OOMPH_HAS_MPI 2133 result[n_dof_local] = delta_lambda;
2134 result[2*n_dof_local+1] = delta_sigma;
2140 Linear_solver_pt->disable_resolve();
2156 if(Alpha_pt!=0) {
delete Alpha_pt;}
2157 if(E_pt!=0) {
delete E_pt;}
2167 std::cout <<
"Augmented pitchfork solve" << std::endl;
2174 throw OomphLibError(
"The result vector must not be distributed",
2175 OOMPH_CURRENT_FUNCTION,
2176 OOMPH_EXCEPTION_LOCATION);
2190 unsigned n_dof = problem_pt->
ndof();
2195 this->build_distribution(dist);
2198 if (!result.
built())
2200 result.
build(this->distribution_pt(),0.0);
2204 DoubleVector a(this->distribution_pt(),0.0), b(this->distribution_pt(),0.0);
2207 if(Alpha_pt!=0) {
delete Alpha_pt;}
2208 Alpha_pt =
new DoubleVector(this->distribution_pt(),0.0);
2211 Linear_solver_pt->enable_resolve();
2213 Linear_solver_pt->solve(problem_pt,a);
2217 for(
unsigned n=0;n<(n_dof-1);++n) {psi[n] = handler_pt->
Psi[n];}
2222 Linear_solver_pt->resolve(psi,*Alpha_pt);
2226 double dof_length=0.0, a_length=0.0, alpha_length=0.0;
2227 for(
unsigned n=0;n<n_dof;n++)
2229 if(std::fabs(problem_pt->
dof(n)) > dof_length)
2230 {dof_length = std::fabs(problem_pt->
dof(n));}
2231 if(std::fabs(a[n]) > a_length) {a_length = std::fabs(a[n]);}
2232 if(std::fabs((*Alpha_pt)[n]) > alpha_length)
2233 {alpha_length = std::fabs((*Alpha_pt)[n]);}
2236 double a_mult = dof_length/a_length;
2237 double alpha_mult = dof_length/alpha_length;
2238 const double FD_step = 1.0e-8;
2244 Jprod_alpha(this->distribution_pt(),0.0);
2248 for(
unsigned long e = 0;
e<n_element;
e++)
2252 unsigned n_var = handler_pt->
ndof(elem_pt);
2263 for(
unsigned n=0;n<n_var;n++)
2266 dof_bac[n] = problem_pt->
dof(eqn_number);
2277 for(
unsigned n=0;n<n_var;n++)
2280 problem_pt->
dof(eqn_number) = dof_bac[n];
2282 problem_pt->
dof(eqn_number) += alpha_mult*(*Alpha_pt)[
eqn_number];
2288 handler_pt->
get_jacobian(elem_pt,res_elemental,jac_alpha);
2291 for(
unsigned n=0;n<n_var;n++)
2294 problem_pt->
dof(eqn_number) = dof_bac[n];
2300 for(
unsigned n=0;n<(n_var-1);n++)
2303 double prod_a=0.0, prod_alpha=0.0;
2304 for(
unsigned m=0;m<(n_var-1);m++)
2306 unsigned unknown = handler_pt->
eqn_number(elem_pt,m);
2307 prod_a += (jac_a(n,m) - jac(n,m))*
2308 handler_pt->
Y[unknown];
2309 prod_alpha += (jac_alpha(n,m) - jac(n,m))*
2310 handler_pt->
Y[unknown];
2313 Jprod_alpha[
eqn_number] += prod_alpha/alpha_mult;
2317 Jprod_alpha[n_dof-1] = 0.0;
2318 Jprod_a[n_dof-1] = 0.0;
2323 for(
unsigned n=0;n<n_dof-1;n++)
2325 b[n] = result[n_dof+n] - Jprod_a[n];
2327 b[n_dof-1] = result[2*n_dof-1];
2331 if(E_pt!=0) {
delete E_pt;}
2336 Linear_solver_pt->resolve(b,f);
2337 Linear_solver_pt->resolve(Jprod_alpha,*E_pt);
2340 const double e_final = (*E_pt)[n_dof-1];
2342 const double d_final = -f[n_dof-1]/e_final;
2344 for(
unsigned n=0;n<n_dof-1;n++)
2346 result[n] = a[n] - (*Alpha_pt)[n]*d_final;
2347 result[n_dof+n] = f[n] + (*E_pt)[n]*d_final;
2350 result[n_dof-1] = a[n_dof-1] - (*Alpha_pt)[n_dof-1]*d_final;
2351 result[2*n_dof-1] = d_final;
2355 static_cast<int>(std::fabs(e_final)/e_final);
2365 Linear_solver_pt->disable_resolve();
2366 delete Alpha_pt; Alpha_pt=0;
2367 delete E_pt; E_pt=0;
2383 std::cout <<
"Augmented pitchfork resolve" << std::endl;
2387 throw OomphLibError(
"The required vectors have not been stored",
2388 OOMPH_CURRENT_FUNCTION,
2389 OOMPH_EXCEPTION_LOCATION);
2401 unsigned n_dof = problem_pt->
ndof();
2406 this->build_distribution(dist);
2409 if (!result.
built())
2411 result.
build(this->distribution_pt(),0.0);
2416 DoubleVector a(this->distribution_pt(),0.0), b(this->distribution_pt(),0.0);
2419 for(
unsigned n=0;n<n_dof;n++) {a[n] = rhs[n];}
2421 Linear_solver_pt->enable_resolve();
2428 Linear_solver_pt->resolve(input_a,a);
2432 double dof_length=0.0, a_length=0.0;
2433 for(
unsigned n=0;n<n_dof;n++)
2435 if(std::fabs(problem_pt->
dof(n)) > dof_length)
2436 {dof_length = std::fabs(problem_pt->
dof(n));}
2438 if(std::fabs(a[n]) > a_length) {a_length = std::fabs(a[n]);}
2440 double a_mult = dof_length/a_length;
2441 const double FD_step = 1.0e-8;
2448 for(
unsigned long e = 0;
e<n_element;
e++)
2452 unsigned n_var = handler_pt->
ndof(elem_pt);
2463 for(
unsigned n=0;n<n_var;n++)
2466 dof_bac[n] = problem_pt->
dof(eqn_number);
2477 for(
unsigned n=0;n<n_var;n++)
2480 problem_pt->
dof(eqn_number) = dof_bac[n];
2486 for(
unsigned n=0;n<(n_var-1);n++)
2490 for(
unsigned m=0;m<(n_var-1);m++)
2492 unsigned unknown = handler_pt->
eqn_number(elem_pt,m);
2493 prod_a += (jac_a(n,m) - jac(n,m))*
2494 handler_pt->
Y[unknown];
2500 Jprod_a[n_dof-1] = 0.0;
2503 for(
unsigned n=0;n<n_dof-1;n++)
2505 b[n] = rhs[n_dof+n] - Jprod_a[n];
2507 b[n_dof-1] = rhs[2*n_dof-1];
2511 Linear_solver_pt->resolve(b,f);
2514 const double d_final = -f[n_dof-1]/(*E_pt)[n_dof-1];
2516 for(
unsigned n=0;n<n_dof-1;n++)
2518 result[n] = a[n] - (*Alpha_pt)[n]*d_final;
2519 result[n_dof+n] = f[n] + (*E_pt)[n]*d_final;
2522 result[n_dof-1] = a[n_dof-1] - (*Alpha_pt)[n_dof-1]*d_final;
2523 result[2*n_dof-1] = d_final;
2525 Linear_solver_pt->disable_resolve();
2541 &assembly_handler_pt,
2542 double*
const ¶meter_pt,
2556 #ifdef OOMPH_HAS_MPI 2564 #ifdef OOMPH_HAS_MPI 2578 #ifdef OOMPH_HAS_MPI 2584 unsigned n_non_halo_element_local=0;
2585 for(
unsigned e=0;
e<n_element;
e++)
2588 #ifdef OOMPH_HAS_MPI 2594 ++n_non_halo_element_local;
2596 unsigned n_var = assembly_handler_pt->
ndof(elem_pt);
2597 for(
unsigned n=0;n<n_var;n++)
2601 #ifdef OOMPH_HAS_MPI 2607 #ifdef OOMPH_HAS_MPI 2614 MPI_Allreduce(&n_non_halo_element_local,&
Nelement,1,MPI_UNSIGNED,MPI_SUM,
2621 Nelement = n_non_halo_element_local;
2624 #ifdef OOMPH_HAS_MPI 2635 double length = symmetry_vector.
norm();
2644 #ifdef OOMPH_HAS_MPI 2649 (
"The symmetry vector must have the same distribution as the dofs\n",
2650 OOMPH_CURRENT_FUNCTION,
2651 OOMPH_EXCEPTION_LOCATION);
2657 for(
unsigned n=0;n<n_dof_local;n++)
2661 Psi[n] =
Y[n] =
C[n] = symmetry_vector[n]/length;
2665 #ifdef OOMPH_HAS_MPI 2680 #ifdef OOMPH_HAS_MPI 2683 unsigned augmented_first_row=0;
2684 unsigned augmented_n_row_local=0;
2689 unsigned global_eqn_count=0;
2690 for(
int d=0;d<n_proc;d++)
2693 if(my_rank==d) {augmented_first_row = global_eqn_count;}
2698 for(
unsigned n=0;n<n_row_local;n++)
2710 for(
unsigned n=0;n<n_row_local;n++)
2723 {augmented_n_row_local = global_eqn_count - augmented_first_row;}
2729 augmented_first_row,
2730 augmented_n_row_local);
2761 if(block_pitchfork_solver_pt)
2767 delete block_pitchfork_solver_pt;
2777 if(augmented_block_pitchfork_solver_pt)
2783 delete augmented_block_pitchfork_solver_pt;
2803 unsigned raw_ndof = elem_pt->
ndof();
2809 return (2*raw_ndof + 2);
2813 return (raw_ndof+1);
2821 std::ostringstream error_stream;
2822 error_stream <<
"The Solve_which_system flag can only take values 0, 1, 2" 2825 OOMPH_CURRENT_FUNCTION,
2826 OOMPH_EXCEPTION_LOCATION);
2832 const unsigned &ieqn_local)
2835 unsigned raw_ndof = elem_pt->
ndof();
2836 unsigned long global_eqn=0;
2843 global_eqn = elem_pt->
eqn_number(ieqn_local);
2849 #ifdef OOMPH_HAS_MPI 2853 "Block Augmented solver not implemented for distributed case\n",
2854 OOMPH_CURRENT_FUNCTION,
2855 OOMPH_EXCEPTION_LOCATION);
2862 if(ieqn_local < raw_ndof)
2867 else if(ieqn_local == raw_ndof)
2873 else if(ieqn_local < (2*raw_ndof + 1))
2896 unsigned raw_ndof = elem_pt->
ndof();
2907 for(
unsigned i=0;
i<raw_ndof;
i++)
2924 residuals[raw_ndof] = 0.0;
2926 for(
unsigned i=0;
i<raw_ndof;
i++)
2933 residuals[raw_ndof] +=
2949 residuals[raw_ndof] = 0.0;
2950 residuals[2*raw_ndof+1] = -1.0/
Nelement;
2954 for(
unsigned i=0;
i<raw_ndof;
i++)
2957 residuals[raw_ndof+1+
i] = 0.0;
2958 for(
unsigned j=0;j<raw_ndof;j++)
2960 unsigned local_unknown = elem_pt->
eqn_number(j);
2961 residuals[raw_ndof+1+
i] += jacobian(
i,j)*
Y.
global_value(local_unknown);
2969 residuals[raw_ndof] +=
2981 std::ostringstream error_stream;
2982 error_stream <<
"The Solve_which_system flag can only take values 0, 1, 2" 2985 OOMPH_CURRENT_FUNCTION,
2986 OOMPH_EXCEPTION_LOCATION);
3000 unsigned augmented_ndof =
ndof(elem_pt);
3001 unsigned raw_ndof = elem_pt->
ndof();
3013 for(
unsigned i=0;
i<raw_ndof;
i++)
3034 const double FD_step = 1.0e-8;
3039 double init = *unknown_pt;
3051 for(
unsigned n=0;n<raw_ndof;n++)
3053 jacobian(n,augmented_ndof-1) = (newres[n] - residuals[n])/FD_step;
3064 for(
unsigned n=0;n<raw_ndof;n++)
3067 jacobian(augmented_ndof-1,n)
3084 for(
unsigned n=0;n<raw_ndof;n++)
3086 for(
unsigned m=0;m<raw_ndof;m++)
3088 jacobian(raw_ndof+1+n,raw_ndof+1+m) = jacobian(n,m);
3098 jacobian(2*raw_ndof+1,raw_ndof+1+n) =
C.
global_value(local_eqn)/
3103 const double FD_step = 1.0e-8;
3108 for(
unsigned n=0;n<raw_ndof;++n)
3113 double init = *unknown_pt;
3119 for(
unsigned m=0;m<raw_ndof;m++)
3121 jacobian(raw_ndof+1+m,n) =
3122 (newres_p[raw_ndof+1+m] - residuals[raw_ndof+1+m])/(FD_step);
3133 double init = *unknown_pt;
3141 for(
unsigned m=0;m<raw_ndof;m++)
3143 jacobian(m,raw_ndof) =
3144 (newres_p[m] - residuals[m])/FD_step;
3147 for(
unsigned m=raw_ndof+1;m<augmented_ndof-1;m++)
3149 jacobian(m,raw_ndof) =
3150 (newres_p[m] - residuals[m])/FD_step;
3161 std::ostringstream error_stream;
3162 error_stream <<
"The Solve_which_system flag can only take values 0, 1, 2" 3165 OOMPH_CURRENT_FUNCTION,
3166 OOMPH_EXCEPTION_LOCATION);
3183 unsigned raw_ndof = elem_pt->
ndof();
3205 dres_dparam[raw_ndof] = 0.0;
3220 dres_dparam[raw_ndof] = 0.0;
3221 dres_dparam[2*raw_ndof+1] = 0.0;
3225 for(
unsigned i=0;
i<raw_ndof;
i++)
3227 dres_dparam[raw_ndof+1+
i] = 0.0;
3228 for(
unsigned j=0;j<raw_ndof;j++)
3230 unsigned local_unknown = elem_pt->
eqn_number(j);
3231 dres_dparam[raw_ndof+1+
i] +=
3239 std::ostringstream error_stream;
3240 error_stream <<
"The Solve_which_system flag can only take values 0, 1, 2" 3243 OOMPH_CURRENT_FUNCTION,
3244 OOMPH_EXCEPTION_LOCATION);
3258 double*
const ¶meter_pt,
3262 std::ostringstream error_stream;
3264 "This function has not been implemented because it is not required\n";
3265 error_stream <<
"in standard problems.\n";
3267 "If you find that you need it, you will have to implement it!\n\n";
3270 OOMPH_CURRENT_FUNCTION,
3271 OOMPH_EXCEPTION_LOCATION);
3298 eigenfunction.resize(1);
3302 const unsigned n_row_local = eigenfunction[0].nrow_local();
3303 for(
unsigned n=0;n<n_row_local;n++)
3305 eigenfunction[0][n] =
Y[n];
3309 #ifdef OOMPH_HAS_MPI 3321 double broadcast_data[2];
3323 broadcast_data[1] =
Sigma;
3325 MPI_Bcast(broadcast_data,2,MPI_DOUBLE,0,
3330 Sigma = broadcast_data[1];
3401 #ifdef OOMPH_HAS_MPI 3408 #ifdef OOMPH_HAS_MPI 3419 for(
unsigned n=0;n<n_dof_local;n++)
3426 #ifdef OOMPH_HAS_MPI 3464 if(A_pt!=0) {
delete A_pt;}
3465 if(E_pt!=0) {
delete E_pt;}
3466 if(G_pt!=0) {
delete G_pt;}
3483 throw OomphLibError(
"The result vector must not be distributed",
3484 OOMPH_CURRENT_FUNCTION,
3485 OOMPH_EXCEPTION_LOCATION);
3495 unsigned n_dof = problem_pt->
ndof();
3500 this->build_distribution(dist);
3506 const double FD_step = 1.0e-8;
3509 double *param_pt = &problem_pt->
dof(n_dof-2);
3511 double old_var = *param_pt;;
3520 for(
unsigned n=0;n<n_dof;n++)
3522 dRdparam[n] = (dRdparam[n] - result[n])/FD_step;
3526 *param_pt = old_var;
3534 n_dof = problem_pt->
ndof();
3538 this->build_distribution(dist);
3542 alpha(this->distribution_pt(),0.0);
3545 if(A_pt!=0) {
delete A_pt;}
3549 Linear_solver_pt->enable_resolve();
3552 Linear_solver_pt->solve(problem_pt,y1);
3558 for(
unsigned n=0;n<n_dof;n++) {alpha[n] = dRdparam[n];}
3561 Linear_solver_pt->resolve(alpha,*A_pt);
3568 this->build_distribution(dist);
3571 if(G_pt!=0) {
delete G_pt;}
3575 Linear_solver_pt->solve(problem_pt,*G_pt);
3582 double dof_length=0.0, a_length=0.0, y1_length=0.0;
3584 for(
unsigned n=0;n<n_dof;n++)
3586 if(std::fabs(problem_pt->
dof(n)) > dof_length)
3587 {dof_length = std::fabs(problem_pt->
dof(n));}
3588 if(std::fabs((*A_pt)[n]) > a_length) {a_length = std::fabs((*A_pt)[n]);}
3589 if(std::fabs(y1[n]) > y1_length)
3590 {y1_length = std::fabs(y1[n]);}
3593 double a_mult = dof_length/a_length;
3594 double y1_mult = dof_length/y1_length;
3608 for(
unsigned long e=0;
e<n_element;
e++)
3612 unsigned n_var = elem_pt->
ndof();
3622 for(
unsigned n=0;n<n_var;n++)
3625 dof_bac[n] = problem_pt->
dof(eqn_number);
3634 for(
unsigned n=0;n<n_var;n++)
3637 problem_pt->
dof(eqn_number) = dof_bac[n];
3646 for(
unsigned n=0;n<n_var;n++)
3649 problem_pt->
dof(eqn_number) = dof_bac[n];
3653 for(
unsigned n=0;n<n_var;n++)
3656 double prod_a1=0.0, prod_y11=0.0;
3657 double prod_a2=0.0, prod_y12=0.0;
3658 for(
unsigned m=0;m<n_var;m++)
3660 const unsigned unknown = elem_pt->
eqn_number(m);
3661 const double y = handler_pt->
Phi[unknown];
3662 const double z = handler_pt->
Psi[unknown];
3663 const double omega = handler_pt->
Omega;
3665 prod_a1 += (jac_a(n,m) - jac(n,m))*y
3666 + omega*(M_a(n,m) - M(n,m))*z;
3667 prod_y11 += (jac_y1(n,m) - jac(n,m))*y
3668 + omega*(M_y1(n,m) - M(n,m))*z;
3670 prod_a2 += (jac_a(n,m) - jac(n,m))*z
3671 - omega*(M_a(n,m) - M(n,m))*y;
3672 prod_y12 += (jac_y1(n,m) - jac(n,m))*z
3673 - omega*(M_y1(n,m) - M(n,m))*y;
3677 Jprod_a[n_dof +
eqn_number] += prod_a2/a_mult;
3678 Jprod_y1[n_dof +
eqn_number] += prod_y12/y1_mult;
3684 for(
unsigned n=0;n<2*n_dof;n++)
3686 rhs[n] = result[n_dof+n] - Jprod_y1[n];
3694 for (
unsigned i = 0;
i < 2*n_dof;
i++)
3700 Linear_solver_pt->resolve(rhs2,y2);
3703 for(
unsigned n=0;n<2*n_dof;n++)
3705 rhs[n] = dRdparam[n_dof+n] - Jprod_a[n];
3709 if(E_pt!=0) {
delete E_pt;}
3713 for (
unsigned i = 0;
i < 2*n_dof;
i++)
3717 Linear_solver_pt->resolve(rhs2,*E_pt);
3721 double dot_c = 0.0, dot_d = 0.0, dot_e = 0.0, dot_f = 0.0, dot_g=0.0;
3724 for(
unsigned n=0;n<n_dof;n++)
3727 const double Cn = handler_pt->
C[n];
3729 dot_d += Cn*y2[n_dof+n];
3730 dot_e += Cn*(*E_pt)[n];
3731 dot_f += Cn*(*E_pt)[n_dof+n];
3732 dot_g += Cn*(*G_pt)[n];
3733 dot_h += Cn*(*G_pt)[n_dof+n];
3737 double denom = dot_e*dot_h - dot_g*dot_f;
3740 double R31 = result[3*n_dof], R32 = result[3*n_dof+1];
3742 const double delta_param =
3743 ((R32 - dot_d)*dot_g - (R31 - dot_c)*dot_h)/denom;
3745 const double delta_w = -((R32 - dot_d) + dot_f*delta_param)/(dot_h);
3748 result[3*n_dof] = delta_param;
3749 result[3*n_dof+1] = delta_w;
3752 for(
unsigned n=0;n<2*n_dof;n++)
3754 result[n_dof + n] = y2[n] - (*E_pt)[n]*delta_param - (*G_pt)[n]*delta_w;
3758 for(
unsigned n=0;n<n_dof;n++)
3760 result[n] = y1[n] - (*A_pt)[n]*delta_param;
3766 static_cast<int>(std::fabs(denom)/denom);
3775 Linear_solver_pt->disable_resolve();
3776 delete A_pt; A_pt=0;
3777 delete E_pt; E_pt=0;
3778 delete G_pt; G_pt=0;
3804 throw OomphLibError(
"The result vector must not be distributed",
3805 OOMPH_CURRENT_FUNCTION,
3806 OOMPH_EXCEPTION_LOCATION);
3809 if (result2.
built())
3813 throw OomphLibError(
"The result2 vector must not be distributed",
3814 OOMPH_CURRENT_FUNCTION,
3815 OOMPH_EXCEPTION_LOCATION);
3825 unsigned n_dof = problem_pt->
ndof();
3830 this->build_distribution(dist);
3833 if (!result.
built())
3835 result.
build(this->distribution_pt(),0.0);
3837 if (!result2.
built())
3839 result2.
build(this->distribution_pt(),0.0);
3846 const double FD_step = 1.0e-8;
3849 double *param_pt = &problem_pt->
dof(n_dof-2);
3851 double old_var = *param_pt;;
3860 for(
unsigned n=0;n<n_dof;n++)
3862 dRdparam[n] = (dRdparam[n] - result[n])/FD_step;
3866 *param_pt = old_var;
3874 n_dof = problem_pt->
ndof();
3878 this->build_distribution(dist);
3882 alpha(this->distribution_pt(),0.0),
3883 y1_resolve(this->distribution_pt(),0.0);
3886 if(A_pt!=0) {
delete A_pt;}
3890 Linear_solver_pt->enable_resolve();
3893 Linear_solver_pt->solve(problem_pt,y1);
3899 for(
unsigned n=0;n<n_dof;n++) {alpha[n] = dRdparam[n];}
3902 Linear_solver_pt->resolve(alpha,*A_pt);
3905 for(
unsigned n=0;n<n_dof;n++) {alpha[n] = rhs2[n];}
3908 Linear_solver_pt->resolve(alpha,y1_resolve);
3915 this->build_distribution(dist);
3918 if(G_pt!=0) {
delete G_pt;}
3922 Linear_solver_pt->solve(problem_pt,*G_pt);
3929 double dof_length=0.0, a_length=0.0, y1_length=0.0, y1_resolve_length=0.0;
3931 for(
unsigned n=0;n<n_dof;n++)
3933 if(std::fabs(problem_pt->
dof(n)) > dof_length)
3934 {dof_length = std::fabs(problem_pt->
dof(n));}
3935 if(std::fabs((*A_pt)[n]) > a_length) {a_length = std::fabs((*A_pt)[n]);}
3936 if(std::fabs(y1[n]) > y1_length)
3937 {y1_length = std::fabs(y1[n]);}
3938 if(std::fabs(y1_resolve[n]) > y1_resolve_length)
3939 {y1_resolve_length = std::fabs(y1[n]);}
3943 double a_mult = dof_length/a_length;
3944 double y1_mult = dof_length/y1_length;
3945 double y1_resolve_mult = dof_length/y1_resolve_length;
3960 for(
unsigned long e = 0;
e<n_element;
e++)
3964 unsigned n_var = elem_pt->
ndof();
3967 jac_y1_resolve(n_var);
3975 for(
unsigned n=0;n<n_var;n++)
3978 dof_bac[n] = problem_pt->
dof(eqn_number);
3987 for(
unsigned n=0;n<n_var;n++)
3990 problem_pt->
dof(eqn_number) = dof_bac[n];
3999 for(
unsigned n=0;n<n_var;n++)
4002 problem_pt->
dof(eqn_number) = dof_bac[n];
4004 problem_pt->
dof(eqn_number) += y1_resolve_mult*y1_resolve[
eqn_number];
4011 for(
unsigned n=0;n<n_var;n++)
4014 problem_pt->
dof(eqn_number) = dof_bac[n];
4018 for(
unsigned n=0;n<n_var;n++)
4021 double prod_a1=0.0, prod_y11=0.0, prod_y1_resolve1 = 0.0;
4022 double prod_a2=0.0, prod_y12=0.0, prod_y1_resolve2 = 0.0;
4023 for(
unsigned m=0;m<n_var;m++)
4025 const unsigned unknown = elem_pt->
eqn_number(m);
4026 const double y = handler_pt->
Phi[unknown];
4027 const double z = handler_pt->
Psi[unknown];
4028 const double omega = handler_pt->
Omega;
4030 prod_a1 += (jac_a(n,m) - jac(n,m))*y
4031 + omega*(M_a(n,m) - M(n,m))*z;
4032 prod_y11 += (jac_y1(n,m) - jac(n,m))*y
4033 + omega*(M_y1(n,m) - M(n,m))*z;
4034 prod_y1_resolve1 += (jac_y1_resolve(n,m) - jac(n,m))*y
4035 + omega*(M_y1_resolve(n,m) - M(n,m))*z;
4037 prod_a2 += (jac_a(n,m) - jac(n,m))*z
4038 - omega*(M_a(n,m) - M(n,m))*y;
4039 prod_y12 += (jac_y1(n,m) - jac(n,m))*z
4040 - omega*(M_y1(n,m) - M(n,m))*y;
4041 prod_y1_resolve2 += (jac_y1_resolve(n,m) - jac(n,m))*z
4042 - omega*(M_y1_resolve(n,m) - M(n,m))*y;
4046 Jprod_y1_resolve[
eqn_number] += prod_y1_resolve1/y1_resolve_mult;
4047 Jprod_a[n_dof +
eqn_number] += prod_a2/a_mult;
4048 Jprod_y1[n_dof +
eqn_number] += prod_y12/y1_mult;
4049 Jprod_y1_resolve[n_dof +
eqn_number] += prod_y1_resolve2/y1_resolve_mult;
4055 for(
unsigned n=0;n<2*n_dof;n++)
4057 rhs[n] = result[n_dof+n] - Jprod_y1[n];
4065 for (
unsigned i = 0;
i < 2*n_dof;
i++)
4067 temp_rhs[
i] = rhs[
i];
4069 Linear_solver_pt->resolve(temp_rhs,y2);
4072 for(
unsigned n=0;n<2*n_dof;n++)
4074 rhs[n] = dRdparam[n_dof+n] - Jprod_a[n];
4078 if(E_pt!=0) {
delete E_pt;}
4082 for (
unsigned i = 0;
i < 2* n_dof;
i++)
4084 temp_rhs[
i] = rhs[
i];
4086 Linear_solver_pt->resolve(temp_rhs,*E_pt);
4089 for(
unsigned n=0;n<2*n_dof;n++)
4091 rhs[n] = rhs2[n_dof+n] - Jprod_y1_resolve[n];
4095 for (
unsigned i = 0;
i < 2* n_dof;
i++)
4097 temp_rhs[
i] = rhs[
i];
4099 Linear_solver_pt->resolve(temp_rhs,y2_resolve);
4104 double dot_c = 0.0, dot_d = 0.0, dot_e = 0.0, dot_f = 0.0, dot_g=0.0;
4107 double dot_c_resolve = 0.0, dot_d_resolve = 0.0;
4109 for(
unsigned n=0;n<n_dof;n++)
4112 const double Cn = handler_pt->
C[n];
4114 dot_d += Cn*y2[n_dof+n];
4115 dot_c_resolve += Cn*y2_resolve[n];
4116 dot_d_resolve += Cn*y2_resolve[n_dof+n];
4117 dot_e += Cn*(*E_pt)[n];
4118 dot_f += Cn*(*E_pt)[n_dof+n];
4119 dot_g += Cn*(*G_pt)[n];
4120 dot_h += Cn*(*G_pt)[n_dof+n];
4124 double denom = dot_e*dot_h - dot_g*dot_f;
4127 double R31 = result[3*n_dof], R32 = result[3*n_dof+1];
4129 const double delta_param =
4130 ((R32 - dot_d)*dot_g - (R31 - dot_c)*dot_h)/denom;
4132 const double delta_w = -((R32 - dot_d) + dot_f*delta_param)/(dot_h);
4135 double R31_resolve = rhs2[3*n_dof], R32_resolve = rhs2[3*n_dof+1];
4137 const double delta_param_resolve =
4138 ((R32_resolve - dot_d_resolve)*dot_g -
4139 (R31_resolve - dot_c_resolve)*dot_h)/denom;
4141 const double delta_w_resolve =
4142 -((R32_resolve - dot_d_resolve) + dot_f*delta_param_resolve)/(dot_h);
4146 result[3*n_dof] = delta_param;
4147 result[3*n_dof+1] = delta_w;
4150 for(
unsigned n=0;n<2*n_dof;n++)
4152 result[n_dof + n] = y2[n] - (*E_pt)[n]*delta_param - (*G_pt)[n]*delta_w;
4156 for(
unsigned n=0;n<n_dof;n++)
4158 result[n] = y1[n] - (*A_pt)[n]*delta_param;
4162 result2[3*n_dof] = delta_param_resolve;
4163 result2[3*n_dof+1] = delta_w_resolve;
4166 for(
unsigned n=0;n<2*n_dof;n++)
4168 result2[n_dof + n] = y2_resolve[n] - (*E_pt)[n]*delta_param_resolve
4169 - (*G_pt)[n]*delta_w_resolve;
4173 for(
unsigned n=0;n<n_dof;n++)
4175 result2[n] = y1_resolve[n] - (*A_pt)[n]*delta_param_resolve;
4182 static_cast<int>(std::fabs(denom)/denom);
4191 Linear_solver_pt->disable_resolve();
4192 delete A_pt; A_pt=0;
4193 delete E_pt; E_pt=0;
4194 delete G_pt; G_pt=0;
4211 throw OomphLibError(
"resolve() is not implemented for this solver",
4212 OOMPH_CURRENT_FUNCTION,
4213 OOMPH_EXCEPTION_LOCATION);
4228 double*
const ¶meter_pt) :
4249 for(
unsigned e=0;
e<n_element;
e++)
4253 unsigned n_var = elem_pt->
ndof();
4254 for(
unsigned n=0;n<n_var;n++)
4279 linear_solver_pt->
solve(problem_pt,x);
4290 linear_solver_pt->
resolve(input_x,x);
4303 double length = 0.0;
4304 for(
unsigned n=0;n<
Ndof;n++) {length += x[n]*x[n];}
4305 length = sqrt(length);
4310 for(
unsigned n=0;n<
Ndof;n++)
4313 C[n] =
Phi[n] = -x[n]/length;
4318 for(
unsigned n=0;n<
Ndof;n+=2)
4334 for(
unsigned n=0;n<
Ndof;n++)
4339 problem_pt->
Dof_pt.push_back(parameter_pt);
4359 double*
const ¶meter_pt,
4360 const double &
omega,
4378 for(
unsigned e=0;
e<n_element;
e++)
4382 unsigned n_var = elem_pt->
ndof();
4383 for(
unsigned n=0;n<n_var;n++)
4391 double length = 0.0;
4392 for(
unsigned n=0;n<
Ndof;n++) {length += phi[n]*phi[n];}
4393 length = sqrt(length);
4397 for(
unsigned n=0;n<
Ndof;n++)
4400 C[n] =
Phi[n] = phi[n]/length;
4401 Psi[n] = psi[n]/length;
4405 for(
unsigned n=0;n<
Ndof;n++)
4411 problem_pt->
Dof_pt.push_back(parameter_pt);
4433 if(block_hopf_solver_pt)
4438 delete block_hopf_solver_pt;
4454 unsigned raw_ndof = elem_pt->
ndof();
4459 return (3*raw_ndof + 2);
4467 return (2*raw_ndof);
4471 throw OomphLibError(
"Solve_which_system can only be 0,1 or 2",
4472 OOMPH_CURRENT_FUNCTION,
4473 OOMPH_EXCEPTION_LOCATION);
4481 const unsigned &ieqn_local)
4484 unsigned raw_ndof = elem_pt->
ndof();
4485 unsigned long global_eqn;
4486 if(ieqn_local < raw_ndof)
4488 global_eqn = elem_pt->
eqn_number(ieqn_local);
4490 else if(ieqn_local < 2*raw_ndof)
4494 else if(ieqn_local < 3*raw_ndof)
4496 global_eqn = 2*
Ndof + elem_pt->
eqn_number(ieqn_local - 2*raw_ndof);
4498 else if(ieqn_local == 3*raw_ndof)
4500 global_eqn = 3*
Ndof;
4504 global_eqn = 3*
Ndof+1;
4519 unsigned raw_ndof = elem_pt->
ndof();
4526 residuals[3*raw_ndof] = -1.0/
4528 residuals[3*raw_ndof+1] = 0.0;
4531 for(
unsigned i=0;
i<raw_ndof;
i++)
4533 residuals[raw_ndof+
i] = 0.0;
4534 residuals[2*raw_ndof+
i] = 0.0;
4535 for(
unsigned j=0;j<raw_ndof;j++)
4537 unsigned global_unknown = elem_pt->
eqn_number(j);
4539 residuals[raw_ndof+
i] +=
4540 jacobian(
i,j)*
Phi[global_unknown] +
Omega*M(
i,j)*
Psi[global_unknown];
4542 residuals[2*raw_ndof+
i] +=
4543 jacobian(
i,j)*Psi[global_unknown] -
Omega*M(
i,j)*
Phi[global_unknown];
4549 residuals[3*raw_ndof] += (
Phi[global_eqn]*
C[global_eqn])/
4552 residuals[3*raw_ndof+1] += (
Psi[global_eqn]*
C[global_eqn])/
4559 OOMPH_CURRENT_FUNCTION,
4560 OOMPH_EXCEPTION_LOCATION);
4577 unsigned augmented_ndof =
ndof(elem_pt);
4578 unsigned raw_ndof = elem_pt->
ndof();
4587 for(
unsigned n=0;n<raw_ndof;++n)
4589 for(
unsigned m=0;m<raw_ndof;++m)
4591 jacobian(raw_ndof+n,raw_ndof+m) = jacobian(n,m);
4592 jacobian(raw_ndof+n,2*raw_ndof+m) =
Omega*M(n,m);
4593 jacobian(2*raw_ndof+n,2*raw_ndof+m) = jacobian(n,m);
4594 jacobian(2*raw_ndof+n,raw_ndof+m) = -
Omega*M(n,m);
4595 unsigned global_eqn = elem_pt->
eqn_number(m);
4596 jacobian(raw_ndof+n,3*raw_ndof+1) += M(n,m)*
Psi[global_eqn];
4597 jacobian(2*raw_ndof+n,3*raw_ndof+1) -= M(n,m)*
Phi[global_eqn];
4601 jacobian(3*raw_ndof,raw_ndof+n) =
C[local_eqn]/
Count[local_eqn];
4602 jacobian(3*raw_ndof+1,2*raw_ndof+n) =
C[local_eqn]/
Count[local_eqn];
4605 const double FD_step = 1.0e-8;
4607 Vector<double> newres_p(augmented_ndof), newres_m(augmented_ndof);
4610 for(
unsigned n=0;n<raw_ndof;n++)
4613 unsigned long global_eqn =
eqn_number(elem_pt,n);
4615 double init = *unknown_pt;
4628 for(
unsigned m=0;m<raw_ndof;m++)
4630 jacobian(raw_ndof+m,n) =
4631 (newres_p[raw_ndof+m] - residuals[raw_ndof+m])/(FD_step);
4632 jacobian(2*raw_ndof+m,n) =
4633 (newres_p[2*raw_ndof+m] - residuals[2*raw_ndof+m])/(FD_step);
4642 double init = *unknown_pt;
4656 for(
unsigned m=0;m<augmented_ndof-2;m++)
4658 jacobian(m,3*raw_ndof) =
4659 (newres_p[m] - residuals[m])/FD_step;
4675 unsigned raw_ndof = elem_pt->
ndof();
4682 for(
unsigned n=0;n<raw_ndof;n++)
4684 for(
unsigned m=0;m<raw_ndof;m++)
4686 jacobian(n,raw_ndof+m) =
Omega*M(n,m);
4687 jacobian(raw_ndof+n,m) = -
Omega*M(n,m);
4688 jacobian(raw_ndof+n,raw_ndof+m) = jacobian(n,m);
4696 for(
unsigned n=0;n<raw_ndof;n++)
4699 residuals[raw_ndof+n] = 0.0;
4700 for(
unsigned m=0;m<raw_ndof;m++)
4702 unsigned global_unknown = elem_pt->
eqn_number(m);
4704 residuals[n] += M(n,m)*
Psi[global_unknown];
4706 residuals[raw_ndof+n] -= M(n,m)*
Phi[global_unknown];
4712 throw OomphLibError(
"Solve_which_system can only be 0,1 or 2",
4713 OOMPH_CURRENT_FUNCTION,
4714 OOMPH_EXCEPTION_LOCATION);
4732 unsigned raw_ndof = elem_pt->
ndof();
4737 parameter_pt,dres_dparam,djac_dparam,dM_dparam);
4741 dres_dparam[3*raw_ndof] = 0.0;
4742 dres_dparam[3*raw_ndof+1] = 0.0;
4745 for(
unsigned i=0;
i<raw_ndof;
i++)
4747 dres_dparam[raw_ndof+
i] = 0.0;
4748 dres_dparam[2*raw_ndof+
i] = 0.0;
4749 for(
unsigned j=0;j<raw_ndof;j++)
4751 unsigned global_unknown = elem_pt->
eqn_number(j);
4753 dres_dparam[raw_ndof+
i] +=
4754 djac_dparam(
i,j)*
Phi[global_unknown] +
4755 Omega*dM_dparam(
i,j)*
Psi[global_unknown];
4757 dres_dparam[2*raw_ndof+
i] +=
4758 djac_dparam(
i,j)*Psi[global_unknown] -
4759 Omega*dM_dparam(
i,j)*
Phi[global_unknown];
4766 OOMPH_CURRENT_FUNCTION,
4767 OOMPH_EXCEPTION_LOCATION);
4782 double*
const ¶meter_pt,
4786 std::ostringstream error_stream;
4788 "This function has not been implemented because it is not required\n";
4789 error_stream <<
"in standard problems.\n";
4791 "If you find that you need it, you will have to implement it!\n\n";
4794 OOMPH_CURRENT_FUNCTION,
4795 OOMPH_EXCEPTION_LOCATION);
4809 std::ostringstream error_stream;
4811 "This function has not been implemented because it is not required\n";
4812 error_stream <<
"in standard problems.\n";
4814 "If you find that you need it, you will have to implement it!\n\n";
4817 OOMPH_CURRENT_FUNCTION,
4818 OOMPH_EXCEPTION_LOCATION);
4830 eigenfunction.resize(2);
4833 eigenfunction[0].build(&dist,0.0);
4834 eigenfunction[1].build(&dist,0.0);
4836 for(
unsigned n=0;n<
Ndof;n++)
4838 eigenfunction[0][n] =
Phi[n];
4839 eigenfunction[1][n] =
Psi[n];
4875 for(
unsigned n=0;n<
Ndof;n++)
4901 for(
unsigned n=0;n<
Ndof;n++)
4905 for(
unsigned n=0;n<
Ndof;n++)
A Generalised Element class.
DoubleVectorWithHaloEntries Count
A vector that is used to determine how many elements contribute to a particular equation. It is used to ensure that the global system is correctly formulated. This should really be an integer, but its double so that the distribution can be used.
virtual void get_residuals(Vector< double > &residuals)
Calculate the vector of residuals of the equations in the element. By default initialise the vector t...
void solve(Problem *const &problem_pt, DoubleVector &result)
The solve function uses the block factorisation.
virtual void solve(Problem *const &problem_pt, DoubleVector &result)=0
Solver: Takes pointer to problem and returns the results vector which contains the solution of the li...
void get_all_vectors_and_matrices(GeneralisedElement *const &elem_pt, Vector< Vector< double > > &vec, Vector< DenseMatrix< double > > &matrix)
Calculate all desired vectors and matrices provided by the element elem_pt.
double * global_dof_pt(const unsigned &i)
Return a pointer to the dof, indexed by global equation number which may be haloed or stored locally...
void solve_block_system()
Set to solve the block system.
void get_hessian_vector_products(DoubleVectorWithHaloEntries const &Y, Vector< DoubleVectorWithHaloEntries > const &C, Vector< DoubleVectorWithHaloEntries > &product)
Return the product of the global hessian (derivative of Jacobian matrix with respect to all variables...
~BlockPitchForkLinearSolver()
Destructor: clean up the allocated memory.
double Sigma
A slack variable used to specify the amount of antisymmetry in the solution.
void get_dresiduals_dparameter(GeneralisedElement *const &elem_pt, double *const ¶meter_pt, Vector< double > &dres_dparam)
Overload the derivatives of the residuals with respect to.
AssemblyHandler * Assembly_handler_pt
Pointer to the underlying (original) assembly handler.
void get_dresiduals_dparameter(GeneralisedElement *const &elem_pt, double *const ¶meter_pt, Vector< double > &dres_dparam)
Overload the derivatives of the residuals with respect to a parameter to apply to the augmented syste...
void redistribute(const LinearAlgebraDistribution *const &dist_pt)
The contents of the vector are redistributed to match the new distribution. In a non-MPI rebuild this...
virtual void get_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Calculate the elemental Jacobian matrix "d equation / d variable".
virtual void actions_after_change_in_bifurcation_parameter()
Actions that are to be performed after a change in the parameter that is being varied as part of the ...
virtual void get_djacobian_dparameter(double *const ¶meter_pt, Vector< double > &dres_dparam, DenseMatrix< double > &djac_dparam)
Calculate the derivatives of the elemental Jacobian matrix and residuals with respect to a parameter...
Vector< int > Count
A vector that is used to determine how many elements contribute to a particular equation. It is used to ensure that the global system is correctly formulated.
void sum_all_halo_and_haloed_values()
void resolve(const DoubleVector &rhs, DoubleVector &result)
The resolve function also uses the block factorisation.
Problem * Problem_pt
Pointer to the problem.
const double & omega() const
Return the frequency of the bifurcation.
virtual void get_inner_products(GeneralisedElement *const &elem_pt, Vector< std::pair< unsigned, unsigned > > const &history_index, Vector< double > &inner_product)
Compute the inner products of the given vector of pairs of history values over the element...
void get_eigenfunction(Vector< DoubleVector > &eigenfunction)
Return the eigenfunction(s) associated with the bifurcation that has been detected in bifurcation tra...
void get_residuals(GeneralisedElement *const &elem_pt, Vector< double > &residuals)
Get the residuals.
virtual void get_mass_matrix(Vector< double > &residuals, DenseMatrix< double > &mass_matrix)
Calculate the residuals and the elemental "mass" matrix, the matrix that multiplies the time derivati...
unsigned long eqn_number(GeneralisedElement *const &elem_pt, const unsigned &ieqn_local)
Get the global equation number of the local unknown.
Vector< int > Count
A vector that is used to determine how many elements contribute to a particular equation. It is used to ensure that the global system is correctly formulated.
LinearAlgebraDistribution * Dof_distribution_pt
The distribution of the DOFs in this problem. This object is created in the Problem constructor and s...
virtual void resolve(const DoubleVector &rhs, DoubleVector &result)
Resolve the system defined by the last assembled jacobian and the rhs vector. Solution is returned in...
double *& dof_pt(const unsigned &i)
Pointer to i-th dof in the problem.
void solve(Problem *const &problem_pt, DoubleVector &result)
The solve function uses the block factorisation.
Vector< double > Phi
A constant vector used to ensure that the null vector is not trivial.
double & global_value(const unsigned &i)
Direct access to global entry.
virtual void get_all_vectors_and_matrices(GeneralisedElement *const &elem_pt, Vector< Vector< double > > &vec, Vector< DenseMatrix< double > > &matrix)
Calculate all desired vectors and matrices provided by the element elem_pt.
virtual void get_hessian_vector_products(GeneralisedElement *const &elem_pt, Vector< double > const &Y, DenseMatrix< double > const &C, DenseMatrix< double > &product)
Calculate the product of the Hessian (derivative of Jacobian with respect to all variables) an eigenv...
void build(const OomphCommunicator *const comm_pt, const unsigned &first_row, const unsigned &nrow_local, const unsigned &nrow=0)
Sets the distribution. Takes first_row, nrow_local and nrow as arguments. If nrow is not provided or ...
double * Parameter_pt
Pointer to the parameter.
void synchronise()
Function that is used to perform any synchronisation required during the solution.
~HopfHandler()
Destructor return the problem to its original (non-augmented) state.
bool is_halo() const
Is this element a halo?
void get_derivative_wrt_global_parameter(double *const ¶meter_pt, DoubleVector &result)
Get the derivative of the entire residuals vector wrt a global parameter, used in continuation proble...
virtual void get_inner_products(Vector< std::pair< unsigned, unsigned > > const &history_index, Vector< double > &inner_product)
Return the vector of inner product of the given pairs of history values.
virtual void get_inner_product_vectors(Vector< unsigned > const &history_index, Vector< Vector< double > > &inner_product_vector)
Compute the vectors that when taken as a dot product with other history values give the inner product...
unsigned first_row() const
access function for the first row on this processor. If not distributed then this is just zero...
Mesh *& mesh_pt()
Return a pointer to the global mesh.
Vector< double > C
A constant vector used to ensure that the null vector is not trivial.
LinearAlgebraDistribution * Augmented_dof_distribution_pt
The augmented distribution.
virtual void dof_vector(GeneralisedElement *const &elem_pt, const unsigned &t, Vector< double > &dof)
Return vector of dofs at time level t in the element elem_pt.
unsigned Solve_which_system
Integer flag to indicate which system should be assembled. There are three possibilities. The full augmented system (0), the non-augmented jacobian system (1), a system in which the jacobian is augmented by 1 row and column to ensure that it is non-singular (2). See the enum above.
unsigned Ndof
Store the number of degrees of freedom in the non-augmented problem.
void get_jacobian(GeneralisedElement *const &elem_pt, Vector< double > &residuals, DenseMatrix< double > &jacobian)
Calculate the elemental Jacobian matrix "d equation / d variable".
OomphCommunicator * communicator_pt()
access function to the oomph-lib communicator
LinearAlgebraDistribution * Dof_distribution_pt
Store the original dof distribution.
virtual void get_hessian_vector_products(Vector< double > const &Y, DenseMatrix< double > const &C, DenseMatrix< double > &product)
Calculate the product of the Hessian (derivative of Jacobian with respect to all variables) an eigenv...
void get_residuals(GeneralisedElement *const &elem_pt, Vector< double > &residuals)
Get the residuals.
void get_eigenfunction(Vector< DoubleVector > &eigenfunction)
Return the eigenfunction(s) associated with the bifurcation that has been detected in bifurcation tra...
Vector< double > Y
Storage for the null vector.
DoubleVectorWithHaloEntries C
A constant vector used to ensure that the null vector is not trivial.
void solve_full_system()
Solve non-block system.
virtual void get_eigenfunction(Vector< DoubleVector > &eigenfunction)
Return the eigenfunction(s) associated with the bifurcation that has been detected in bifurcation tra...
unsigned long nelement() const
Return number of elements in the mesh.
unsigned Ndof
Store the number of degrees of freedom in the non-augmented problem.
void get_jacobian(GeneralisedElement *const &elem_pt, Vector< double > &residuals, DenseMatrix< double > &jacobian)
Calculate the elemental Jacobian matrix "d equation / d variable" for elem_pt. Again deliberately br...
void resolve(const DoubleVector &rhs, DoubleVector &result)
The resolve function also uses the block factorisation.
unsigned ndof(GeneralisedElement *const &elem_pt)
Return the number of degrees of freedom in the element elem_pt.
DoubleVectorWithHaloEntries Y
Storage for the null vector.
bool distributed() const
distribution is serial or distributed
unsigned long eqn_number(GeneralisedElement *const &elem_pt, const unsigned &ieqn_local)
Return the global equation number of the local unknown ieqn_local in elem_pt.
AssemblyHandler *& assembly_handler_pt()
Return a pointer to the assembly handler object.
unsigned ndof() const
Return the number of equations/dofs in the element.
~AugmentedBlockPitchForkLinearSolver()
Destructor: clean up the allocated memory.
void get_djacobian_dparameter(GeneralisedElement *const &elem_pt, double *const ¶meter_pt, Vector< double > &dres_dparam, DenseMatrix< double > &djac_dparam)
Overload the derivative of the residuals and jacobian with respect to a parameter so that it breaks...
bool Distributed
Boolean to indicate whether the problem is distributed.
virtual unsigned ndof(GeneralisedElement *const &elem_pt)
Return the number of degrees of freedom in the element elem_pt.
Describes the distribution of a distributable linear algebra type object. Typically this is a contain...
virtual void get_djacobian_and_dmass_matrix_dparameter(double *const ¶meter_pt, Vector< double > &dres_dparam, DenseMatrix< double > &djac_dparam, DenseMatrix< double > &dmass_matrix_dparam)
Calculate the derivatives of the elemental Jacobian matrix mass matrix and residuals with respect to ...
void get_djacobian_dparameter(GeneralisedElement *const &elem_pt, double *const ¶meter_pt, Vector< double > &dres_dparam, DenseMatrix< double > &djac_dparam)
Overload the derivative of the residuals and jacobian with respect to a parameter so that it breaks...
void build(const DoubleVector &old_vector)
Just copys the argument DoubleVector.
void get_hessian_vector_products(GeneralisedElement *const &elem_pt, Vector< double > const &Y, DenseMatrix< double > const &C, DenseMatrix< double > &product)
Overload the hessian vector product function so that it breaks.
void resolve(const DoubleVector &rhs, DoubleVector &result)
The resolve function also uses the block factorisation.
double & dof(const unsigned &i)
i-th dof in the problem
virtual double * bifurcation_parameter_pt() const
Return a pointer to the bifurcation parameter in bifurcation tracking problems.
GeneralisedElement *& element_pt(const unsigned long &e)
Return pointer to element e.
virtual void get_inner_product_vectors(GeneralisedElement *const &elem_pt, Vector< unsigned > const &history_index, Vector< Vector< double > > &inner_product_vector)
Compute the vectors that when taken as a dot product with other history values give the inner product...
void resolve(const DoubleVector &rhs, DoubleVector &result)
The resolve function also uses the block factorisation.
LinearSolver * linear_solver_pt() const
Access function to the original linear solver.
unsigned ndof(GeneralisedElement *const &elem_pt)
Return the number of degrees of freedom in the element elem_pt.
bool is_resolve_enabled() const
Boolean flag indicating if resolves are enabled.
double * Parameter_pt
Storage for the pointer to the parameter.
void build_halo_scheme(DoubleVectorHaloScheme *const &halo_scheme_pt)
Construct the halo scheme and storage for the halo data.
int & sign_of_jacobian()
Access function for the sign of the global jacobian matrix. This will be set by the linear solver...
virtual void get_djacobian_dparameter(GeneralisedElement *const &elem_pt, double *const ¶meter_pt, Vector< double > &dres_dparam, DenseMatrix< double > &djac_dparam)
Calculate the derivative of the residuals and jacobian with respect to a parameter.
void dof_pt_vector(Vector< double *> &dof_pt)
Return the vector of pointers to dof values.
virtual void dof_pt_vector(GeneralisedElement *const &elem_pt, Vector< double *> &dof_pt)
Return vector of pointers to dofs in the element elem_pt.
unsigned long eqn_number(const unsigned &ieqn_local) const
Return the global equation number corresponding to the ieqn_local-th local equation number...
FoldHandler(Problem *const &problem_pt, double *const ¶meter_pt)
Constructor: initialise the fold handler, by setting initial guesses for Y, Phi and calculating count...
virtual void get_dresiduals_dparameter(double *const ¶meter_pt, Vector< double > &dres_dparam)
Calculate the derivatives of the residuals with respect to a parameter.
void solve_for_two_rhs(Problem *const &problem_pt, DoubleVector &result, const DoubleVector &rhs2, DoubleVector &result2)
Solve for two right hand sides.
unsigned Solve_which_system
Integer flag to indicate which system should be assembled. There are three possibilities. The full augmented system (0), the non-augmented jacobian system (1), a system in which the jacobian is augmented by 1 row and column to ensure that it is non-singular (2). See the enum above.
unsigned nrow_local() const
access function for the num of local rows on this processor. If no MPI then Nrow is returned...
void get_dresiduals_dparameter(GeneralisedElement *const &elem_pt, double *const ¶meter_pt, Vector< double > &dres_dparam)
Overload the derivatives of the residuals with respect to a parameter to apply to the augmented syste...
void get_all_vectors_and_matrices(GeneralisedElement *const &elem_pt, Vector< Vector< double > > &vec, Vector< DenseMatrix< double > > &matrix)
Calculate all desired vectors and matrices provided by the element elem_pt.
virtual void get_residuals(DoubleVector &residuals)
Return the fully-assembled residuals Vector for the problem: Virtual so it can be overloaded in for m...
void setup_dof_halo_scheme()
Function that is used to setup the halo scheme.
virtual double & local_problem_dof(Problem *const &problem_pt, const unsigned &t, const unsigned &i)
Return the t-th level of storage associated with the i-th (local) dof stored in the problem...
virtual void get_jacobian_and_mass_matrix(Vector< double > &residuals, DenseMatrix< double > &jacobian, DenseMatrix< double > &mass_matrix)
Calculate the residuals and jacobian and elemental "mass" matrix, the matrix that multiplies the time...
void solve_block_system()
Set to solve the block system.
~FoldHandler()
Destructor, return the problem to its original state before the augmented system was added...
void get_eigenfunction(Vector< DoubleVector > &eigenfunction)
Return the eigenfunction(s) associated with the bifurcation that.
unsigned ndof(GeneralisedElement *const &elem_pt)
Get the number of elemental degrees of freedom.
~AugmentedBlockFoldLinearSolver()
Destructor: clean up the allocated memory.
A class that is used to define the functions used to assemble the elemental contributions to the resi...
void solve_full_system()
Solve non-block system.
virtual void enable_resolve()
Enable resolve (i.e. store matrix and/or LU decomposition, say) Virtual so it can be overloaded to pe...
Vector< Vector< unsigned > > Sparse_assemble_with_arrays_previous_allocation
the number of elements in each row of a compressed matrix in the previous matrix assembly.
unsigned Solve_which_system
Integer flag to indicate which system should be assembled. There are three possibilities. The full augmented system (0), the non-augmented jacobian system (1), and complex system (2), where the matrix is a combination of the jacobian and mass matrices.
void get_djacobian_dparameter(GeneralisedElement *const &elem_pt, double *const ¶meter_pt, Vector< double > &dres_dparam, DenseMatrix< double > &djac_dparam)
Overload the derivative of the residuals and jacobian with respect to a parameter so that it breaks...
void get_residuals(GeneralisedElement *const &elem_pt, Vector< double > &residuals)
Return the contribution to the residuals of the element elem_pt This is deliberately broken in our ei...
void solve(Problem *const &problem_pt, DoubleVector &result)
The solve function uses the block factorisation.
virtual void get_residuals(GeneralisedElement *const &elem_pt, Vector< double > &residuals)
Return the contribution to the residuals of the element elem_pt.
unsigned long ndof() const
Return the number of dofs.
HopfHandler(Problem *const &problem_pt, double *const ¶meter_pt)
Constructor.
virtual void disable_resolve()
Disable resolve (i.e. store matrix and/or LU decomposition, say) This function simply resets an inter...
~PitchForkHandler()
Destructor return the problem to its original (non-augmented) state.
LinearSolver *& linear_solver_pt()
Return a pointer to the linear solver object.
void get_jacobian(GeneralisedElement *const &elem_pt, Vector< double > &residuals, DenseMatrix< double > &jacobian)
Calculate the elemental Jacobian matrix "d equation / d variable".
unsigned long eqn_number(GeneralisedElement *const &elem_pt, const unsigned &ieqn_local)
Return the global equation number of the local unknown ieqn_local in elem_pt.
void synchronise()
Synchronise the halo data.
double dot(const DoubleVector &vec) const
compute the dot product of this vector with the vector vec.
void solve_complex_system()
Set to solve the complex system.
Problem * Problem_pt
Pointer to the problem.
virtual void get_jacobian(GeneralisedElement *const &elem_pt, Vector< double > &residuals, DenseMatrix< double > &jacobian)
Calculate the elemental Jacobian matrix "d equation / d variable" for elem_pt.
Problem * Problem_pt
Pointer to the problem.
double * Parameter_pt
Storage for the pointer to the parameter.
void dof_vector(const unsigned &t, Vector< double > &dof)
Return the vector of dof values at time level t.
~BlockHopfLinearSolver()
Destructor: clean up the allocated memory.
unsigned ndof(GeneralisedElement *const &elem_pt)
Get the number of elemental degrees of freedom.
void solve_full_system()
Solve non-block system.
void solve_augmented_block_system()
Set to solve the augmented block system.
DoubleVectorWithHaloEntries Psi
A constant vector that is specifies the symmetry being broken.
unsigned long eqn_number(GeneralisedElement *const &elem_pt, const unsigned &ieqn_local)
Get the global equation number of the local unknown.
virtual unsigned long eqn_number(GeneralisedElement *const &elem_pt, const unsigned &ieqn_local)
Return the global equation number of the local unknown ieqn_local in elem_pt.
Vector< double * > Dof_pt
Vector of pointers to dofs.
void get_hessian_vector_products(GeneralisedElement *const &elem_pt, Vector< double > const &Y, DenseMatrix< double > const &C, DenseMatrix< double > &product)
Overload the hessian vector product function so that it breaks.
unsigned nrow_local() const
access function for the num of local rows on this processor.
DoubleVectorHaloScheme * Halo_scheme_pt
Pointer to the halo scheme for any global vectors that have the Dof_distribution. ...
virtual void actions_before_newton_convergence_check()
Any actions that are to be performed before the residual is checked in the Newton method...
Vector< unsigned > Global_eqn_number
A vector that is used to map the global equations to their actual location in a distributed problem...
double Omega
The critical frequency of the bifurcation.
A vector in the mathematical sense, initially developed for linear algebra type applications. If MPI then this vector can be distributed - its distribution is described by the LinearAlgebraDistribution object at Distribution_pt. Data is stored in a C-style pointer vector (double*)
unsigned global_eqn_number(const unsigned &i)
Function that is used to return map the global equations using the simplistic numbering scheme into t...
void get_residuals(GeneralisedElement *const &elem_pt, Vector< double > &residuals)
Return the contribution to the residuals of the element elem_pt This is deliberately broken in our ei...
unsigned ndof(GeneralisedElement *const &elem_pt)
Get the number of elemental degrees of freedom.
double norm() const
compute the 2 norm of this vector
Vector< double > Phi
The real part of the null vector.
void solve_standard_system()
Set to solve the standard system.
unsigned long eqn_number(GeneralisedElement *const &elem_pt, const unsigned &ieqn_local)
Get the global equation number of the local unknown.
void solve_augmented_block_system()
Set to solve the augmented block system.
LinearSolver * linear_solver_pt() const
Access function to the original linear solver.
void solve(Problem *const &problem_pt, DoubleVector &result)
The solve function uses the block factorisation.
LinearSolver * linear_solver_pt() const
Access function to the original linear solver.
unsigned Ndof
Store the number of degrees of freedom in the non-augmented problem.
void get_residuals(GeneralisedElement *const &elem_pt, Vector< double > &residuals)
Get the residuals.
void get_jacobian(GeneralisedElement *const &elem_pt, Vector< double > &residuals, DenseMatrix< double > &jacobian)
Calculate the elemental Jacobian matrix "d equation / d variable".
PitchForkHandler(Problem *const &problem_pt, AssemblyHandler *const &assembly_handler_pt, double *const ¶meter_pt, const DoubleVector &symmetry_vector)
Constructor, initialise the systems.
LinearAlgebraDistribution * distribution_pt() const
access to the LinearAlgebraDistribution
void get_jacobian(GeneralisedElement *const &elem_pt, Vector< double > &residuals, DenseMatrix< double > &jacobian)
Calculate the elemental Jacobian matrix "d equation / d variable" for elem_pt. Again deliberately br...
Vector< double > Psi
The imaginary part of the null vector.
LinearSolver * linear_solver_pt() const
Access function to the original linear solver.
void get_hessian_vector_products(GeneralisedElement *const &elem_pt, Vector< double > const &Y, DenseMatrix< double > const &C, DenseMatrix< double > &product)
Overload the hessian vector product function so that it breaks.
virtual void get_dresiduals_dparameter(GeneralisedElement *const &elem_pt, double *const ¶meter_pt, Vector< double > &dres_dparam)
Calculate the derivative of the residuals with respect to a parameter.