37 #include "navier_stokes.h" 40 #include "meshes/channel_spine_mesh.h" 44 using namespace oomph;
92 SpikedLine(
const Vector<Data*>& geom_data_pt) : GeomObject(1,2)
95 if (geom_data_pt.size()!=1)
97 std::ostringstream error_stream;
99 <<
"Wrong size for geom_data_pt " << geom_data_pt.size() << std::endl;
100 if (geom_data_pt[0]->nvalue()!=1)
102 error_stream <<
"Wrong geom_data_pt[0]->nvalue() " 103 << geom_data_pt[0]->nvalue() << std::endl;
106 throw OomphLibError(error_stream.str(),
107 OOMPH_CURRENT_FUNCTION,
108 OOMPH_EXCEPTION_LOCATION);
111 Geom_data_pt.resize(1);
112 Geom_data_pt[0]=geom_data_pt[0];
122 const double& zeta_min,
const double& zeta_max)
126 Geom_data_pt.resize(1);
129 Geom_data_pt[0] =
new Data(4);
135 for (
unsigned i=0;i<4;i++) {Geom_data_pt[0]->pin(i);}
138 Geom_data_pt[0]->set_value(0,height);
139 Geom_data_pt[0]->set_value(1,amplitude);
140 Geom_data_pt[0]->set_value(2,zeta_min);
141 Geom_data_pt[0]->set_value(3,zeta_max);
151 delete Geom_data_pt[0];
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 halfLz = (zeta_max-zeta_min)/2.0;
177 if (zeta[0]-zeta_min<=halfLz)
179 r[1] = H + A*(zeta[0]-zeta_min)/halfLz;
183 r[1] = H - A*(zeta[0]-zeta_max)/halfLz;
191 void position(
const unsigned& t,
const Vector<double>& zeta,
192 Vector<double>& r)
const 195 if (t>Geom_data_pt[0]->time_stepper_pt()->nprev_values())
197 std::ostringstream error_stream;
199 <<
"t > nprev_values() in SpikedLine: " << t <<
" " 200 << Geom_data_pt[0]->time_stepper_pt()->nprev_values() << std::endl;
202 throw OomphLibError(error_stream.str(),
203 OOMPH_CURRENT_FUNCTION,
204 OOMPH_EXCEPTION_LOCATION);
209 double H = Geom_data_pt[0]->value(t,0);
210 double A = Geom_data_pt[0]->value(t,1);
211 double zeta_min = Geom_data_pt[0]->value(t,2);
212 double zeta_max = Geom_data_pt[0]->value(t,3);
213 double halfLz = (zeta_max-zeta_min)/2.0;
217 if (zeta[0]-zeta_min<=halfLz)
219 r[1] = H + A*(zeta[0]-zeta_min)/halfLz;
223 r[1] = H - A*(zeta[0]-zeta_max)/halfLz;
232 DenseMatrix<double> &drdzeta)
const 235 double A = Geom_data_pt[0]->value(1);
236 double zeta_min = Geom_data_pt[0]->value(2);
237 double zeta_max = Geom_data_pt[0]->value(3);
238 double halfLz = (zeta_max-zeta_min)/2.0;
242 if (zeta[0]-zeta_min<=halfLz)
244 drdzeta(0,1)=A/halfLz;
248 drdzeta(0,1)=-A/halfLz;
257 RankThreeTensor<double> &ddrdzeta)
const 270 virtual void d2position(
const Vector<double>& zeta, Vector<double>& r,
271 DenseMatrix<double> &drdzeta,
272 RankThreeTensor<double> &ddrdzeta)
const 275 double H = Geom_data_pt[0]->value(0);
276 double A = Geom_data_pt[0]->value(1);
277 double zeta_min = Geom_data_pt[0]->value(2);
278 double zeta_max = Geom_data_pt[0]->value(3);
279 double halfLz = (zeta_max-zeta_min)/2.0;
283 if (zeta[0]-zeta_min<=halfLz)
285 r[1] = H + A*(zeta[0]-zeta_min)/halfLz;
289 r[1] = H - A*(zeta[0]-zeta_max)/halfLz;
294 if (zeta[0]-zeta_min<=halfLz)
296 drdzeta(0,1)=A/halfLz;
300 drdzeta(0,1)=-A/halfLz;
335 template<
class ELEMENT>
356 mesh_pt()->node_update();
360 unsigned num_nod= mesh_pt()->nboundary_node(ibound);
361 for (
unsigned inod=0;inod<num_nod;inod++)
363 double y=mesh_pt()->boundary_node_pt(ibound,inod)->x(1);
366 mesh_pt()->boundary_node_pt(ibound,inod)->set_value(i,y*(Ly-y));
369 mesh_pt()->boundary_node_pt(ibound,inod)->set_value(i,0);
374 unsigned num_bound = mesh_pt()->nboundary();
375 for(
unsigned ibound=0;ibound<num_bound-1;ibound++)
377 unsigned num_nod= mesh_pt()->nboundary_node(ibound);
378 for (
unsigned inod=0;inod<num_nod;inod++)
380 for (
unsigned i=0;i<2;i++)
384 mesh_pt()->boundary_node_pt(ibound,inod)->set_value(i,0.0);
388 mesh_pt()->boundary_node_pt(ibound,inod)->set_value(1,0.0);
399 return dynamic_cast<ChannelSpineMesh<ELEMENT>*
>(Problem::mesh_pt());
406 void doc_solution(DocInfo& doc_info);
416 template<
class ELEMENT>
442 double amplitude_upper = -0.4*Ly;
444 double zeta_max=Lx0+Lx1;
445 GeomObject* UpperWall =
446 new SpikedLine(Ly,amplitude_upper,zeta_min,zeta_max);
449 Problem::mesh_pt() =
new ChannelSpineMesh<ELEMENT>(Nx0,Nx1,Nx2,Ny,
456 unsigned num_bound = mesh_pt()->nboundary();
457 for(
unsigned ibound=0;ibound<num_bound;ibound++)
459 unsigned num_nod= mesh_pt()->nboundary_node(ibound);
460 for (
unsigned inod=0;inod<num_nod;inod++)
465 for (
unsigned i=0;i<2;i++)
467 mesh_pt()->boundary_node_pt(ibound,inod)->pin(i);
473 mesh_pt()->boundary_node_pt(ibound,inod)->pin(1);
479 unsigned n_element = mesh_pt()->nelement();
484 for(
unsigned e=0;e<n_element;e++)
487 ELEMENT* el_pt =
dynamic_cast<ELEMENT*
>(mesh_pt()->element_pt(e));
493 cout <<
"Number of equations: " << assign_eqn_numbers() << std::endl;
502 template<
class ELEMENT>
513 sprintf(filename,
"%s/soln%i.dat",doc_info.directory().c_str(),
515 some_file.open(filename);
516 mesh_pt()->output(some_file,npts);
529 doc_info.set_directory(
"RESLT");
540 problem.newton_solve();
558 problem.newton_solve();
Namespace for physical parameters.
int main()
Driver for SpikedChannelSpineFlow test problem.
double height(const double &x)
Height of domain.
unsigned ngeom_data() const
How many items of Data does the shape of the object depend on?
void actions_before_newton_solve()
Update the problem specs before solve. set velocity boundary conditions just to be on the safe side...
~SpikedChannelSpineFlowProblem()
Destructor: Empty.
~SpikedLine()
Destructor: Clean up if necessary.
void position(const unsigned &t, const Vector< double > &zeta, Vector< double > &r) const
Parametrised position on object: r(zeta). Evaluated at previous timestep. t=0: current time; t>0: pre...
void position(const Vector< double > &zeta, Vector< double > &r) const
Position Vector at Lagrangian coordinate zeta.
SpikedLine(const Vector< Data *> &geom_data_pt)
Constructor: Four item of geometric data:
void doc_solution(DocInfo &doc_info)
Doc the solution.
SpikedChannelSpineFlowProblem()
Constructor.
virtual void d2position(const Vector< double > &zeta, RankThreeTensor< double > &ddrdzeta) const
2nd derivative of position Vector w.r.t. to coordinates: = ddrdzeta(alpha,beta,i). Evaluated at current time.
Data * geom_data_pt(const unsigned &j)
Return pointer to the j-th Data item that the object's shape depends on.
SpikedLine(const double &height, const double &litude, const double &zeta_min, const double &zeta_max)
Constructor: Pass height, amplitude, zeta min and zeta max (all are pinned by default) ...
double Re
Reynolds number.
Vector< Data * > Geom_data_pt
Vector of pointers to Data items that affects the object's shape.
double H
Undeformed height of domain.
virtual void dposition(const Vector< double > &zeta, DenseMatrix< double > &drdzeta) const
Derivative of position Vector w.r.t. to coordinates: = drdzeta(alpha,i). Evaluated at current time...
bool Must_clean_up
Do I need to clean up?
double Ly
Width of channel.
virtual void d2position(const Vector< double > &zeta, Vector< double > &r, DenseMatrix< double > &drdzeta, RankThreeTensor< double > &ddrdzeta) const
Posn Vector and its 1st & 2nd derivatives w.r.t. to coordinates: = drdzeta(alpha,i). = ddrdzeta(alpha,beta,i). Evaluated at current time.
Channel flow, through a non-uniform channel, using Spines.
double A
Amplitude of indentation.
void actions_after_newton_solve()
Update the after solve (empty)
ChannelSpineMesh< ELEMENT > * mesh_pt()
Upcasted access function for the mesh.