33 #include "navier_stokes.h"
36 #include "meshes/channel_spine_mesh.h"
40 using namespace oomph;
72 class SinusoidalWall :
public GeomObject
79 SinusoidalWall(
const double&
height,
const double& amplitude,
80 const double& zeta_min,
const double& zeta_max)
84 Geom_data_pt.resize(1);
87 Geom_data_pt[0] =
new Data(4);
93 for (
unsigned i=0;i<4;i++) {Geom_data_pt[0]->pin(i);}
96 Geom_data_pt[0]->set_value(0,
height);
97 Geom_data_pt[0]->set_value(1,amplitude);
98 Geom_data_pt[0]->set_value(2,zeta_min);
99 Geom_data_pt[0]->set_value(3,zeta_max);
111 SinusoidalWall(
const Vector<Data*>& geom_data_pt) : GeomObject(1,2)
114 if(geom_data_pt.size()!=1)
116 std::ostringstream error_stream;
118 <<
"Wrong size for geom_data_pt " << geom_data_pt.size() << std::endl;
119 if (geom_data_pt[0]->nvalue()!=1)
121 error_stream <<
"Wrong geom_data_pt[0]->nvalue() "
122 << geom_data_pt[0]->nvalue() << std::endl;
125 throw OomphLibError(error_stream.str(),
126 OOMPH_CURRENT_FUNCTION,
127 OOMPH_EXCEPTION_LOCATION);
130 Geom_data_pt.resize(1);
131 Geom_data_pt[0]=geom_data_pt[0];
145 delete Geom_data_pt[0];
151 double&
height(){
return *Geom_data_pt[0]->value_pt(0);}
154 double& amplitude(){
return *Geom_data_pt[0]->value_pt(1);}
158 void position(
const Vector<double>& zeta, Vector<double>& r)
const
163 throw OomphLibError(
"The vector r has the wrong dimension\n",
164 OOMPH_CURRENT_FUNCTION,
165 OOMPH_EXCEPTION_LOCATION);
169 double H = Geom_data_pt[0]->value(0);
170 double A = Geom_data_pt[0]->value(1);
171 double zeta_min = Geom_data_pt[0]->value(2);
172 double zeta_max = Geom_data_pt[0]->value(3);
173 double Lz = zeta_max-zeta_min;
177 r[1] =
H +
A*sin(MathematicalConstants::Pi*(zeta[0]-zeta_min)/Lz);
184 void position(
const unsigned& t,
const Vector<double>& zeta,
185 Vector<double>& r)
const
188 if (t>Geom_data_pt[0]->time_stepper_pt()->nprev_values())
190 std::ostringstream error_stream;
192 <<
"t > nprev_values() in SpikedLine: " << t <<
" "
193 << Geom_data_pt[0]->time_stepper_pt()->nprev_values() << std::endl;
195 throw OomphLibError(error_stream.str(),
196 OOMPH_CURRENT_FUNCTION,
197 OOMPH_EXCEPTION_LOCATION);
202 double H = Geom_data_pt[0]->value(t,0);
203 double A = Geom_data_pt[0]->value(t,1);
204 double zeta_min = Geom_data_pt[0]->value(t,2);
205 double zeta_max = Geom_data_pt[0]->value(t,3);
206 double Lz = zeta_max-zeta_min;
210 r[1] =
H +
A*sin(MathematicalConstants::Pi*(zeta[0]-zeta_min)/Lz);
218 virtual void dposition(
const Vector<double>& zeta,
219 DenseMatrix<double> &drdzeta)
const
222 double A = Geom_data_pt[0]->value(1);
223 double zeta_min = Geom_data_pt[0]->value(2);
224 double zeta_max = Geom_data_pt[0]->value(3);
225 double Lz = zeta_max-zeta_min;
229 drdzeta(0,1)=MathematicalConstants::Pi*
A*
230 cos(MathematicalConstants::Pi*(zeta[0]-zeta_min)/Lz)/Lz;
237 virtual void d2position(
const Vector<double>& zeta,
238 RankThreeTensor<double> &ddrdzeta)
const
241 double A = Geom_data_pt[0]->value(1);
242 double zeta_min = Geom_data_pt[0]->value(2);
243 double zeta_max = Geom_data_pt[0]->value(3);
244 double Lz = zeta_max-zeta_min;
248 ddrdzeta(0,0,1)=-MathematicalConstants::Pi*MathematicalConstants::Pi*
249 A*sin(MathematicalConstants::Pi*(zeta[0]-zeta_min)/Lz)/(Lz*Lz);
258 virtual void d2position(
const Vector<double>& zeta, Vector<double>& r,
259 DenseMatrix<double> &drdzeta,
260 RankThreeTensor<double> &ddrdzeta)
const
263 double H = Geom_data_pt[0]->value(0);
264 double A = Geom_data_pt[0]->value(1);
265 double zeta_min = Geom_data_pt[0]->value(2);
266 double zeta_max = Geom_data_pt[0]->value(3);
267 double Lz = zeta_max-zeta_min;
271 r[1] =
H +
A*sin(MathematicalConstants::Pi*(zeta[0]-zeta_min)/Lz);
275 drdzeta(0,1)=MathematicalConstants::Pi*
A*
276 cos(MathematicalConstants::Pi*(zeta[0]-zeta_min)/Lz)/Lz;
280 ddrdzeta(0,0,1)=-MathematicalConstants::Pi*MathematicalConstants::Pi*
281 A*sin(MathematicalConstants::Pi*(zeta[0]-zeta_min)/Lz)/(Lz*Lz);
285 unsigned ngeom_data()
const {
return Geom_data_pt.size();}
289 Data* geom_data_pt(
const unsigned& j) {
return Geom_data_pt[j];}
295 Vector<Data*> Geom_data_pt;
312 template<
class ELEMENT>
329 mesh_pt()->node_update();
353 template<
class ELEMENT>
383 double amplitude_upper = -0.4*Ly;
386 double zeta_max=Lx0+Lx1;
387 GeomObject* UpperWall =
388 new SinusoidalWall(Ly,amplitude_upper,zeta_min,zeta_max);
392 Problem::mesh_pt() =
new ChannelSpineMesh<ELEMENT>(Nx0,Nx1,Nx2,Ny,
400 unsigned num_bound = mesh_pt()->nboundary();
401 for(
unsigned ibound=0;ibound<num_bound;ibound++)
403 unsigned num_nod= mesh_pt()->nboundary_node(ibound);
404 for (
unsigned inod=0;inod<num_nod;inod++)
409 for (
unsigned i=0;i<2;i++)
411 mesh_pt()->boundary_node_pt(ibound,inod)->pin(i);
417 mesh_pt()->boundary_node_pt(ibound,inod)->pin(1);
425 for (
unsigned ibound=0;ibound<num_bound-1;ibound++)
427 unsigned num_nod= mesh_pt()->nboundary_node(ibound);
428 for (
unsigned inod=0;inod<num_nod;inod++)
432 for (
unsigned i=0;i<2;i++)
434 mesh_pt()->boundary_node_pt(ibound,inod)->set_value(i,0.0);
439 mesh_pt()->boundary_node_pt(ibound,inod)->set_value(1,0.0);
447 unsigned num_nod= mesh_pt()->nboundary_node(ibound);
448 for (
unsigned inod=0;inod<num_nod;inod++)
450 double y=mesh_pt()->boundary_node_pt(ibound,inod)->x(1);
452 mesh_pt()->boundary_node_pt(ibound,inod)->set_value(0,y*(Ly-y));
453 mesh_pt()->boundary_node_pt(ibound,inod)->set_value(1,0.0);
457 unsigned n_element = mesh_pt()->nelement();
462 for(
unsigned e=0;e<n_element;e++)
465 ELEMENT* el_pt =
dynamic_cast<ELEMENT*
>(mesh_pt()->element_pt(e));
471 cout <<
"Number of equations: " << assign_eqn_numbers() << std::endl;
481 template<
class ELEMENT>
492 sprintf(filename,
"%s/soln%i.dat",doc_info.directory().c_str(),
494 some_file.open(filename);
495 mesh_pt()->output(some_file,npts);
510 doc_info.set_directory(
"RESLT");
521 problem.newton_solve();
539 problem.newton_solve();
563 doc_info.set_directory(
"RESLT");
587 double amplitude_upper = -0.4*Ly;
589 double zeta_max=Lx0+Lx1;
590 GeomObject* UpperWall =
591 new SinusoidalWall(Ly,amplitude_upper,zeta_min,zeta_max);
594 ChannelSpineMesh<SpineElement<QTaylorHoodElement<2> > >* mesh_pt =
595 new ChannelSpineMesh<SpineElement<QTaylorHoodElement<2> > >(Nx0,Nx1,Nx2,Ny,
600 mesh_pt->node_update();
603 dynamic_cast<SinusoidalWall*
>(mesh_pt->wall_pt())->amplitude()=0.5;
613 sprintf(filename,
"%s/mesh_update%i.dat",doc_info.directory().c_str(),
618 unsigned n_node = mesh_pt->nnode();
619 for (
unsigned inode=0;inode<n_node;inode++)
621 SpineNode* node_pt=
dynamic_cast<SpineNode*
>(
622 mesh_pt->node_pt(inode));
623 if (node_pt->node_update_fct_id()==1)
625 node_pt->node_update();
627 some_file.open(filename);
628 sprintf(filename,
"%s/mesh_update%i.dat",doc_info.directory().c_str(),
631 mesh_pt->output(some_file,npts);
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
void doc_solution(DocInfo &doc_info)
Doc the solution.
ChannelSpineFlowProblem()
Constructor.
void actions_after_newton_solve()
Update the after solve (empty)
void actions_before_newton_solve()
Update the problem specs before solve. Set velocity boundary conditions just to be on the safe side....
~ChannelSpineFlowProblem()
Destructor: (empty)
////////////////////////////////////////////////////////////////////
double A
Amplitude of indentation.
double height(const double &x)
Height of domain.
double Re
Reynolds number.
double H
Undeformed height of domain.
void doc_sparse_node_update()
Create the files to illustrate the sparse node update operation.
int main()
Driver for channel flow problem with spine mesh.