time_periodic_taylor_couette.cc File Reference

Classes

class  BaseStateProblem< BASE_ELEMENT >
 Base state problem class for Tuckerman counter-rotating lids problem. More...
 
class  PerturbedStateProblem< BASE_ELEMENT, PERTURBED_ELEMENT >
 
class  StabilityProblem< BASE_ELEMENT, PERTURBED_ELEMENT >
 

Namespaces

 GlobalPhysicalVariables
 Namespace for physical parameters.
 

Functions

int main (int argc, char *argv[])
 Driver for time-periodic Taylor–Couette problem. More...
 

Variables

double GlobalPhysicalVariables::MMC_Re_current
 
double GlobalPhysicalVariables::MMC_Re_lower_limit = 20.93
 Loop information. More...
 
double GlobalPhysicalVariables::MMC_Re_upper_limit = 20.94
 
double GlobalPhysicalVariables::AngularFrequency = 10.58
 Angular frequency of outer cylinder rotation (omega = 2*gamma^2) More...
 
double GlobalPhysicalVariables::Epsilon = 0.9
 Dimensionless modulation amplitude (epsilon) More...
 
double GlobalPhysicalVariables::Eta = 0.88
 Radius ratio (radius of inner cylinder / radius of outer cylinder) More...
 
double GlobalPhysicalVariables::a = 3.2
 Wavenumber of azimuthal waves e^iaz. More...
 
Vector< doubleGlobalPhysicalVariables::G (3)
 Direction of gravity. More...
 

Function Documentation

◆ main()

int main ( int argc  ,
char argv[] 
)

Driver for time-periodic Taylor–Couette problem.

////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////

1633 {
1634  // Store command line arguments
1635  CommandLineArgs::setup(argc,argv);
1636 
1637  // Set number of elements in radial (r) direction
1638  const unsigned base_n_r = 16;
1639  const unsigned perturbed_n_r = 16;
1640 
1641  // Set number of elements in axial (z) direction
1642  const unsigned base_n_z = 16;
1643  const unsigned perturbed_n_z = 16;
1644 
1645  // Cache radius ratio
1646  const double eta = GlobalPhysicalVariables::Eta;
1647 
1648  // Determine tadius of inner cylinder
1649  const double radius_inner_cylinder = eta/(1.0-eta);
1650 
1651  // Determine radius of outer cylinder
1652  const double radius_outer_cylinder = 1.0/(1.0-eta);
1653 
1654  // Length in axial (z) direction (set to fit in half a wavelength)
1656 
1657  // Set direction of gravity (vertically downwards)
1658  GlobalPhysicalVariables::G[0] = 0.0;
1659  GlobalPhysicalVariables::G[1] = -1.0;
1660  GlobalPhysicalVariables::G[2] = 0.0;
1661 
1662  // Determine period of the base state problem
1663  const double T =
1665 
1666  // Set number of timesteps per period
1667  unsigned nstep = 40;
1668 
1669  // Set maximum number of iterations of the power method
1670  unsigned max_iter = 1000;
1671 
1672  // Set tolerance for power method convergence (this is usually machine
1673  // precision according to Bai, Demmel, Dongarra, Ruhe & Van der Vorst)
1674  const double power_method_tolerance = 1e-8;
1675 
1676  // Set tolerance for L2 norm of difference in dof vectors from one
1677  // period to the next for defining the point at which the base flow
1678  // has settled down to a periodic state.
1679  double base_flow_norm_tolerance = 1e-6;
1680 
1681  // Cache upper and lower limits and number of steps for loop over MMC_Re
1684  double n_param_steps = GlobalPhysicalVariables::Nparam_steps;
1685 
1686  // If we are doing a validation run, only compute one value of the
1687  // Reynolds number, use a lower number of timesteps per period,
1688  // accept a lower base flow convergence tolerance and insist that
1689  // only one iteration of the power method is performed
1690  if(CommandLineArgs::Argc>1)
1691  {
1692  n_param_steps = 1;
1693  nstep = 20;
1694  base_flow_norm_tolerance = 1e-2;
1695  max_iter = 1;
1696  }
1697 
1698  // Check that nstep is exactly divisible by both 2 and 5
1699  // (This is necessary for the self_starting_BDF2 timestepper)
1700  if(nstep%2 != 0 || nstep%5 !=0)
1701  {
1702  cout << "\nThe self-starting BDF2 timestepper requires that the number"
1703  << "\nof timesteps be exactly divisible by both 2 and 5. This is"
1704  << "\nnot the case for nstep = " << nstep << ". Exiting...\n"
1705  << endl;
1706  exit(2);
1707  }
1708 
1709  // Calculate length of timestep
1710  const double dt = T/nstep;
1711 
1712  // -----------------------------------------
1713  // LinearisedAxisymmetricQTaylorHoodElements
1714  // -----------------------------------------
1715  {
1716  cout << "\nDoing LinearisedAxisymmetricQTaylorHoodElements\n" << endl;
1717 
1718  // Build stability problem (this creates base and perturbed state problems)
1721  problem(base_n_r,base_n_z,perturbed_n_r,perturbed_n_z,
1722  radius_inner_cylinder,radius_outer_cylinder,l_z);
1723 
1724  // Set up labels for output
1725  DocInfo doc_info;
1726 
1727  // Output directory
1728  doc_info.set_directory("RESLT_TH");
1729 
1730  // Initialise timestep (also sets weights for all timesteppers)
1731  problem.initialise_dt(dt);
1732 
1733  // Set initial conditions
1734  problem.set_initial_condition();
1735 
1736  // Set up storage for dominant eigenvector and eigenvalue
1737  DoubleVector eigenvector;
1738  double eigenvalue = 0.0;
1739 
1740  // Get initial guess for eigenvector (these are the initial conditions
1741  // set up in PerturbedStateProblem::set_initial_conditions())
1742  problem.get_perturbed_state_problem_dofs(eigenvector);
1743 
1744  // Create and initialise global trace file
1745  ofstream global_trace;
1746  char filename[256];
1747  sprintf(filename,"%s/global_trace_epsilon%2.1f.dat",
1748  doc_info.directory().c_str(),
1750  global_trace.open(filename);
1751  global_trace << "MMC_Re, dominating eigenvalue, "
1752  << "n_periods_to_set_up_periodic_base_flow, "
1753  << "n_power_method_iterations" << std::endl;
1754 
1755  // Begin loop over Reynolds number
1756  for(unsigned param=0;param<n_param_steps;param++)
1757  {
1758  // Set MMC_Re_current to the correct value
1759  if(lower==upper || n_param_steps<=1)
1760  {
1762  }
1763  else
1764  {
1766  lower + (((upper-lower)/(n_param_steps-1))*param);
1767  }
1768 
1769  cout << "\n====================================================" << endl;
1770  cout << "Beginning parameter run " << param+1 << " of "
1771  << n_param_steps << ": MMC_Re = "
1773  cout << "====================================================" << endl;
1774 
1775  // Reset the global time (of both problems!) to zero
1776  problem.reset_global_time_to_zero();
1777 
1778  // Initialise counter for solutions
1779  doc_info.number()=0;
1780 
1781  // Create trace files
1782  problem.create_trace_files(doc_info);
1783 
1784  // Initialise trace files
1785  problem.initialise_trace_files();
1786 
1787  // Output initial conditions
1788  problem.doc_solution(doc_info,false,false);
1789 
1790  // Increment counter for solutions
1791  doc_info.number()++;
1792 
1793  // Set up periodic base flow and record how many period it takes
1794  const unsigned n_periods_to_set_up_periodic_base_flow
1795  = problem.set_up_periodic_base_flow(dt,nstep,doc_info,
1796  base_flow_norm_tolerance);
1797 
1798  // Set up storage for base state dofs over one period
1799  const unsigned n_entries_required = (27*(nstep/10))-3;
1800  Vector<DoubleVector> base_state_dofs_over_period(n_entries_required);
1801 
1802  // Perform power method and store number of iterations
1803  const unsigned n_power_method_iterations =
1804  problem.perform_power_method(dt,nstep,doc_info,power_method_tolerance,
1805  max_iter,eigenvalue,eigenvector,
1806  base_state_dofs_over_period);
1807 
1808  cout << "\nDominating eigenvalue is " << eigenvalue << endl;
1809 
1810  // The corresponding dominating eigenvector is "input"
1811 
1812  // Document in the global trace file
1813  global_trace << GlobalPhysicalVariables::MMC_Re_current << " "
1814  << eigenvalue << " "
1815  << n_periods_to_set_up_periodic_base_flow << " "
1816  << n_power_method_iterations << std::endl;
1817 
1818  // The initial guess for the next power method will be the eigenvector
1819  // calculated by this power method
1820 
1821  // Clear and close trace files
1822  problem.close_trace_files();
1823 
1824  } // End loop over Reynolds number
1825  }
1826 
1827  // ----------------------------------------------
1828  // LinearisedAxisymmetricQCrouzeixRaviartElements
1829  // ----------------------------------------------
1830  {
1831  cout << "\nDoing LinearisedAxisymmetricQCrouzeixRaviartElements\n" << endl;
1832 
1833  // Build stability problem (this creates base and perturbed state problems)
1836  problem(base_n_r,base_n_z,perturbed_n_r,perturbed_n_z,
1837  radius_inner_cylinder,radius_outer_cylinder,l_z);
1838 
1839  // Set up labels for output
1840  DocInfo doc_info;
1841 
1842  // Output directory
1843  doc_info.set_directory("RESLT_CR");
1844 
1845  // Initialise timestep (also sets weights for all timesteppers)
1846  problem.initialise_dt(dt);
1847 
1848  // Set initial conditions
1849  problem.set_initial_condition();
1850 
1851  // Set up storage for dominant eigenvector and eigenvalue
1852  DoubleVector eigenvector;
1853  double eigenvalue = 0.0;
1854 
1855  // Get initial guess for eigenvector (these are the initial conditions
1856  // set up in PerturbedStateProblem::set_initial_conditions())
1857  problem.get_perturbed_state_problem_dofs(eigenvector);
1858 
1859  // Create and initialise global trace file
1860  ofstream global_trace;
1861  char filename[256];
1862  sprintf(filename,"%s/global_trace_epsilon%2.1f.dat",
1863  doc_info.directory().c_str(),
1865  global_trace.open(filename);
1866  global_trace << "MMC_Re, dominating eigenvalue, "
1867  << "n_periods_to_set_up_periodic_base_flow, "
1868  << "n_power_method_iterations" << std::endl;
1869 
1870  // Begin loop over Reynolds number
1871  for(unsigned param=0;param<n_param_steps;param++)
1872  {
1873  // Set MMC_Re_current to the correct value
1874  if(lower==upper || n_param_steps<=1)
1875  {
1877  }
1878  else
1879  {
1881  lower + (((upper-lower)/(n_param_steps-1))*param);
1882  }
1883 
1884  cout << "\n====================================================" << endl;
1885  cout << "Beginning parameter run " << param+1 << " of "
1886  << n_param_steps << ": MMC_Re = "
1888  cout << "====================================================" << endl;
1889 
1890  // Reset the global time (of both problems!) to zero
1891  problem.reset_global_time_to_zero();
1892 
1893  // Initialise counter for solutions
1894  doc_info.number()=0;
1895 
1896  // Create trace files
1897  problem.create_trace_files(doc_info);
1898 
1899  // Initialise trace files
1900  problem.initialise_trace_files();
1901 
1902  // Output initial conditions
1903  problem.doc_solution(doc_info,false,false);
1904 
1905  // Increment counter for solutions
1906  doc_info.number()++;
1907 
1908  // Set up periodic base flow and record how many period it takes
1909  const unsigned n_periods_to_set_up_periodic_base_flow
1910  = problem.set_up_periodic_base_flow(dt,nstep,doc_info,
1911  base_flow_norm_tolerance);
1912 
1913  // Set up storage for base state dofs over one period
1914  const unsigned n_entries_required = (27*(nstep/10))-3;
1915  Vector<DoubleVector> base_state_dofs_over_period(n_entries_required);
1916 
1917  // Perform power method and store number of iterations
1918  const unsigned n_power_method_iterations =
1919  problem.perform_power_method(dt,nstep,doc_info,power_method_tolerance,
1920  max_iter,eigenvalue,eigenvector,
1921  base_state_dofs_over_period);
1922 
1923  cout << "\nDominating eigenvalue is " << eigenvalue << endl;
1924 
1925  // The corresponding dominating eigenvector is "input"
1926 
1927  // Document in the global trace file
1928  global_trace << GlobalPhysicalVariables::MMC_Re_current << " "
1929  << eigenvalue << " "
1930  << n_periods_to_set_up_periodic_base_flow << " "
1931  << n_power_method_iterations << std::endl;
1932 
1933  // The initial guess for the next power method will be the eigenvector
1934  // calculated by this power method
1935 
1936  // Clear and close trace files
1937  problem.close_trace_files();
1938 
1939  } // End loop over Reynolds number
1940  }
1941 
1942 } // End of main
Array< double, 1, 3 > e(1./3., 0.5, 2.)
Definition: demo_drivers/axisym_navier_stokes/counter_rotating_disks/multi_domain_linearised_axisym_navier_stokes_elements.h:186
Definition: demo_drivers/axisym_navier_stokes/counter_rotating_disks/multi_domain_linearised_axisym_navier_stokes_elements.h:54
Definition: axisym_navier_stokes/counter_rotating_disks/counter_rotating_disks.cc:702
Definition: axisym_navier_stokes_elements.h:1234
Definition: axisym_navier_stokes_elements.h:1532
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
Definition: double_vector.h:58
Definition: oomph-lib/src/generic/Vector.h:58
double Pi
Definition: two_d_biharmonic.cc:235
void setup(Time *time_pt)
Create all GeomObjects needed to define the cylinder and the flag.
Definition: turek_flag_non_fsi.cc:277
double MMC_Re_upper_limit
Definition: time_periodic_taylor_couette.cc:77
double MMC_Re_lower_limit
Loop information.
Definition: time_periodic_taylor_couette.cc:76
double Epsilon
Dimensionless modulation amplitude (epsilon)
Definition: time_periodic_taylor_couette.cc:84
double AngularFrequency
Angular frequency of outer cylinder rotation (omega = 2*gamma^2)
Definition: time_periodic_taylor_couette.cc:81
double MMC_Re_current
Definition: time_periodic_taylor_couette.cc:73
Vector< double > G(3)
Direction of gravity.
double a
Wavenumber of azimuthal waves e^iaz.
Definition: time_periodic_taylor_couette.cc:90
unsigned Nparam_steps
Definition: linearised_axisym_navier_stokes/counter_rotating_disks/counter_rotating_disks.cc:77
double Eta
Radius ratio (radius of inner cylinder / radius of outer cylinder)
Definition: time_periodic_taylor_couette.cc:87
string filename
Definition: MergeRestartFiles.py:39
double eta
Definition: foeppl_von_karman/circular_disk/circular_disk.cc:45
std::string lower(std::string s)
returns the input string after converting upper-case characters to lower case
Definition: StringHelpers.cc:11
int Argc
Number of arguments + 1.
Definition: oomph_utilities.cc:407
Constructor for SteadyAxisymAdvectionDiffusion problem
Definition: steady_axisym_advection_diffusion.cc:213

References GlobalPhysicalVariables::a, GlobalPhysicalVariables::AngularFrequency, oomph::CommandLineArgs::Argc, oomph::DocInfo::directory(), e(), GlobalPhysicalVariables::Epsilon, TestSoln::eta, GlobalPhysicalVariables::Eta, MergeRestartFiles::filename, GlobalPhysicalVariables::G, helpers::lower(), GlobalPhysicalVariables::MMC_Re_current, GlobalPhysicalVariables::MMC_Re_lower_limit, GlobalPhysicalVariables::MMC_Re_upper_limit, GlobalPhysicalVariables::Nparam_steps, oomph::DocInfo::number(), BiharmonicTestFunctions2::Pi, problem, oomph::DocInfo::set_directory(), and Flag_definition::setup().