50 for (
unsigned i=0;i<n_data;i++)
56 unsigned n_prev=
Solid_data_pt[i]->time_stepper_pt()->nprev_values();
64 for (
unsigned k=0;k<n_value;k++)
84 mesh_pt()->node_update();
100 for (
unsigned i=0;i<orig_n_sub_mesh;i++)
106 rebuild_global_mesh();
130 rebuild_global_mesh();
156 rebuild_global_mesh();
172 for (
unsigned i=0;i<n_data;i++)
178 for (
unsigned k=0;k<n_value;k++)
197 for (
unsigned i=0;i<n_data;i++)
203 for (
unsigned k=0;k<n_value;k++)
230 for (
unsigned i=0;i<n_data;i++)
236 for (
unsigned k=0;k<n_value;k++)
256 for (
unsigned i=0;i<n_data;i++)
262 for (
unsigned k=0;k<n_value;k++)
288 unsigned value_count=0;
294 for (
unsigned i=0;i<n_data;i++)
300 for (
unsigned k=0;k<n_value;k++)
332 double& rms_change,
double& max_change,
double& rms_norm)
341 unsigned value_count=0;
347 for (
unsigned i=0;i<n_data;i++)
353 for (
unsigned k=0;k<n_value;k++)
361 if (std::fabs(change)>max_change) max_change=std::fabs(change);
364 rms_change+=pow(change,2);
375 rms_change=sqrt(rms_change/
double(value_count));
376 rms_norm=sqrt(rms_norm/
double(value_count));
397 unsigned value_count=0;
403 for (
unsigned i=0;i<n_data;i++)
409 for (
unsigned k=0;k<n_value;k++)
418 double change=old_solid_value-new_solid_value;
433 crit+=std::fabs(change);
457 for (
unsigned i=0;i<n_data;i++)
463 for (
unsigned k=0;k<n_value;k++)
489 unsigned value_count=0;
495 for (
unsigned i=0;i<n_data;i++)
501 for (
unsigned k=0;k<n_value;k++)
528 unsigned value_count=0;
534 for (
unsigned i=0;i<n_data;i++)
540 for (
unsigned k=0;k<n_value;k++)
549 double max_diff=std::max(std::fabs(v1-v0),std::fabs(v2-v1));
550 if (max_diff>1.0e-10)
552 new_value=v2-std::pow((v2-v1),
int(2))/(v2-2.0*v1+v0);
579 clock_t t_total_start = clock();
586 get_max_global_residual=
true;
593 double cpu_for_global_residual=0.0;
600 bool converged=
false;
604 double tol_achieved=0.0;
622 double max_res = 0.0;
623 if (get_max_global_residual)
625 clock_t t_start = clock();
629 assign_eqn_numbers();
632 DoubleVector residual;
633 get_residuals(residual);
635 max_res = residual.max();
636 clock_t t_end = clock();
637 cpu_for_global_residual+=double(t_end-t_start)/CLOCKS_PER_SEC;
640 oomph_info <<
"==================================================\n";
641 oomph_info <<
"Initial iteration : " 643 oomph_info <<
"RMS change : " 645 oomph_info <<
"Max. change : " 647 oomph_info <<
"RMS norm : " 649 if (get_max_global_residual)
651 oomph_info <<
"Max. global residual : " 652 << max_res << std::endl;
654 oomph_info <<
"==================================================\n\n";
663 <<
"\n\n\n////////////////////////////////////////////////////////" 664 <<
"\nPicard iteration converged after " 665 << 0 <<
" steps!" << std::endl
666 <<
"Convergence was based on max. residual of coupled eqns \n" 668 <<
"////////////////////////////////////////////////////////\n\n\n" 682 goto jump_out_of_picard;
693 assign_eqn_numbers();
696 oomph_info <<
"\n\nDOING FLUID SOLVE\n\n";
709 assign_eqn_numbers();
712 oomph_info <<
"\n\nDOING SOLID SOLVE\n\n";
745 if (get_max_global_residual)
747 clock_t t_start = clock();
753 assign_eqn_numbers();
759 DoubleVector residual;
760 get_residuals(residual);
763 max_res = residual.max();
765 clock_t t_end = clock();
766 cpu_for_global_residual+=double(t_end-t_start)/CLOCKS_PER_SEC;
769 oomph_info <<
"==================================================\n";
770 oomph_info <<
"Iteration : " 771 << iter << std::endl;
772 oomph_info <<
"RMS change : " 773 << rms_change << std::endl;
774 oomph_info <<
"Max. change : " 775 << max_change << std::endl;
776 oomph_info <<
"RMS norm : " 777 << rms_norm << std::endl;
778 if (get_max_global_residual)
780 oomph_info <<
"Max. global residual : " 781 << max_res << std::endl;
783 oomph_info <<
"==================================================\n\n";
790 tol_achieved=max_change;
794 <<
"\n\n\n////////////////////////////////////////////////////////" 795 <<
"\nPicard iteration converged after " 796 << iter <<
" steps!" << std::endl
797 <<
"Convergence was based on absolute change in solid dofs \n" 799 <<
"////////////////////////////////////////////////////////\n\n\n" 807 tol_achieved=std::fabs(rms_change/rms_norm);
811 <<
"\n\n\n///////////////////////////////////////////////////////" 812 <<
"\nPicard iteration converged after " 813 << iter <<
" steps!" << std::endl
814 <<
"Convergence was based on relative change in solid dofs \n" 816 <<
"////////////////////////////////////////////////////////\n\n\n" 823 tol_achieved=max_res;
827 <<
"\n\n\n////////////////////////////////////////////////////////" 828 <<
"\nPicard iteration converged after " 829 << iter <<
" steps!" << std::endl
830 <<
"Convergence was based on max. residual of coupled eqns \n" 832 <<
"////////////////////////////////////////////////////////\n\n\n" 853 goto jump_out_of_picard;
894 assign_eqn_numbers();
903 conv_data.
niter()=iter_taken;
906 clock_t t_total_end = clock();
907 conv_data.
cpu_total()=double(t_total_end-t_total_start)/
927 <<
"\n\n\n////////////////////////////////////////////////////////" 928 <<
"\nPicard iteration did not converge after " 929 << iter_taken <<
" steps!" << std::endl
930 <<
"Convergence was based on absolute change in solid dofs \n" 932 <<
"but we achieved only " << tol_achieved <<
"." << std::endl
933 <<
"////////////////////////////////////////////////////////\n\n\n" 949 <<
"\n\n\n///////////////////////////////////////////////////////" 950 <<
"\nPicard iteration did not converge after " 951 << iter_taken <<
" steps!" << std::endl
952 <<
"Convergence was based on relative change in solid dofs \n" 954 <<
"but we achieved only " << tol_achieved <<
"." << std::endl
955 <<
"////////////////////////////////////////////////////////\n\n\n" 970 <<
"\n\n\n////////////////////////////////////////////////////////" 971 <<
"\nPicard iteration did not converge after " 972 << iter_taken <<
" steps!" << std::endl
973 <<
"Convergence was based on max. residual of coupled eqns \n" 975 <<
"but we achieved only " << tol_achieved <<
"." << std::endl
977 <<
"////////////////////////////////////////////////////////\n\n\n" 1006 unsigned n_time_steppers = ntime_stepper();
1010 std::vector<bool> was_steady(n_time_steppers);
1013 for(
unsigned i=0;i<n_time_steppers;i++)
1015 was_steady[i]=time_stepper_pt(i)->is_steady();
1016 time_stepper_pt(i)->make_steady();
1032 std::ostringstream error_stream;
1033 error_stream <<
"Error occured in Segregated solver. " 1035 throw OomphLibError(error_stream.str(),
1036 OOMPH_CURRENT_FUNCTION,
1037 OOMPH_EXCEPTION_LOCATION);
1041 oomph_info <<
"Note: Ran out of iterations but continuing anyway" 1049 for(
unsigned i=0;i<n_time_steppers;i++)
1053 time_stepper_pt(i)->undo_make_steady();
1062 assign_initial_values_impulsive();
1087 const double& dt,
const bool &shift_values)
1090 if(shift_values) {shift_time_values();}
1093 time_pt()->time()+=dt;
1097 unsigned n_time_steppers = ntime_stepper();
1100 for(
unsigned i=0;i<n_time_steppers;i++)
1102 time_stepper_pt(i)->set_weights();
1107 actions_before_implicit_timestep();
1125 std::ostringstream error_stream;
1126 error_stream <<
"Error occured in Segregated solver. " 1128 throw OomphLibError(error_stream.str(),
1129 OOMPH_CURRENT_FUNCTION,
1130 OOMPH_EXCEPTION_LOCATION);
1134 oomph_info <<
"Note: Ran out of iterations but continuing anyway" 1140 actions_after_implicit_timestep();
1152 const bool &full_setup_of_fluid_and_solid_dofs)
1155 if(full_setup_of_fluid_and_solid_dofs)
1158 Vector<Data*> fluid_data_pt;
1159 Vector<Data*> solid_data_pt;
1166 << std::endl << std::endl
1167 <<
"Warning: Your implementation of the pure virtual\n" 1168 <<
" function identify_fluid_and_solid_dofs(...)\n" 1169 <<
" returned a NULL pointer for Fluid_mesh_pt.\n" 1170 <<
" --> The fluid elements will remain activated\n" 1171 <<
" during the solid solve. This is inefficient!\n" 1172 <<
" You should combine all fluid elements into a combined\n" 1173 <<
" mesh and specify this mesh in your\n" 1174 <<
" implementation of \n\n" 1175 <<
" SegregatableFSIProblem::identify_fluid_and_solid_dofs(...)" 1176 << std::endl << std::endl;
1183 << std::endl << std::endl
1184 <<
"Warning: Your implementation of the pure virtual\n" 1185 <<
" function identify_fluid_and_solid_dofs(...)\n" 1186 <<
" returned a NULL pointer for Solid_mesh_pt.\n" 1187 <<
" --> The solid elements will remain activated\n" 1188 <<
" during the fluid solve. This is inefficient!\n" 1189 <<
" You should combine all solid elements into a combined\n" 1190 <<
" mesh and specify this mesh in your\n" 1191 <<
" implementation of \n\n" 1192 <<
" SegregatableFSIProblem::identify_fluid_and_solid_dofs(...)" 1193 << std::endl << std::endl;
1198 unsigned orig_n_sub_mesh=nsub_mesh();
1200 for (
unsigned i=0;i<orig_n_sub_mesh;i++)
1213 unsigned n_fluid_data=fluid_data_pt.size();
1218 unsigned n_fluid_values=0;
1221 for (
unsigned i=0;i<n_fluid_data;i++)
1227 unsigned n_value=fluid_data_pt[i]->nvalue();
1231 for (
unsigned k=0;k<n_value;k++)
1234 fluid_data_pt[i]->is_pinned(k);
1253 unsigned n_solid_data=solid_data_pt.size();
1256 unsigned nsolid_data=solid_data_pt.size();
1261 unsigned n_solid_values=0;
1264 for (
unsigned i=0;i<n_solid_data;i++)
1270 unsigned n_value=solid_data_pt[i]->nvalue();
1274 for (
unsigned k=0;k<n_value;k++)
1277 solid_data_pt[i]->is_pinned(k);
1297 for (
unsigned i=0;i<n_solid_values;i++)
unsigned & niter()
Number of iterations performed.
virtual void actions_before_segregated_solve()
This function is called once at the start of each segregated solve.
void under_relax_solid()
Under-relax the most recently computed solid variables, either by classical relaxation or by Irons & ...
virtual void identify_fluid_and_solid_dofs(Vector< Data *> &fluid_data_pt, Vector< Data *> &solid_data_pt, Mesh *&fluid_mesh_pt, Mesh *&solid_mesh_pt)=0
Identify the fluid and solid Data. This is a pure virtual function that MUST be implemented for every...
Vector< Vector< double > > Pointwise_aitken_solid_value
Vector of Vectors containing up to three previous iterates for the solid dofs; used for pointwise Ait...
Vector< double > Del_irons_and_tuck
Vector of changes in Irons and Tuck under-relaxation.
bool Ran_out_of_iterations
Vector< Mesh * > Orig_sub_mesh_pt
Backup for the pointers to the submeshes in the original problem.
virtual void actions_after_segregated_solve()
This function is called once at the end of each segregated solve.
double R_irons_and_tuck
Irons and Tuck relaxation factor.
bool Recheck_convergence_after_pointwise_aitken
Have we just done a pointwise Aitken step.
double & cpu_for_global_residual()
CPU time for computation of global residual vectors Note: This time is contained in Total_CPU and is ...
unsigned Max_picard
Max. number of Picard iterations.
void set_solver_converged()
Set the flag to indicate that the solver has converged.
double t_spent_on_actual_solve()
Total elapsed time since start of solve.
PicardConvergenceData unsteady_segregated_solve(const double &dt)
Unsteady segregated solver, advance time by dt and solve by the segregated solver. The time values are always shifted by this function. Returns PicardConvergenceData object that contains the vital stats of the iteration.
void rebuild_monolithic_mesh()
Rebuild global mesh for monolithic discretisation.
double Convergence_tolerance
Convergence tolerance for Picard iteration.
double & tol_achieved()
Final tolerance achieved by the iteration.
void pin_solid_dofs()
Pin solid dofs.
double & cpu_total()
Total CPU time for segregated solve.
bool Use_pointwise_aitken
Use pointwise Aitken extrapolation?
void setup_segregated_solver(const bool &full_setup_of_fluid_and_solid_dofs=true)
Setup the segregated solver: Backup the pinned status of the fluid and solid dofs and allocate the in...
void restore_fluid_dofs()
Restore pinned status of fluid dofs.
void pin_fluid_dofs()
Pin fluid dofs.
int Convergence_criterion
Convergence criterion (enumerated flag)
void restore_solid_dofs()
Restore pinned status of solid dofs.
int Pointwise_aitken_counter
Number of Aitken histories available (int because after extrapolation it's re-initialised to -1 to fo...
void reset_timer()
Reset timer.
A class to handle errors in the Segregated solver.
bool Use_irons_and_tuck_extrapolation
Boolean flag to indicate use of Irons and Tuck's extrapolation for solid values.
PicardConvergenceData segregated_solve()
Segregated solver. Peform a segregated step from the present state of the system. Returns PicardConve...
void pointwise_aitken_extrapolate()
Do pointwise Aitken extrapolation for solid.
void store_solid_dofs()
Store the current solid values as reference values for future convergence check. Also add another ent...
virtual void actions_before_segregated_convergence_check()
This function is to be filled with actions that take place before the check for convergence of the en...
double Omega_relax
Under-relaxation parameter. (1.0: no under-relaxation; 0.0: Freeze wall shape)
Vector< double > Previous_solid_value
Vector storing the previous solid values – used for convergence check.
void use_only_solid_elements()
Only include solid elements in the Problem's mesh. This is called before the segregated solid solve...
PicardConvergenceData steady_segregated_solve()
Steady version of segregated solver. Makes all timesteppers steady before solving. Returns PicardConvergenceData object that contains the vital stats of the iteration.
bool Doc_max_global_residual
Doc maximum global residual during iteration? (default: false)
int Solve_type
Solve that is taking place (enumerated flag)
Vector< Data * > Solid_data_pt
Vector storing the Data objects associated with the solid problem: Typically the positional data of s...
Vector< std::vector< bool > > Fluid_value_is_pinned
Vector of vectors that store the pinned status of fluid Data values.
void use_only_fluid_elements()
Only include fluid elements in the Problem's mesh. This is called before the segregated fluid solve...
Object that collates convergence data of Picard iteration.
unsigned Pointwise_aitken_start
Start pointwise Aitken extrpolation after specified number of Picard iterations.
Vector< std::vector< bool > > Solid_value_is_pinned
Vector of vectors that store the pinned status of solid Data values.
Vector< Data * > Fluid_data_pt
Vector storing the Data objects associated with the fluid problem: Tyically the nodal and internal da...
void get_solid_change(double &rms_change, double &max_change, double &rms_norm)
Get rms of change in the solid dofs; the max. change of the solid dofs and the rms norm of the solid ...
Mesh * Fluid_mesh_pt
Mesh containing only fluid elements – the elements in this Mesh will be excluded from the assembly p...
double & essential_cpu_total()
Total essential CPU time for segregated solve (excluding any actions that merely doc the progress of ...
void extrapolate_solid_data()
Extrapolate solid data and update fluid mesh during unsteady run.
Mesh * Solid_mesh_pt
Mesh containing only solid elements – the elements in this mesh will be excluded from the assembly p...