32 #include "unsteady_heat.h" 
   35 #include "meshes/quarter_circle_sector_mesh.h" 
   39 using namespace oomph;
 
   41 using namespace MathematicalConstants;
 
   57            const double& a_hat, 
const double& b_hat, 
 
   58            const double& period, Time* time_pt) : 
 
   59   GeomObject(1,2), A(a), B(b), A_hat(a_hat), B_hat(b_hat), 
 
   60   T(period), Time_pt(time_pt) {}
 
   67  void position(
const Vector<double>& xi, Vector<double>& r)
 const 
   70    double time=Time_pt->time();
 
   73    r[0] = (A+A_hat*sin(2.0*MathematicalConstants::Pi*time/T))*cos(xi[0]);
 
   74    r[1] = (B+B_hat*sin(2.0*MathematicalConstants::Pi*time/T))*sin(xi[0]);
 
   83  void position(
const unsigned& t, 
const Vector<double>& xi,
 
   84                Vector<double>& r)
 const 
   87    double time=Time_pt->time(t);
 
   90    r[0] = (A+A_hat*sin(2.0*MathematicalConstants::Pi*time/T))*cos(xi[0]);
 
   91    r[1] = (B+B_hat*sin(2.0*MathematicalConstants::Pi*time/T))*sin(xi[0]);
 
  145   return Beta*tanh(
Gamma*cos(0.2E1*MathematicalConstants::Pi*time));
 
  155        MathematicalConstants::Pi*time)))-Y));
 
  159  void get_exact_u(
const double& time, 
const Vector<double>& x, 
double& u)
 
  164          MathematicalConstants::Pi*time)))-Y));
 
  168  void get_source(
const double& time, 
const Vector<double>& x, 
double& source)
 
  173 MathematicalConstants::Pi*time)))-Y))*(1.0-pow(tanh(0.1E1-
Alpha*(
TanPhi*(X-
 
  174 Beta*tanh(
Gamma*cos(0.2E1*MathematicalConstants::Pi*time)))-Y)),2.0))*
Alpha*
 
  176 MathematicalConstants::Pi*time)))-Y))*(1.0-pow(tanh(0.1E1-
Alpha*(
TanPhi*(X-
 
  177 Beta*tanh(
Gamma*cos(0.2E1*MathematicalConstants::Pi*time)))-Y)),2.0))*
Alpha*
 
  179 MathematicalConstants::Pi*time)))-Y)),2.0))*
Alpha*
TanPhi*
Beta*(1.0-pow(tanh(
 
  180 Gamma*cos(0.2E1*MathematicalConstants::Pi*time)),2.0))*
Gamma*sin(0.2E1*
 
  181 MathematicalConstants::Pi*time)*MathematicalConstants::Pi;
 
  186                                           const Vector<double>& x, 
 
  198 MathematicalConstants::Pi*time)))-Y)),2.0))*
Alpha*
TanPhi*NX+(1.0-pow(tanh(
 
  200 time)))-Y)),2.0))*
Alpha*NY;
 
  214 template<
class ELEMENT>
 
  222                              UnsteadyHeatSourceFctPt source_fct_pt);
 
  238  void actions_before_implicit_timestep();
 
  241  void actions_before_adapt();
 
  244  void actions_after_adapt();
 
  251  void set_initial_condition();
 
  256  void create_flux_elements(
const unsigned &b, Mesh* 
const &bulk_mesh_pt,
 
  257                            Mesh* 
const &surface_mesh_pt);
 
  260  void delete_flux_elements(Mesh* 
const &surface_mesh_pt);
 
  266  void dump_it(ofstream& dump_file);
 
  269  void restart(ifstream& restart_file);
 
  307 template<
class ELEMENT>
 
  309    UnsteadyHeatEquations<2>::UnsteadyHeatSourceFctPt source_fct_pt) : 
 
  310          Source_fct_pt(source_fct_pt)
 
  325  sprintf(filename,
"%s/trace.dat",
Doc_info.directory().c_str());
 
  328  Trace_file << 
"VARIABLES=\"time t\",\"u<SUB>FE</SUB>\",\"u<SUB>exact</SUB>\"," 
  330             << 
"\"X<SUB>step</SUB>\"," 
  331             << 
"\"N<SUB>element</SUB>\"," 
  332             << 
"\"N<SUB>refined</SUB>\"," 
  333             << 
"\"N<SUB>unrefined</SUB>\"," 
  334             << 
"\"norm of error\"," 
  335             << 
"\"norm of solution\"" 
  357  add_time_stepper_pt(
new BDF<2>());
 
  382  double xi_hi=MathematicalConstants::Pi/2.0;
 
  387  double fract_mid=0.5;
 
  388  Bulk_mesh_pt = 
new RefineableQuarterCircleSectorMesh<ELEMENT>(
 
  389   Boundary_pt,xi_lo,fract_mid,xi_hi,time_stepper_pt());
 
  407  Z2ErrorEstimator* error_estimator_pt=
new Z2ErrorEstimator;
 
  408  Bulk_mesh_pt->spatial_error_estimator_pt()=error_estimator_pt;
 
  414  for(
unsigned b=0;b<n_bound;b++)
 
  421      for (
unsigned n=0;n<n_node;n++)
 
  430  FiniteElement* el0_pt=
Bulk_mesh_pt->finite_element_pt(0);
 
  431  unsigned nnod=el0_pt->nnode();
 
  443  for(
unsigned i=0;i<n_element;i++)
 
  446    ELEMENT *el_pt = 
dynamic_cast<ELEMENT*
>(
Bulk_mesh_pt->element_pt(i));
 
  454  for(
unsigned e=0;e<n_element;e++)
 
  457    UnsteadyHeatFluxElement<ELEMENT> *el_pt = 
 
  458     dynamic_cast<UnsteadyHeatFluxElement<ELEMENT>*
>(
 
  462    el_pt->flux_fct_pt() = 
 
  467  cout <<
"Number of equations: " << assign_eqn_numbers() << std::endl; 
 
  475 template<
class ELEMENT>
 
  488 template<
class ELEMENT>
 
  492  Bulk_mesh_pt->node_update();
 
  495  double time=time_pt()->time();
 
  498  unsigned num_bound = Bulk_mesh_pt->nboundary();
 
  499  for(
unsigned b=0;b<num_bound;b++)
 
  505      unsigned num_nod=Bulk_mesh_pt->nboundary_node(b);
 
  506      for (
unsigned j=0;j<num_nod;j++)
 
  508        Node* nod_pt=Bulk_mesh_pt->boundary_node_pt(b,j);
 
  514        nod_pt->set_value(0,u);
 
  524 template<
class ELEMENT>
 
  529  delete_flux_elements(Surface_mesh_pt);
 
  532  rebuild_global_mesh();
 
  540 template<
class ELEMENT>
 
  545  create_flux_elements(0,Bulk_mesh_pt,Surface_mesh_pt);
 
  548  rebuild_global_mesh();
 
  551  unsigned n_element=Surface_mesh_pt->nelement();
 
  552  for(
unsigned e=0;e<n_element;e++)
 
  555    UnsteadyHeatFluxElement<ELEMENT> *el_pt = 
 
  556     dynamic_cast<UnsteadyHeatFluxElement<ELEMENT>*
>(
 
  557      Surface_mesh_pt->element_pt(e));
 
  560    el_pt->flux_fct_pt() = 
 
  570 template<
class ELEMENT>
 
  575  ifstream* restart_file_pt=0;
 
  581  if (CommandLineArgs::Argc==1)
 
  583    cout << 
"No restart -- setting IC from exact solution" << std::endl;
 
  585  else if (CommandLineArgs::Argc==2)
 
  588    restart_file_pt= 
new ifstream(CommandLineArgs::Argv[1],ios_base::in);
 
  589    if (restart_file_pt!=0)
 
  591      cout << 
"Have opened " << CommandLineArgs::Argv[1] << 
 
  592       " for restart. " << std::endl;
 
  596      std::ostringstream error_stream;
 
  598       << 
"ERROR while trying to open " << CommandLineArgs::Argv[1] << 
 
  599       " for restart." << std::endl;
 
  603       OOMPH_CURRENT_FUNCTION,
 
  604       OOMPH_EXCEPTION_LOCATION);
 
  610    std::ostringstream error_stream;
 
  611    error_stream << 
"Can only specify one input file\n"  
  612                 << 
"You specified the following command line arguments:\n";
 
  614    CommandLineArgs::output();
 
  618     OOMPH_CURRENT_FUNCTION,
 
  619     OOMPH_EXCEPTION_LOCATION);
 
  625  if (restart_file_pt!=0)
 
  629    restart(*restart_file_pt);
 
  643    double backed_up_time=time_pt()->time();
 
  650    Vector<double> soln(1);
 
  654    unsigned num_nod = Bulk_mesh_pt->nnode();
 
  657    int nprev_steps=time_stepper_pt()->nprev_values();
 
  658    Vector<double> prev_time(nprev_steps+1);
 
  659    for (
int itime=nprev_steps;itime>=0;itime--)
 
  661      prev_time[itime]=time_pt()->time(
unsigned(itime));
 
  666    for (
int itime=nprev_steps;itime>=0;itime--)
 
  668      double time=prev_time[itime];
 
  672      time_pt()->time()=time;
 
  674      cout << 
"setting IC at time =" << time << std::endl;
 
  679      Bulk_mesh_pt->node_update(); 
 
  682      for (
unsigned jnod=0;jnod<num_nod;jnod++)
 
  685        x[0]=Bulk_mesh_pt->node_pt(jnod)->x(0);
 
  686        x[1]=Bulk_mesh_pt->node_pt(jnod)->x(1);
 
  692        Bulk_mesh_pt->node_pt(jnod)->set_value(itime,0,soln[0]);
 
  695        for (
unsigned i=0;i<2;i++)
 
  697          Bulk_mesh_pt->node_pt(jnod)->x(itime,i)=x[i];
 
  703    time_pt()->time()=backed_up_time;
 
  712 template<
class ELEMENT>
 
  723  cout << 
"=================================================" << std::endl;
 
  724  cout << 
"Docing solution for t=" << time_pt()->time() << std::endl;
 
  725  cout << 
"=================================================" << std::endl;
 
  729  sprintf(filename,
"%s/soln%i.dat",Doc_info.directory().c_str(),
 
  731  some_file.open(filename);
 
  732  Bulk_mesh_pt->output(some_file,npts);
 
  733  some_file << 
"TEXT X=2.5,Y=93.6,F=HELV,HU=POINT,C=BLUE,H=26,T=\"time = "  
  734            << time_pt()->time() << 
"\"";
 
  735  some_file << 
"GEOMETRY X=2.5,Y=98,T=LINE,C=BLUE,LT=0.4" << std::endl;
 
  736  some_file << 
"1" << std::endl;
 
  737  some_file << 
"2" << std::endl;
 
  738  some_file << 
" 0 0" << std::endl;
 
  739  some_file << time_pt()->time()*20.0 << 
" 0" << std::endl;
 
  742  some_file << 
"ZONE I=2,J=2" << std::endl;
 
  743  some_file << 
"0.0 0.0 -1.2" << std::endl;
 
  744  some_file << 
"1.3 0.0 -1.2" << std::endl;
 
  745  some_file << 
"0.0 1.3 -1.2" << std::endl;
 
  746  some_file << 
"1.3 1.3 -1.2" << std::endl;
 
  747  some_file << 
"ZONE I=2,J=2" << std::endl;
 
  748  some_file << 
"0.0 0.0 1.2" << std::endl;
 
  749  some_file << 
"1.3 0.0 1.2" << std::endl;
 
  750  some_file << 
"0.0 1.3 1.2" << std::endl;
 
  751  some_file << 
"1.3 1.3 1.2" << std::endl;
 
  758  sprintf(filename,
"%s/exact_soln%i.dat",Doc_info.directory().c_str(),
 
  760  some_file.open(filename);
 
  761  Bulk_mesh_pt->output_fct(some_file,npts,time_pt()->time(),
 
  765  some_file << 
"ZONE I=2,J=2" << std::endl;
 
  766  some_file << 
"0.0 0.0 -1.2" << std::endl;
 
  767  some_file << 
"1.3 0.0 -1.2" << std::endl;
 
  768  some_file << 
"0.0 1.3 -1.2" << std::endl;
 
  769  some_file << 
"1.3 1.3 -1.2" << std::endl;
 
  770  some_file << 
"ZONE I=2,J=2" << std::endl;
 
  771  some_file << 
"0.0 0.0 1.2" << std::endl;
 
  772  some_file << 
"1.3 0.0 1.2" << std::endl;
 
  773  some_file << 
"0.0 1.3 1.2" << std::endl;
 
  774  some_file << 
"1.3 1.3 1.2" << std::endl;
 
  782  sprintf(filename,
"%s/error%i.dat",Doc_info.directory().c_str(),
 
  784  some_file.open(filename);
 
  785  Bulk_mesh_pt->compute_error(some_file,
 
  795  cout << 
"error: " << error << std::endl; 
 
  796  cout << 
"norm : " << norm << std::endl << std::endl;
 
  799  x[0]=Doc_node_pt->x(0);
 
  800  x[1]=Doc_node_pt->x(1);
 
  803  Vector<double > xi_wall(1);
 
  804  Vector<double > r_wall(2);
 
  806  Boundary_pt->position(xi_wall,r_wall);
 
  807  Trace_file << time_pt()->time() 
 
  808             << 
" " << Doc_node_pt->value(0)
 
  812             << 
" " << Bulk_mesh_pt->nelement() 
 
  813             << 
" " << Bulk_mesh_pt->nrefined()
 
  814             << 
" " << Bulk_mesh_pt->nunrefined() 
 
  816             << 
" " << norm << std::endl;
 
  820  sprintf(filename,
"%s/Wall%i.dat",Doc_info.directory().c_str(),
 
  822  some_file.open(filename);
 
  825  for (
unsigned iplot=0;iplot<nplot;iplot++)
 
  827    xi_wall[0]=0.5*Pi*double(iplot)/double(nplot-1);
 
  828    Boundary_pt->position(xi_wall,r_wall);
 
  829    some_file << r_wall[0] << 
" " << r_wall[1] << std::endl;
 
  834  sprintf(filename,
"%s/restart%i.dat",Doc_info.directory().c_str(),
 
  836  some_file.open(filename);
 
  852 template<
class ELEMENT>
 
  855                      Mesh* 
const &surface_mesh_pt)
 
  858  unsigned n_element = bulk_mesh_pt->nboundary_element(b);
 
  861  for(
unsigned e=0;e<n_element;e++)
 
  864    ELEMENT* bulk_elem_pt = 
dynamic_cast<ELEMENT*
>(
 
  865     bulk_mesh_pt->boundary_element_pt(b,e));
 
  868    int face_index = bulk_mesh_pt->face_index_at_boundary(b,e);
 
  871    UnsteadyHeatFluxElement<ELEMENT>* flux_element_pt = 
new  
  872    UnsteadyHeatFluxElement<ELEMENT>(bulk_elem_pt,face_index);
 
  875    surface_mesh_pt->add_element_pt(flux_element_pt);
 
  885 template<
class ELEMENT>
 
  890  unsigned n_element = surface_mesh_pt->nelement();
 
  893  for(
unsigned e=0;e<n_element;e++)
 
  896    delete surface_mesh_pt->element_pt(e);
 
  900  surface_mesh_pt->flush_element_and_node_storage();
 
  908 template<
class ELEMENT>
 
  913  dump_file << Doc_info.number() << 
" # step number" << std::endl;
 
  916  Problem::dump(dump_file);
 
  923 template<
class ELEMENT>
 
  928  getline(restart_file,input_string,
'#');
 
  931  restart_file.ignore(80,
'\n');
 
  934  Doc_info.number()=unsigned(atof(input_string.c_str()));
 
  937  Problem::read(restart_file);
 
  952 int main(
int argc, 
char* argv[])
 
  956  CommandLineArgs::setup(argc,argv);
 
  975  unsigned max_adapt=10; 
 
  982  double dt=problem.time_pt()->dt();
 
  989  if (CommandLineArgs::Argc==2)
 
  997    problem.refine_uniformly();
 
  998    problem.refine_uniformly();
 
 1008  for (
unsigned istep=0;istep<nstep;istep++)
 
 1011    problem.unsteady_newton_solve(dt,max_adapt,first);
 
double B_hat
Amplitude of variation in y-half axis.
 
double A_hat
Amplitude of variation in x-half axis.
 
void position(const Vector< double > &xi, Vector< double > &r) const
Current position vector to material point at Lagrangian coordinate xi.
 
void position(const unsigned &t, const Vector< double > &xi, Vector< double > &r) const
Parametrised position on object: r(xi). Evaluated at previous time level. t=0: current time; t>0: pre...
 
MyEllipse(const double &a, const double &b, const double &a_hat, const double &b_hat, const double &period, Time *time_pt)
Constructor: Pass half axes, amplitudes of their variation, period of oscillation and pointer to time...
 
double T
Period of oscillation.
 
Time * Time_pt
Pointer to time object.
 
virtual ~MyEllipse()
Destructor: Empty.
 
///////////////////////////////////////////////////////////////////// ///////////////////////////////...
 
void actions_after_adapt()
Actions after adapt: Rebuild the mesh of prescribed flux elements.
 
void dump_it(ofstream &dump_file)
Dump problem data to allow for later restart.
 
Mesh * Surface_mesh_pt
Pointer to the "surface" mesh.
 
void set_initial_condition()
Set initial condition (incl previous timesteps) according to specified function. Note that his overlo...
 
GeomObject * Boundary_pt
Pointer to GeomObject that specifies the domain bondary.
 
void actions_before_adapt()
Actions before adapt: Wipe the mesh of prescribed flux elements.
 
RefineableQuarterCircleSectorMesh< ELEMENT > * bulk_mesh_pt()
Pointer to bulk mesh.
 
void create_flux_elements(const unsigned &b, Mesh *const &bulk_mesh_pt, Mesh *const &surface_mesh_pt)
Create UnsteadyHeat flux elements on boundary b of the Mesh pointed to by bulk_mesh_pt and add them t...
 
void doc_solution()
Doc the solution.
 
Node * Doc_node_pt
Pointer to central node (exists at all refinement levels) for doc.
 
RefineableUnsteadyHeatProblem(UnsteadyHeatEquations< 2 >::UnsteadyHeatSourceFctPt source_fct_pt)
Constructor: Pass pointer to source function.
 
ofstream Trace_file
Trace file.
 
~RefineableUnsteadyHeatProblem()
Destructor: Close trace file.
 
UnsteadyHeatEquations< 2 >::UnsteadyHeatSourceFctPt Source_fct_pt
Pointer to source function.
 
DocInfo Doc_info
Doc info object.
 
void actions_after_implicit_timestep()
Update the problem specs after timestep (empty)
 
void actions_before_newton_solve()
Update the problem specs before solve (empty)
 
void actions_before_implicit_timestep()
Update the problem specs before next timestep: Set Dirchlet boundary conditions from exact solution.
 
void delete_flux_elements(Mesh *const &surface_mesh_pt)
Delete UnsteadyHeat flux elements and wipe the surface mesh.
 
void actions_after_newton_solve()
Update the problem specs after solve (empty)
 
void restart(ifstream &restart_file)
Read problem data for restart.
 
RefineableQuarterCircleSectorMesh< ELEMENT > * Bulk_mesh_pt
Pointer to the "bulk" mesh.
 
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
 
void get_exact_u(const double &time, const Vector< double > &x, Vector< double > &u)
Exact solution as a Vector.
 
double Alpha
Parameter for steepness of step.
 
double Gamma
Parameter for timescale of step translation.
 
void get_exact_u(const double &time, const Vector< double > &x, double &u)
Exact solution as a scalar.
 
double Beta
Parameter for amplitude of step translation.
 
double step_position(const double &time)
Position of step (x-axis intercept)
 
void get_source(const double &time, const Vector< double > &x, double &source)
Source function to make it an exact solution.
 
void prescribed_flux_on_fixed_y_boundary(const double &time, const Vector< double > &x, double &flux)
Flux required by the exact solution on a boundary on which y is fixed.
 
double TanPhi
Parameter for angle of step.
 
int main(int argc, char *argv[])
///////////////////////////////////////////////////////////////////// ///////////////////////////////...