fsi_jacobian_approximation.cc File Reference
#include <iostream>
#include <cstring>
#include "generic.h"
#include "navier_stokes.h"
#include "beam.h"
#include "meshes/one_d_lagrangian_mesh.h"
#include "meshes/collapsible_channel_mesh.h"

Classes

class  UndeformedWall
 
class  FSICollapsibleChannelProblem< ELEMENT >
 Problem class. More...
 

Namespaces

 BL_Squash
 
 Control_Flags
 Namespace for phyical parameters.
 
 Global_Physical_Variables
 Global variables.
 

Functions

double BL_Squash::squash_fct (const double &s)
 
doubleGlobal_Physical_Variables::external_pressure ()
 Access function to value of external pressure. More...
 
void Global_Physical_Variables::prescribed_traction (const double &t, const Vector< double > &x, const Vector< double > &n, Vector< double > &traction)
 Traction applied on the fluid at the left (inflow) boundary. More...
 
void Global_Physical_Variables::load (const Vector< double > &xi, const Vector< double > &x, const Vector< double > &N, Vector< double > &load)
 Load function: Apply a constant external pressure to the beam. More...
 
int main (int argc, char *argv[])
 

Variables

bool Control_Flags::Validation_run =false
 Normal run or validation run? More...
 
bool Control_Flags::Steady_run =false
 Steady run or unsteady run? More...
 

Function Documentation

◆ main()

int main ( int argc  ,
char argv[] 
)

Driver code for a collapsible channel problem with FSI.

Run with the -help flag for more information on command line arguments to run with an approximation to the Jacobian, to run steady calculations and to perform validation runs with coarse resolution and small number of timesteps.

Disclaimer: this code is intended to demonstrate how to ask for various approximations to be made to the Jacobian matrix which can result in reduced calculations per Newton step (and to test this).However these approximations to the Jacobian may increase the overall number of Newton steps, or even cause the Newton solve to diverge. Therefore for any particular FSI problem some experiementation is required to determine whether approximating the Jacobian is beneficial. Note: In tests using this code, approximating the Jacobain increased the overall time per Newton solve, however for a 3D equivalent to this problem significant speed ups were found.

914 {
915 
916  // Store command line arguments
917  CommandLineArgs::setup(argc,argv);
918 
919  // Parse command line
920  int arg_index = 0;
921  bool print_help = false;
922  bool approx_jacobian = false;
923 
924  while (arg_index < argc)
925  {
926  if ( strcmp(argv[arg_index], "-validation_run") == 0 )
927  {
928  arg_index++;
930  }
931  else if ( strcmp(argv[arg_index], "-steady_run") == 0 )
932  {
933  arg_index++;
935  }
936  else if ( strcmp(argv[arg_index], "-approx_jacobian") == 0 )
937  {
938  arg_index++;
939  approx_jacobian=true;
940  }
941  else if ( strcmp(argv[arg_index], "-help") == 0 )
942  {
943  print_help = true;
944  break;
945  }
946  else
947  {
948  arg_index++;
949  }
950  }
951 
952  if (print_help)
953  {
954  oomph_info << "\n\nOption flags:\n\n";
955  oomph_info << "-validation run Perform validation run with coarse mesh\n"
956  << " and fewer Newton solves\n\n";
957  oomph_info << "-steady_run Solve series of steady problems with\n"
958  << " different wall positions, otherwise\n"
959  << " solve unsteady problem\n\n";
960  oomph_info << "-approx_jacobian Use Jacobian approximation\n\n";
961  return (0);
962  }
963 
964  // Set flags controlling approximations to the Jacobian
965  bool wall_jacobian_ignores_fluid_shear_stress_data = false;
966  bool wall_jacobian_ignores_geometric_data = false;
967  bool fluid_jacobian_ignores_geometric_data = false;
968  if (approx_jacobian)
969  {
970  wall_jacobian_ignores_fluid_shear_stress_data = true;
971  wall_jacobian_ignores_geometric_data = true;
972 
974  {
975  // This can speed up the calculation of the Jacobian but causes the
976  // Newton method to fail for unsteady problems
977  fluid_jacobian_ignores_geometric_data = true;
978  }
979  }
980 
981  // Reduction in resolution for validation run?
982  unsigned coarsening_factor=1;
984  {
985  coarsening_factor=4;
986  }
987 
988  // Number of elements in the domain
989  unsigned nup=20/coarsening_factor;
990  unsigned ncollapsible=40/coarsening_factor;
991  unsigned ndown=40/coarsening_factor;
992  unsigned ny=16/coarsening_factor;
993 
994  // Length of the domain
995  double lup=5.0;
996  double lcollapsible=10.0;
997  double ldown=10.0;
998  double ly=1.0;
999 
1000  // Build the problem with QTaylorHoodElements
1002  problem(nup,
1003  ncollapsible,
1004  ndown,
1005  ny,
1006  lup,
1007  lcollapsible,
1008  ldown,
1009  ly,
1010  wall_jacobian_ignores_fluid_shear_stress_data,
1011  wall_jacobian_ignores_geometric_data,
1012  fluid_jacobian_ignores_geometric_data);
1013 
1014  // Set external pressure (on the wall stiffness scale).
1016 
1017  // Pressure on the left boundary: This is consistent with steady
1018  // Poiseuille flow
1019  Global_Physical_Variables::P_up=12.0*(lup+lcollapsible+ldown);
1020 
1021  // Set initial wall displacement
1023 
1024  // Set Re and ReSt - it appears small values are required in this 2D problem,
1025  // with the Jacobian approximations otherwise the Newton method converges, this
1026  // is not the experience found with the 3D equivalent problem.
1029 
1030  // Timestep. Note: Preliminary runs indicate that the period of
1031  // the oscillation is about 1 so this gives us 40 steps per period.
1032  double dt=1.0/40.0;
1033 
1034  // Initial time for the simulation
1035  double t_min=0.0;
1036 
1037  // Maximum time for simulation
1038  double t_max=3.5;
1039 
1040  // Initialise timestep
1041  problem.time_pt()->time()=t_min;
1042  problem.initialise_dt(dt);
1043 
1044  // Apply initial condition
1045  problem.set_initial_condition();
1046 
1047  //Set output directory
1048  DocInfo doc_info;
1050  {
1051  if (approx_jacobian)
1052  {
1053  oomph_info << "Using approximate Jacobian\n";
1055  doc_info.set_directory("RESLT_APPROX_STEADY");
1056  else
1057  doc_info.set_directory("RESLT_APPROX_UNSTEADY");
1058  }
1059  else
1060  {
1061  oomph_info << "Using exact Jacobian\n";
1063  doc_info.set_directory("RESLT_EXACT_STEADY");
1064  else
1065  doc_info.set_directory("RESLT_EXACT_UNSTEADY");
1066  }
1067  }
1068  else
1069  {
1070  doc_info.set_directory("RESLT");
1071  }
1072 
1073  // Open a trace file
1074  ofstream trace_file;
1075  char filename[100];
1076  sprintf(filename,"%s/trace.dat",doc_info.directory().c_str());
1077  trace_file.open(filename);
1078 
1079  // Output the initial solution
1080  problem.doc_solution(doc_info, trace_file);
1081 
1082  // Increment step number
1083  doc_info.number()++;
1084 
1086  {
1087  // Number of solves (reduced for validation)
1088  unsigned nstep = 20;
1090  {
1091  nstep=3;
1092  }
1093 
1094  // Loop over different wall displacement
1095  for (unsigned istep=0;istep<nstep;istep++)
1096  {
1097  oomph_info << "\nSteady Newton solve " << istep
1098  << " for wall displacement of "
1100  << "====================================================\n";
1101 
1102  // Solve the problem
1103  problem.newton_solve();
1104 
1105  cout << "External pressure="
1107  << "\n";
1108 
1109  // Output the solution
1110  problem.doc_solution(doc_info, trace_file);
1111 
1112  // Step number
1113  doc_info.number()++;
1114 
1115  // Change wall position
1117  }
1118  }
1119  else
1120  {
1121  // Find number of timesteps (reduced for validation)
1122  unsigned nstep = unsigned((t_max-t_min)/dt);
1124  {
1125  nstep=10;
1126  }
1127 
1128  // Timestepping loop
1129  for (unsigned istep=0;istep<nstep;istep++)
1130  {
1131  oomph_info << "\nNewton solve " << istep << "\n"
1132  << "================\n";
1133 
1134  // Solve the problem
1135  problem.unsteady_newton_solve(dt);
1136 
1137  // Output the solution
1138  problem.doc_solution(doc_info, trace_file);
1139 
1140  // Step number
1141  doc_info.number()++;
1142  }
1143 
1144  }
1145 
1146  // Close trace file.
1147  trace_file.close();
1148 
1149 }//end of main
Problem class.
Definition: fsi_chan_problem.h:315
Definition: oomph_utilities.h:499
std::string directory() const
Output directory.
Definition: oomph_utilities.h:524
void set_directory(const std::string &directory)
Definition: oomph_utilities.cc:298
unsigned & number()
Number used (e.g.) for labeling output files.
Definition: oomph_utilities.h:554
bool Steady_run
Steady run or unsteady run?
Definition: fsi_jacobian_approximation.cc:181
bool Validation_run
Normal run or validation run?
Definition: fsi_jacobian_approximation.cc:178
void setup(Time *time_pt)
Create all GeomObjects needed to define the cylinder and the flag.
Definition: turek_flag_non_fsi.cc:277
double ReSt
Womersley number.
Definition: rayleigh_instability.cc:56
double & external_pressure()
Access function to value of external pressure.
Definition: steady_ring.cc:79
double Prescribed_y
Prescribed position of control point.
Definition: mpi/distribution/clamped_shell/clamped_shell_with_arclength_cont.cc:54
double Re
Reynolds number.
Definition: fibre.cc:55
double P_up
Default pressure on the left boundary.
Definition: fsi_collapsible_channel.cc:183
string filename
Definition: MergeRestartFiles.py:39
const double ly
Definition: ConstraintElementsUnitTest.cpp:34
const unsigned ny
Definition: ConstraintElementsUnitTest.cpp:31
OomphInfo oomph_info
Definition: oomph_definitions.cc:319
Constructor for SteadyAxisymAdvectionDiffusion problem
Definition: steady_axisym_advection_diffusion.cc:213

References oomph::DocInfo::directory(), Global_Physical_Variables::external_pressure(), MergeRestartFiles::filename, Mesh_Parameters::ly, oomph::DocInfo::number(), Mesh_Parameters::ny, oomph::oomph_info, Global_Physical_Variables::P_up, Global_Physical_Variables::Prescribed_y, problem, Global_Physical_Variables::Re, Global_Physical_Variables::ReSt, oomph::DocInfo::set_directory(), Flag_definition::setup(), Control_Flags::Steady_run, and Control_Flags::Validation_run.