30 #ifndef OOMPH_FISH_MESH_TEMPLATE_CC 31 #define OOMPH_FISH_MESH_TEMPLATE_CC 43 template<
class ELEMENT>
48 MeshChecker::assert_geometric_element<QElementGeometricBase,ELEMENT>(2);
54 Back_pt=
new Circle(x_c,y_c,r_back);
57 Must_kill_fish_back=
true;
60 build_mesh(time_stepper_pt);
69 template<
class ELEMENT>
74 MeshChecker::assert_geometric_element<QElementGeometricBase,ELEMENT>(2);
88 template<
class ELEMENT>
92 MeshChecker::assert_geometric_element<QElementGeometricBase,ELEMENT>(2);
108 std::ofstream some_file;
114 some_file.open(
"fish_domain.dat");
134 ELEMENT* dummy_el_pt=
new ELEMENT;
137 unsigned n_node_1d=dummy_el_pt->nnode_1d();
143 unsigned nnodes_total=(2*(n_node_1d-1)+1)*(2*(n_node_1d-1)+1);
155 for (
unsigned e=0;
e<nelem;
e++)
161 for (
unsigned i1=0;i1<n_node_1d;i1++)
165 for (
unsigned i0=0;i0<n_node_1d;i0++)
168 unsigned j_local=i0+i1*n_node_1d;
172 construct_node(j_local,time_stepper_pt);
178 s[0]=-1.0+2.0*s_fraction[0];
179 s[1]=-1.0+2.0*s_fraction[1];
185 node_pt->
x(0) = r[0];
186 node_pt->
x(1) = r[1];
198 unsigned node_count=0;
205 double Max_tol_in_node_killing=1.0e-12;
212 for (
unsigned i1=0;i1<n_node_1d;i1++)
216 for (
unsigned i0=0;i0<n_node_1d;i0++)
219 unsigned j_local=i0+i1*n_node_1d;
228 if((i0==0) || (i1==0))
246 zeta[0]=xi_lo+(xi_hi-xi_lo)*
double(i0)/double(n_node_1d-1);
247 Node_pt[node_count]->set_coordinates_on_boundary(0,zeta);
262 for (
unsigned i1=0;i1<n_node_1d;i1++)
266 for (
unsigned i0=0;i0<n_node_1d;i0++)
270 unsigned j_local=i0+i1*n_node_1d;
284 unsigned i0_neigh=n_node_1d-1;
285 unsigned i1_neigh=i1;
286 unsigned j_local_neigh=i0_neigh+i1_neigh*n_node_1d;
290 for (
unsigned i=0;
i<2;
i++)
292 double error=std::fabs(
296 if (error>Max_tol_in_node_killing)
299 <<
i <<
" " << error << std::endl;
323 if((i1==0) ||(i0==n_node_1d-1))
357 for (
unsigned i1=0;i1<n_node_1d;i1++)
361 for (
unsigned i0=0;i0<n_node_1d;i0++)
365 unsigned j_local=i0+i1*n_node_1d;
379 unsigned i0_neigh=i0;
380 unsigned i1_neigh=n_node_1d-1;
381 unsigned j_local_neigh=i0_neigh+i1_neigh*n_node_1d;
384 for (
unsigned i=0;
i<2;
i++)
386 double error=std::fabs(
390 if (error>Max_tol_in_node_killing)
393 <<
i <<
" " << error << std::endl;
416 if((i1==n_node_1d-1) || (i0==0))
435 zeta[0]=xi_lo+(xi_hi-xi_lo)*
double(i0)/double(n_node_1d-1);
437 set_coordinates_on_boundary(4,zeta);
456 for (
unsigned i1=0;i1<n_node_1d;i1++)
460 for (
unsigned i0=0;i0<n_node_1d;i0++)
464 unsigned j_local=i0+i1*n_node_1d;
478 unsigned i0_neigh=n_node_1d-1;
479 unsigned i1_neigh=i1;
480 unsigned j_local_neigh=i0_neigh+i1_neigh*n_node_1d;
484 for (
unsigned i=0;
i<2;
i++)
486 double error=std::fabs(
490 if (error>Max_tol_in_node_killing)
493 <<
i <<
" " << error << std::endl;
512 if ((i0!=0)&&(i1==0))
519 unsigned i0_neigh=i0;
520 unsigned i1_neigh=n_node_1d-1;
521 unsigned j_local_neigh=i0_neigh+i1_neigh*n_node_1d;
525 for (
unsigned i=0;
i<2;
i++)
527 double error=std::fabs(
531 if (error>Max_tol_in_node_killing)
534 <<
i <<
" " << error << std::endl;
558 if((i1==n_node_1d-1) || (i0==n_node_1d-1))
588 std::ostringstream error_message;
589 error_message <<
"Error occured in node killing!\n";
591 <<
"Max. permitted difference in position of the two nodes\n " 592 <<
"that get 'merged' : " << Max_tol_in_node_killing << std::endl;
595 OOMPH_CURRENT_FUNCTION,
596 OOMPH_EXCEPTION_LOCATION);
602 unsigned n_element=this->
nelement();
603 for (
unsigned e=0;e<n_element;e++)
627 for(
unsigned ibound=0;ibound<num_bound;ibound++)
633 for (
unsigned inod=0;inod<num_nod;inod++)
637 get_coordinates_on_boundary(ibound,zeta);
643 if (ibound==0) r[1]=-r[1];
646 for (
unsigned i=0;
i<2;
i++)
649 if (error>Max_tol_in_node_killing)
651 oomph_info <<
"Error in boundary coordinate for direction " 652 <<
i <<
" on boundary " << ibound <<
":" 653 << error << std::endl;
661 << std::endl << std::endl;
673 std::ostringstream error_message;
674 error_message <<
"Error occured in boundary coordinate setup!\n";
676 <<
"Max. tolerance: " << Max_tol_in_node_killing << std::endl;
679 OOMPH_CURRENT_FUNCTION,
680 OOMPH_EXCEPTION_LOCATION);
701 template <
class ELEMENT>
705 this->setup_quadtree_forest();
727 template <
class ELEMENT>
736 if (lower_body_pt==0)
738 std::ostringstream error_message;
739 error_message <<
"Element in AlgebraicFishMesh must be\n" 740 <<
"derived from AlgebraicElementBase\n" 741 <<
"but it is of type: " 745 OOMPH_CURRENT_FUNCTION,
746 OOMPH_EXCEPTION_LOCATION);
761 for (
unsigned i1=0;i1<n_p;i1++)
764 for (
unsigned i0=0;i0<n_p;i0++)
767 unsigned jnod=i0+i1*n_p;
771 geom_object_pt[0]=this->
Back_pt;
777 ref_value[0]=double(i0)/double(n_p-1);
782 ref_value[1]=1.0-double(i1)/double(n_p-1);
790 add_node_update_info(
808 for (
unsigned i1=0;i1<n_p;i1++)
812 for (
unsigned i0=0;i0<n_p;i0++)
816 unsigned jnod=i0+i1*n_p;
820 geom_object_pt[0]=this->
Back_pt;
826 ref_value[0]=double(i0)/double(n_p-1);
831 ref_value[1]=1.0-double(i1)/double(n_p-1);
839 add_node_update_info(
856 for (
unsigned i1=0;i1<n_p;i1++)
859 for (
unsigned i0=0;i0<n_p;i0++)
862 unsigned jnod=i0+i1*n_p;
866 geom_object_pt[0]=this->
Back_pt;
872 ref_value[0]=double(i0)/double(n_p-1);
877 ref_value[1]=double(i1)/double(n_p-1);
885 add_node_update_info(
902 for (
unsigned i1=0;i1<n_p;i1++)
905 for (
unsigned i0=0;i0<n_p;i0++)
908 unsigned jnod=i0+i1*n_p;
912 geom_object_pt[0]=this->
Back_pt;
918 ref_value[0]=double(i0)/double(n_p-1);
923 ref_value[1]=double(i1)/double(n_p-1);
931 add_node_update_info(
949 template <
class ELEMENT>
968 double fract_x=node_pt->
ref_value(
unsigned(0));
981 zeta[0]=zeta_mouth+fract_x*(zeta_near_tail-zeta_mouth);
986 zeta[0]=zeta_near_tail;
988 back_pt->
position(t,zeta,r_near_tail);
992 r_sym[0]=x_mouth+fract_x*(r_near_tail[0]-x_mouth);
996 node_pt->
x(t,0) = r_sym[0]+fract_y*(r_back[0]-r_sym[0]);
997 node_pt->
x(t,1) =sign*(r_sym[1]+fract_y*(r_back[1]-r_sym[1]));
1009 template <
class ELEMENT>
1026 double fract_x=node_pt->
ref_value(
unsigned(0));
1044 double y_fin_edge=r_back[1]+fract_x*(y_tail-r_back[1]);
1047 node_pt->
x(t,0)=r_back[0]+fract_x*(x_tail-r_back[0]);
1048 node_pt->
x(t,1)=sign*fract_y*y_fin_edge;
GeomObject * Back_pt
Pointer to fish back.
GeomObject * geom_object_pt(const unsigned &i)
Return pointer to i-th geometric object involved in default (usually first) update function...
Vector< Node * > Node_pt
Vector of pointers to nodes.
Node *& boundary_node_pt(const unsigned &b, const unsigned &n)
Return pointer to node n on boundary b.
void convert_to_boundary_node(Node *&node_pt, const Vector< FiniteElement *> &finite_element_pt)
A function that upgrades an ordinary node to a boundary node We shouldn't ever really use this...
void add_boundary_node(const unsigned &b, Node *const &node_pt)
Add a (pointer to) a node to the b-th boundary.
std::vector< bool > Boundary_coordinate_exists
Vector of boolean data that indicates whether the boundary coordinates have been set for the boundary...
double & y_fin()
y-position of fin tip
Fish shaped mesh. The geometry is defined by the Domain object FishDomain.
A general Finite Element class.
MacroElement * macro_element_pt(const unsigned &i)
Access to i-th macro element.
bool boundary_coordinate_exists(const unsigned &i) const
Indicate whether the i-th boundary has an intrinsic coordinate.
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
unsigned long nboundary_node(const unsigned &ibound) const
Return number of nodes on a particular boundary.
virtual void position(const Vector< double > &zeta, Vector< double > &r) const =0
Parametrised position on object at current time: r(zeta).
void build_mesh(TimeStepper *time_stepper_pt)
Build the mesh, using the geometric object identified by Back_pt.
bool Must_kill_fish_back
Do I need to kill the fish back geom object?
unsigned long nelement() const
Return number of elements in the mesh.
double & xi_tail()
End coordinate on wall (near tail)
virtual void set_macro_elem_pt(MacroElement *macro_elem_pt)
Set pointer to macro element – can be overloaded in derived elements to perform additional tasks...
unsigned nlagrangian() const
Access function to # of Lagrangian coordinates.
virtual void local_fraction_of_node(const unsigned &j, Vector< double > &s_fraction)
Get the local fraction of the node j in the element A dumb, but correct default implementation is pro...
double & x(const unsigned &i)
Return the i-th nodal coordinate.
double & x_mouth()
x-position of mouth
unsigned nboundary() const
Return number of boundaries.
void set_nboundary(const unsigned &nbound)
Set the number of boundaries in the mesh.
void output_macro_element_boundaries(const std::string &filename, const unsigned &nplot)
Output all macro element boundaries as tecplot zones.
void macro_map(const Vector< double > &s, Vector< double > &r)
The mapping from local to global coordinates at the current time : r(s)
void node_update_in_body(const unsigned &t, AlgebraicNode *&node_pt)
Algebraic update function for nodes in upper/lower body.
void setup_boundary_element_info()
Vector< GeneralisedElement * > Element_pt
Vector of pointers to generalised elements.
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Node *& node_pt(const unsigned long &n)
Return pointer to global node n.
unsigned ndim() const
Access function to # of Eulerian coordinates.
FiniteElement * finite_element_pt(const unsigned &e) const
Upcast (downcast?) to FiniteElement (needed to access FiniteElement member functions).
FishDomain * Domain_pt
Pointer to domain.
double ref_value(const unsigned &i)
Return i-th reference value involved in default (usually first) update function.
void setup_adaptivity()
Setup all the information that's required for spatial adaptivity: Set pointers to macro elements and ...
Fish shaped domain, represented by four MacroElements. Shape is parametrised by GeomObject that repre...
void setup_algebraic_node_update()
Setup algebraic update operation for all nodes (separate function because this task needs to be perfo...
const Vector< GeneralisedElement * > & element_pt() const
Return reference to the Vector of elements.
void output(const std::string &filename, const unsigned &nplot)
Output macro elements.
FishMesh(TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass pointer to timestepper (defaults to the (Steady) default timestepper defined in Mes...
void node_update_in_fin(const unsigned &t, AlgebraicNode *&node_pt)
Algebraic update function for nodes in upper/lower fin.
Base class for time-stepping schemes. Timestepper provides an approximation of the temporal derivativ...
double & x_fin()
x-position of fin tip
double & xi_nose()
Start coordinate on wall (near nose)