32 #ifndef OOMPH_VORTICITY_SMOOTHER_HEADER 33 #define OOMPH_VORTICITY_SMOOTHER_HEADER 37 #include <oomph-lib-config.h> 92 if ((max_deriv<-1)||(max_deriv>3))
95 throw OomphLibError(
"Invalid input value! Should be between -1 and 3!",
96 OOMPH_CURRENT_FUNCTION,
97 OOMPH_EXCEPTION_LOCATION);
114 if ((max_deriv<0)||(max_deriv>1))
117 throw OomphLibError(
"Invalid input value! Should be between 0 and 3!",
118 OOMPH_CURRENT_FUNCTION,
119 OOMPH_EXCEPTION_LOCATION);
163 unsigned n_bins=n+n_dim-1;
179 for (
unsigned i=0;
i<k;++
i)
229 template<
class ELEMENT>
242 Smoothed_vorticity_index=3;
246 Maximum_order_of_recoverable_vorticity_derivatives=3;
250 Maximum_order_of_recoverable_velocity_derivatives=1;
269 Exact_vorticity_fct_pt=0;
291 unsigned n_vector=n_vort_deriv+n_veloc_deriv+1;
297 for (
unsigned i=0;
i<n_vort_deriv+1;
i++)
304 for (
unsigned i=n_vort_deriv+1;
i<n_vort_deriv+n_veloc_deriv+1;
i++)
311 return vort_and_derivs;
321 std::pair<unsigned,unsigned>
332 if (n_vort_deriv+n_veloc_deriv+1==0)
335 throw OomphLibError(
"Not recovering anything so this shouldn't be called.",
336 OOMPH_CURRENT_FUNCTION,
337 OOMPH_EXCEPTION_LOCATION);
342 unsigned max_vort_order=Maximum_order_of_recoverable_vorticity_derivatives;
345 unsigned max_veloc_order=Maximum_order_of_recoverable_velocity_derivatives;
348 unsigned max_vort_recov=0;
351 unsigned max_veloc_recov=0;
354 for (
unsigned j=0;j<max_vort_order+1;j++)
361 for (
unsigned j=1;j<max_veloc_order+1;j++)
368 std::pair<unsigned,unsigned> container_id;
371 unsigned nprev_deriv=0;
377 if (i<max_vort_recov)
380 for (
unsigned jj=0;jj<n_vort_deriv+1;jj++)
386 nprev_deriv+=n_deriv;
392 container_id.first=jj;
395 container_id.second=i-(nprev_deriv-n_deriv);
403 else if (i<max_vort_recov+max_veloc_recov)
407 nprev_deriv=max_vort_recov;
410 for (
unsigned jj=n_vort_deriv+1;jj<n_vort_deriv+n_veloc_deriv+1;jj++)
416 nprev_deriv+=n_deriv;
422 container_id.first=jj;
425 container_id.second=i-(nprev_deriv-n_deriv);
435 std::ostringstream error_message_stream;
438 error_message_stream <<
"Dof number " << i <<
" not associated " 439 <<
"with a vorticity or velocity derivative!" 444 OOMPH_CURRENT_FUNCTION,
445 OOMPH_EXCEPTION_LOCATION);
461 std::pair<unsigned,unsigned>
465 std::pair<unsigned,unsigned> container_id;
468 unsigned derivative_index=
i;
481 for (
unsigned i=0;i<n_vort_derivs+1;i++)
500 if (vector_index==-1)
503 for (
unsigned i=1;i<n_veloc_derivs+1;i++)
509 vector_index=n_vort_derivs+
i;
524 if (vector_index==-1)
527 std::ostringstream error_message_stream;
530 error_message_stream <<
"Value of vector_index has not been set. " 531 <<
"Something's wrong!";
535 OOMPH_CURRENT_FUNCTION,
536 OOMPH_EXCEPTION_LOCATION);
541 container_id.first=vector_index;
544 container_id.second=derivative_index;
559 std::pair<unsigned,unsigned>
id=recovered_dof_to_container_id(i-N_dim-1);
562 unsigned vector_index=
id.first;
565 unsigned deriv_index=
id.second;
571 unsigned max_vort_recov=Maximum_order_of_recoverable_vorticity_derivatives;
574 if (vector_index<max_vort_recov+1)
577 unsigned n_prev_deriv=0;
580 for (
unsigned j=0;j<vector_index;j++)
587 index+=n_prev_deriv+deriv_index;
593 unsigned n_prev_deriv=0;
596 for (
unsigned j=0;j<max_vort_recov+1;j++)
606 for (
unsigned j=1;j<vector_index-n_vort_deriv;j++)
613 index+=n_prev_deriv+deriv_index;
627 return Maximum_order_of_recoverable_vorticity_derivatives;
637 return Maximum_order_of_recoverable_velocity_derivatives;
708 return Exact_vorticity_fct_pt;
716 return Exact_vorticity_fct_pt;
723 return Smoothed_vorticity_index;
752 get_interpolated_values(t,s,values);
767 unsigned n_node=this->nnode();
776 for (
unsigned i=0;
i<N_dim;
i++)
779 unsigned u_nodal_index=this->u_index_nst(
i);
782 for (
unsigned l=0;l<n_node;l++)
785 values[
i]+=this->nodal_value(t,l,u_nodal_index)*psif[l];
790 values[N_dim]=this->interpolated_p_nst(s);
797 unsigned nnod=this->nnode();
800 for (
unsigned j=0;j<nnod;j++)
803 Node* nod_pt=this->node_pt(j);
817 const unsigned& nplot)
826 unsigned n_node=this->nnode();
832 outfile << this->tecplot_zone_string(nplot);
835 unsigned num_plot_points=this->nplot_points(nplot);
839 create_container_for_vorticity_and_derivatives();
842 for (
unsigned iplot=0;iplot<num_plot_points;iplot++)
845 this->get_s_plot(iplot,nplot,s);
848 for (
unsigned i=0;
i<N_dim;
i++)
851 x[
i]=this->interpolated_x(s,
i);
854 outfile << x[
i] <<
" ";
858 outfile <<
"0.0 0.0 0.0 ";
862 Exact_vorticity_fct_pt(x,vort_and_derivs);
865 unsigned n_vector=vort_and_derivs.size();
868 for (
unsigned i=0;
i<n_vector;
i++)
871 unsigned i_entries=vort_and_derivs[
i].size();
874 for (
unsigned j=0;j<i_entries;j++)
877 outfile << (vort_and_derivs[
i])[j] <<
" ";
882 outfile << std::endl;
886 this->write_tecplot_zone_footer(outfile,nplot);
899 unsigned n_node=this->nnode();
905 outfile << this->tecplot_zone_string(nplot);
909 create_container_for_vorticity_and_derivatives();
915 unsigned num_plot_points=this->nplot_points(nplot);
918 for (
unsigned iplot=0;iplot<num_plot_points;iplot++)
921 this->get_s_plot(iplot,nplot,s);
924 vorticity_and_its_derivs(s,vort_and_derivs);
927 for (
unsigned i=0;
i<N_dim;
i++)
930 x[
i]=this->interpolated_x(s,
i);
933 outfile << x[
i] <<
" ";
937 for (
unsigned i=0;
i<N_dim;
i++)
940 outfile << this->interpolated_u_nst(s,
i) <<
" ";
944 outfile << this->interpolated_p_nst(s) <<
" ";
952 unsigned n_vector=vort_and_derivs.size();
955 for (
unsigned i=0;
i<n_vector;
i++)
958 unsigned i_entries=vort_and_derivs[
i].size();
961 for (
unsigned j=0;j<i_entries;j++)
964 outfile << (vort_and_derivs[
i])[j] <<
" ";
969 outfile << std::endl;
973 this->write_tecplot_zone_footer(outfile,nplot);
988 const unsigned& nplot)
const 994 unsigned num_plot_points=this->nplot_points_paraview(nplot);
998 create_container_for_vorticity_and_derivatives();
1001 for (
unsigned iplot=0;iplot<num_plot_points;iplot++)
1004 this->get_s_plot(iplot,nplot,s);
1010 file_out << this->interpolated_u_nst(s,i) << std::endl;
1016 file_out << this->interpolated_p_nst(s) << std::endl;
1019 else if (i<nscalar_paraview())
1022 vorticity_and_its_derivs(s,vort_and_derivs);
1025 std::pair<unsigned,unsigned>
id=recovered_dof_to_container_id(i-N_dim-1);
1028 file_out << (vort_and_derivs[
id.first])[
id.second] << std::endl;
1035 std::stringstream error_stream;
1038 error_stream <<
"These VorticitySmoother elements only store " 1040 <<
"but i is currently: " << i << std::endl;
1044 OOMPH_CURRENT_FUNCTION,
1045 OOMPH_EXCEPTION_LOCATION);
1069 else if (i<nscalar_paraview())
1072 unsigned index=Smoothed_vorticity_index+stored_dof_to_recoverable_dof(i);
1104 return "d^3/dx^2dy";
1107 return "d^3/dxdy^2";
1133 std::stringstream error_stream;
1134 error_stream <<
"These Navier Stokes elements only store " 1135 << nscalar_paraview() <<
" fields,\n" 1136 <<
"but i is currently: " << i << std::endl;
1140 OOMPH_CURRENT_FUNCTION,
1141 OOMPH_EXCEPTION_LOCATION);
1149 void output(std::ostream &outfile,
const unsigned &nplot)
1158 unsigned n_node=this->nnode();
1164 outfile << this->tecplot_zone_string(nplot);
1167 unsigned num_plot_points=this->nplot_points(nplot);
1171 create_container_for_vorticity_and_derivatives();
1174 for (
unsigned iplot=0;iplot<num_plot_points;iplot++)
1177 this->get_s_plot(iplot,nplot,s);
1180 this->
shape(s,psif);
1183 for (
unsigned i=0;
i<N_dim;
i++)
1186 x[
i]=this->interpolated_x(s,
i);
1189 outfile << x[
i] <<
" ";
1193 for (
unsigned i=0;
i<N_dim;
i++)
1196 outfile << this->interpolated_u_nst(s,
i) <<
" ";
1200 outfile << this->interpolated_p_nst(s) <<
" ";
1203 vorticity_and_its_derivs(s,vort_and_derivs);
1206 unsigned n_vector=vort_and_derivs.size();
1209 for (
unsigned i=0;
i<n_vector;
i++)
1212 unsigned i_entries=vort_and_derivs[
i].size();
1215 for (
unsigned j=0;j<i_entries;j++)
1218 outfile << (vort_and_derivs[
i])[j] <<
" ";
1223 outfile << std::endl;
1227 this->write_tecplot_zone_footer(outfile,nplot);
1236 unsigned n_node=this->nnode();
1242 DShape dpsifdx(n_node,2);
1245 this->dshape_eulerian(s,psif,dpsifdx);
1251 for (
unsigned l=0;l<n_node;l++)
1254 for (
unsigned j=0;j<2;j++)
1257 dveloc_dx[j]+=this->nodal_value(l,0)*dpsifdx(l,j);
1260 dveloc_dx[j+2]+=this->nodal_value(l,1)*dpsifdx(l,j);
1268 const unsigned& index)
const 1271 unsigned n_node=this->nnode();
1277 DShape dpsifdx(n_node,2);
1280 this->dshape_eulerian(s,psif,dpsifdx);
1290 for (
unsigned l=0;l<n_node;l++)
1293 dveloc_dx+=this->nodal_value(l,0)*dpsifdx(l,0);
1298 for (
unsigned l=0;l<n_node;l++)
1301 dveloc_dx+=this->nodal_value(l,0)*dpsifdx(l,1);
1306 for (
unsigned l=0;l<n_node;l++)
1309 dveloc_dx+=this->nodal_value(l,1)*dpsifdx(l,0);
1314 for (
unsigned l=0;l<n_node;l++)
1317 dveloc_dx+=this->nodal_value(l,1)*dpsifdx(l,1);
1321 oomph_info <<
"Never get here!" << std::endl;
1331 unsigned n_node=this->nnode();
1337 DShape dpsifdx(n_node,2);
1340 this->dshape_eulerian(s,psif,dpsifdx);
1346 for (
unsigned l=0;l<n_node;l++)
1349 for (
unsigned j=0;j<2;j++)
1352 dvorticity_dx[j]+=this->nodal_value(l,Smoothed_vorticity_index)*
1360 double& dvorticity_dx,
1361 const unsigned& index)
const 1364 unsigned n_node=this->nnode();
1370 DShape dpsifdx(n_node,2);
1373 this->dshape_eulerian(s,psif,dpsifdx);
1383 for (
unsigned l=0;l<n_node;l++)
1386 dvorticity_dx+=this->nodal_value(l,Smoothed_vorticity_index)*dpsifdx(l,0);
1391 for (
unsigned l=0;l<n_node;l++)
1394 dvorticity_dx+=this->nodal_value(l,Smoothed_vorticity_index)*dpsifdx(l,1);
1398 oomph_info <<
"Never get here!" << std::endl;
1408 unsigned n_node=this->nnode();
1414 DShape dpsifdx(n_node,2);
1417 this->dshape_eulerian(s,psif,dpsifdx);
1423 for (
unsigned l=0;l<n_node;l++)
1426 for (
unsigned j=0;j<2;j++)
1429 dvorticity_dxdy[j]+=this->nodal_value(l,Smoothed_vorticity_index+1)*
1434 dvorticity_dxdy[2]+=this->nodal_value(l,Smoothed_vorticity_index+2)*
1443 double& dvorticity_dxdy,
1444 const unsigned& index)
const 1447 unsigned n_node=this->nnode();
1453 DShape dpsifdx(n_node,2);
1456 this->dshape_eulerian(s,psif,dpsifdx);
1459 dvorticity_dxdy=0.0;
1466 for (
unsigned l=0;l<n_node;l++)
1469 dvorticity_dxdy+=this->nodal_value(l,Smoothed_vorticity_index+1)*
1475 for (
unsigned l=0;l<n_node;l++)
1478 dvorticity_dxdy+=this->nodal_value(l,Smoothed_vorticity_index+1)*
1484 for (
unsigned l=0;l<n_node;l++)
1487 dvorticity_dxdy+=this->nodal_value(l,Smoothed_vorticity_index+2)*
1492 oomph_info <<
"Never get here!" << std::endl;
1503 unsigned n_node=this->nnode();
1509 DShape dpsifdx(n_node,2);
1512 this->dshape_eulerian(s,psif,dpsifdx);
1518 for (
unsigned l=0;l<n_node;l++)
1521 dvorticity_dxdxdy[0]+=this->nodal_value(l,Smoothed_vorticity_index+3)*
1525 dvorticity_dxdxdy[1]+=this->nodal_value(l,Smoothed_vorticity_index+4)*
1529 dvorticity_dxdxdy[2]+=this->nodal_value(l,Smoothed_vorticity_index+4)*
1533 dvorticity_dxdxdy[3]+=this->nodal_value(l,Smoothed_vorticity_index+5)*
1542 double& dvorticity_dxdxdy,
1543 const unsigned& index)
const 1546 unsigned n_node=this->nnode();
1552 DShape dpsifdx(n_node,2);
1555 this->dshape_eulerian(s,psif,dpsifdx);
1558 dvorticity_dxdxdy=0.0;
1565 for (
unsigned l=0;l<n_node;l++)
1568 dvorticity_dxdxdy+=this->nodal_value(l,Smoothed_vorticity_index+3)*
1574 for (
unsigned l=0;l<n_node;l++)
1577 dvorticity_dxdxdy+=this->nodal_value(l,Smoothed_vorticity_index+4)*
1583 for (
unsigned l=0;l<n_node;l++)
1586 dvorticity_dxdxdy+=this->nodal_value(l,Smoothed_vorticity_index+4)*
1592 for (
unsigned l=0;l<n_node;l++)
1595 dvorticity_dxdxdy+=this->nodal_value(l,Smoothed_vorticity_index+5)*
1600 oomph_info <<
"Never get here!" << std::endl;
1613 unsigned n_recovered_derivs=(nvorticity_derivatives_to_recover()+
1614 nvelocity_derivatives_to_recover());
1617 if ((n_recovered_derivs==0)||(i>=n_recovered_derivs))
1620 throw OomphLibError(
"Can't calculate this; not recovering enough data.",
1621 OOMPH_CURRENT_FUNCTION,
1622 OOMPH_EXCEPTION_LOCATION);
1628 create_container_for_vorticity_and_derivatives();
1631 std::pair<unsigned,unsigned> indices=recovered_dof_to_container_id(i);
1634 unsigned n_vector=synth_vort_and_derivs.size();
1637 double norm_squared=0.0;
1640 unsigned n_node=this->nnode();
1646 DShape dpsifdx(n_node,2);
1649 unsigned n_intpt=this->integral_pt()->nweight();
1658 for (
unsigned ipt=0;ipt<n_intpt;ipt++)
1661 for (
unsigned ii=0;ii<N_dim;ii++)
1664 s[ii]=this->integral_pt()->knot(ipt,ii);
1668 this->interpolated_x(s,x);
1671 double w=this->integral_pt()->weight(ipt);
1674 double J=this->dshape_eulerian(s,psif,dpsifdx);
1680 double smoothed_vort=0.0;
1683 for (
unsigned l=0;l<n_node;l++)
1686 smoothed_vort+=this->nodal_value(l,Smoothed_vorticity_index+i)*psif[l];
1690 for (
unsigned jj=0;jj<n_vector;jj++)
1697 if (0!=Exact_vorticity_fct_pt)
1700 Exact_vorticity_fct_pt(x,synth_vort_and_derivs);
1704 double synth_quantity=0.0;
1707 synth_quantity=(synth_vort_and_derivs[indices.first])[indices.second];
1710 norm_squared+=pow(smoothed_vort-synth_quantity,2)*
W;
1714 return norm_squared;
1723 unsigned n_node=this->nnode();
1729 this->
shape(s,psif);
1732 unsigned n_vector=vort_and_derivs.size();
1738 for (
unsigned i=0;
i<n_vector;
i++)
1741 vort_and_derivs[
i].initialise(0.0);
1744 unsigned num_entries=vort_and_derivs[
i].size();
1747 for (
unsigned j=0;j<num_entries;j++)
1750 for (
unsigned l=0;l<n_node;l++)
1753 (vort_and_derivs[
i])[j]+=
1754 this->nodal_value(l,Smoothed_vorticity_index+i_dof)*psif[l];
1815 template<
class ELEMENT>
1822 Recovery_order(recovery_order)
1844 return Recovery_order;
1850 void shape_rec(
const Vector<double>& x,Vector<double>& psi_r)
1853 std::ostringstream error_stream;
1856 switch(recovery_order())
1883 psi_r[6]=x[0]*x[0]*x[0];
1884 psi_r[7]=x[0]*x[0]*x[1];
1885 psi_r[8]=x[0]*x[1]*x[1];
1886 psi_r[9]=x[1]*x[1]*x[1];
1891 error_stream <<
"Recovery shape functions for recovery order " 1892 << recovery_order() <<
" haven't yet been implemented for 2D" 1896 throw OomphLibError(error_stream.str(),
1897 OOMPH_CURRENT_FUNCTION,
1898 OOMPH_EXCEPTION_LOCATION);
1916 std::ostringstream error_stream;
1922 switch(recovery_order())
1929 return(
new Gauss<2,2>);
1934 return(
new TGauss<2,2>);
1943 return(
new Gauss<2,3>);
1948 return(
new TGauss<2,3>);
1957 return(
new Gauss<2,4>);
1962 return(
new TGauss<2,4>);
1968 error_stream <<
"Recovery shape functions for recovery order " 1969 << recovery_order() <<
" haven't yet been implemented for 2D" 1973 throw OomphLibError(error_stream.str(),
1974 OOMPH_CURRENT_FUNCTION,
1975 OOMPH_EXCEPTION_LOCATION);
1987 std::map<Node*,Vector<ELEMENT*>*>& adjacent_elements_pt,
1988 Vector<Node*>& vertex_node_pt)
1991 adjacent_elements_pt.clear();
1994 std::map<Node*,Vector<ELEMENT*>*> aux_adjacent_elements_pt;
1998 unsigned ndisagree=0;
2005 unsigned nelem=mesh_pt->nelement();
2006 for (
unsigned e=0;
e<nelem;
e++)
2008 ELEMENT* el_pt=
dynamic_cast<ELEMENT*
>(mesh_pt->element_pt(
e));
2012 if (el_pt->nrecovery_order()!=Recovery_order){ndisagree++;}
2016 unsigned nnod=el_pt->nnode();
2017 for (
unsigned n=0;n<nnod;n++)
2020 Node* nod_pt=el_pt->node_pt(n);
2023 if (aux_adjacent_elements_pt[nod_pt]==0)
2026 aux_adjacent_elements_pt[nod_pt]=
new Vector<ELEMENT*>;
2030 (*aux_adjacent_elements_pt[nod_pt]).push_back(el_pt);
2038 oomph_info <<
"\n\n======================================================\n" 2040 << ndisagree <<
" out of " << mesh_pt->nelement() <<
" elements" 2041 <<
"\nhave different preferences for the order of the recovery" 2042 <<
"\nshape functions. We are using: Recovery_order=" 2043 << Recovery_order << std::endl;
2044 oomph_info <<
"======================================================\n\n";
2049 nelem=mesh_pt->nelement();
2050 for (
unsigned e=0;
e<nelem;
e++)
2052 ELEMENT* el_pt=
dynamic_cast<ELEMENT*
>(mesh_pt->element_pt(
e));
2055 unsigned n_node=el_pt->nvertex_node();
2056 for (
unsigned n=0;n<n_node;n++)
2058 Node* nod_pt=el_pt->vertex_node_pt(n);
2061 if (adjacent_elements_pt[nod_pt]==0)
2064 vertex_node_pt.push_back(nod_pt);
2067 adjacent_elements_pt[nod_pt]=
new Vector<ELEMENT*>;
2070 unsigned nel=(*aux_adjacent_elements_pt[nod_pt]).size();
2071 for (
unsigned e=0;
e<nel;
e++)
2073 (*adjacent_elements_pt[nod_pt]).push_back(
2074 (*aux_adjacent_elements_pt[nod_pt])[
e]);
2081 for (
typename std::map<Node*,Vector<ELEMENT*>*>::iterator it=
2082 aux_adjacent_elements_pt.begin();
2083 it!=aux_adjacent_elements_pt.end();it++)
2097 const Vector<ELEMENT*>& patch_el_pt,
2098 const unsigned& num_recovery_terms,
2099 Vector<double>*& recovered_vorticity_coefficient_pt,
2103 unsigned nelem=patch_el_pt.size();
2106 ELEMENT* el_pt=patch_el_pt[0];
2113 int n_vort_derivs=el_pt->get_maximum_order_of_vorticity_derivative();
2116 int n_veloc_derivs=el_pt->get_maximum_order_of_velocity_derivative();
2119 if (n_vort_derivs+n_veloc_derivs==-1)
2122 std::ostringstream error_stream;
2125 error_stream <<
"Not recovering anything. Change the maximum number " 2126 <<
"of derivatives to recover.";
2129 throw OomphLibError(error_stream.str(),
2130 OOMPH_CURRENT_FUNCTION,
2131 OOMPH_EXCEPTION_LOCATION);
2137 std::pair<unsigned,unsigned> container_id=
2138 el_pt->vorticity_dof_to_container_id(n_deriv);
2141 unsigned max_recoverable_vort_order=el_pt->
2142 get_maximum_order_of_recoverable_vorticity_derivative();
2145 unsigned max_recoverable_veloc_order=el_pt->
2146 get_maximum_order_of_recoverable_velocity_derivative();
2155 for (
unsigned i=0;
i<max_recoverable_vort_order+1;
i++)
2158 counter+=el_pt->npartial_derivative(
i);
2162 if (n_deriv<counter)
2177 for (
unsigned i=1;
i<max_recoverable_veloc_order+1;
i++)
2180 counter+=2*el_pt->npartial_derivative(
i);
2184 if (n_deriv<counter)
2187 case_value=max_recoverable_vort_order+
i;
2200 std::ostringstream error_message_stream;
2203 error_message_stream <<
"Case order has not been set. Something's wrong!";
2206 throw OomphLibError(error_message_stream.str(),
2207 OOMPH_CURRENT_FUNCTION,
2208 OOMPH_EXCEPTION_LOCATION);
2213 double recovered_quantity=0.0;
2216 DenseDoubleMatrix recovery_mat(num_recovery_terms,num_recovery_terms,0.0);
2219 Vector<double> rhs(num_recovery_terms,0.0);
2224 bool is_q_mesh=
true;
2229 if (dynamic_cast<TElementBase*>(patch_el_pt[0]))
2236 Integral*
const integ_pt=this->integral_rec(is_q_mesh);
2239 for (
unsigned e=0;
e<nelem;
e++)
2242 ELEMENT*
const el_pt=patch_el_pt[
e];
2245 Vector<double> psi_r(num_recovery_terms);
2248 Vector<double>
s(2,0.0);
2251 unsigned n_intpt=integ_pt->nweight();
2254 for (
unsigned ipt=0;ipt<n_intpt;ipt++)
2257 for (
unsigned i=0;
i<2;
i++)
2260 s[
i]=integ_pt->knot(ipt,
i);
2264 double w=integ_pt->weight(ipt);
2267 double J=el_pt->J_eulerian(s);
2270 Vector<double> x(2,0.0);
2273 el_pt->interpolated_x(s,x);
2278 double W=w*J*(el_pt->geometric_jacobian(x));
2288 Vector<double> vorticity(1,0.0);
2289 el_pt->get_vorticity(s,vorticity);
2290 recovered_quantity=vorticity[0];
2295 el_pt->get_raw_vorticity_deriv(s,recovered_quantity,
2296 container_id.second);
2301 el_pt->get_raw_vorticity_second_deriv(s,recovered_quantity,
2302 container_id.second);
2307 el_pt->get_raw_vorticity_third_deriv(s,recovered_quantity,
2308 container_id.second);
2313 el_pt->get_raw_velocity_deriv(s,recovered_quantity,
2314 container_id.second);
2319 oomph_info <<
"Never get here." << std::endl;
2327 for (
unsigned l=0;l<num_recovery_terms;l++)
2330 rhs[l]+=recovered_quantity*psi_r[l]*
W;
2334 for (
unsigned l=0;l<num_recovery_terms;l++)
2337 for (
unsigned l2=0;l2<num_recovery_terms;l2++)
2340 recovery_mat(l,l2)+=psi_r[l]*psi_r[l2]*
W;
2352 recovery_mat.ludecompose();
2355 recovery_mat.lubksub(rhs);
2359 recovered_vorticity_coefficient_pt=
new Vector<double>(num_recovery_terms);
2362 for (
unsigned icoeff=0;icoeff<num_recovery_terms;icoeff++)
2365 (*recovered_vorticity_coefficient_pt)[icoeff]=rhs[icoeff];
2373 switch(Recovery_order)
2397 std::ostringstream error_stream;
2400 error_stream <<
"Wrong Recovery_order " << Recovery_order << std::endl;
2403 throw OomphLibError(error_stream.str(),
2404 OOMPH_CURRENT_FUNCTION,
2405 OOMPH_EXCEPTION_LOCATION);
2416 doc_info.disable_doc();
2419 recover_vorticity(mesh_pt,doc_info);
2430 Vector<double>
s(2,0.0);
2433 Vector<double> x(2,0.0);
2438 std::map<Node*,Vector<ELEMENT*>*> adjacent_elements_pt;
2441 Vector<Node*> vertex_node_pt;
2444 setup_patches(mesh_pt,adjacent_elements_pt,vertex_node_pt);
2447 ELEMENT*
const el_pt=
dynamic_cast<ELEMENT*
>(mesh_pt->element_pt(0));
2450 unsigned smoothed_vorticity_index=el_pt->smoothed_vorticity_index();
2453 unsigned max_vort_order=el_pt->
2454 get_maximum_order_of_recoverable_vorticity_derivative();
2457 unsigned max_veloc_order=el_pt->
2458 get_maximum_order_of_recoverable_velocity_derivative();
2461 unsigned max_vort_recov=0;
2464 unsigned max_veloc_recov=0;
2467 for (
unsigned i=0;
i<max_vort_order+1;
i++)
2470 max_vort_recov+=el_pt->npartial_derivative(
i);
2474 for (
unsigned i=1;
i<max_veloc_order+1;
i++)
2477 max_veloc_recov+=2*el_pt->npartial_derivative(
i);
2481 unsigned n_recovered_vort_derivs=el_pt->nvorticity_derivatives_to_recover();
2484 unsigned n_recovered_veloc_derivs=el_pt->nvelocity_derivatives_to_recover();
2488 unsigned num_recovery_terms=nrecovery_order();
2491 std::map<Node*,unsigned> count;
2494 unsigned nodal_dof=0;
2497 for (
unsigned deriv=0;deriv<max_vort_recov+max_veloc_recov;deriv++)
2502 if ((
int(deriv)>
int(n_recovered_vort_derivs-1))&&(deriv<max_vort_recov))
2509 else if ((n_recovered_veloc_derivs==0)&&(deriv>=max_vort_recov))
2516 std::map<Node*,double> averaged_recovered_vort;
2522 for (
typename std::map<Node*,Vector<ELEMENT*>*>::iterator it=
2523 adjacent_elements_pt.begin();it!=adjacent_elements_pt.end();it++)
2526 Vector<double>* recovered_vorticity_coefficient_pt;
2529 get_recovered_vorticity_in_patch(*(it->second),
2531 recovered_vorticity_coefficient_pt,
2538 unsigned nelem=(*(it->second)).size();
2541 for (
unsigned e=0;
e<nelem;
e++)
2544 ELEMENT*
const el_pt=(*(it->second))[
e];
2547 unsigned nnode_el=el_pt->nnode();
2550 for (
unsigned j=0;j<nnode_el;j++)
2553 Node* nod_pt=el_pt->node_pt(j);
2556 el_pt->local_coordinate_of_node(j,s);
2559 el_pt->interpolated_x(s,x);
2562 Vector<double> psi_r(num_recovery_terms);
2568 double recovered_vort=0.0;
2571 for (
unsigned i=0;
i<num_recovery_terms;
i++)
2574 recovered_vort+=(*recovered_vorticity_coefficient_pt)[
i]*psi_r[
i];
2578 averaged_recovered_vort[nod_pt]+=recovered_vort;
2586 delete recovered_vorticity_coefficient_pt;
2589 recovered_vorticity_coefficient_pt=0;
2593 unsigned nnod=mesh_pt->nnode();
2596 for (
unsigned j=0;j<nnod;j++)
2599 Node* nod_pt=mesh_pt->node_pt(j);
2602 averaged_recovered_vort[nod_pt]/=count[nod_pt];
2605 nod_pt->set_value(smoothed_vorticity_index+nodal_dof,
2606 averaged_recovered_vort[nod_pt]);
2617 for (
typename std::map<Node*,Vector<ELEMENT*>*>::iterator it=
2618 adjacent_elements_pt.begin();it!=adjacent_elements_pt.end();it++)
2625 oomph_info <<
"Time for vorticity recovery [sec]: " void broken_copy(const std::string &class_name)
Issue error message and terminate execution.
void get_raw_vorticity_second_deriv(const Vector< double > &s, double &dvorticity_dxdy, const unsigned &index) const
double vorticity_error_squared(const unsigned &i)
Compute the element's contribution to the (squared) L2 norm of the difference between exact and smoot...
int Maximum_order_of_vorticity_derivative
Maximum number of derivatives to retain in the vorticity recovery. Note, the value -1 means we ONLY o...
std::string scalar_name_paraview(const unsigned &i) const
Name of the i-th scalar field. Default implementation returns V1 for the first one, V2 for the second etc. Can (should!) be overloaded with more meaningful names in specific elements.
std::pair< unsigned, unsigned > vorticity_dof_to_container_id(const unsigned &i) const
Helper function that, given the local dof number of the i-th vorticity or velocity derivative...
void get_raw_vorticity_deriv(const Vector< double > &s, Vector< double > &dvorticity_dx) const
Get raw derivative of smoothed vorticity.
void setup_patches(Mesh *&mesh_pt, std::map< Node *, Vector< ELEMENT *> *> &adjacent_elements_pt, Vector< Node *> &vertex_node_pt)
Setup patches: For each vertex node pointed to by nod_pt, adjacent_elements_pt[nod_pt] contains the p...
int get_maximum_order_of_velocity_derivative() const
The maximum order of derivatives calculated in the velocity recovery. Note, this value can only be se...
void get_raw_velocity_deriv(const Vector< double > &s, Vector< double > &dveloc_dx) const
Get raw derivative of velocity.
unsigned get_maximum_order_of_recoverable_vorticity_derivative() const
The maximum order of vorticity derivative that can be recovered. This is set in the constructor and s...
void shape_rec(const Vector< double > &x, Vector< double > &psi_r)
Recovery shape functions as functions of the global, Eulerian coordinate x of dimension dim...
void pin_smoothed_vorticity()
Pin all smoothed vorticity quantities.
VorticitySmootherElement()
Constructor.
void set_maximum_order_of_velocity_derivative(const int &max_deriv)
The maximum order of derivatives calculated in the velocity recovery.
int Maximum_order_of_velocity_derivative
Maximum number of derivatives to retain in the velocity recovery. Note, the value 0 means we don't ca...
unsigned nvorticity_derivatives_to_recover() const
The number of terms calculated in the vorticity recovery. Also includes the zeroth derivative...
ExactVorticityFctPt Exact_vorticity_fct_pt
Pointer to function that specifies exact vorticity and derivs (for validation).
void get_interpolated_values(const unsigned &t, const Vector< double > &s, Vector< double > &values)
Get the function value u in Vector. Note: Given the generality of the interface (this function is usu...
int get_maximum_order_of_vorticity_derivative() const
The maximum order of derivatives calculated in the vorticity recovery. Note, this value can only be s...
int maximum_order_of_vorticity_derivative() const
The maximum order of derivatives calculated in the vorticity recovery.
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
unsigned nscalar_paraview() const
Number of scalars/fields output by this element. Re-implements broken virtual function in base class...
void get_raw_vorticity_third_deriv(const Vector< double > &s, double &dvorticity_dxdxdy, const unsigned &index) const
unsigned ncont_interpolated_values() const
Number of continuously interpolated values:
void pin(const unsigned &i)
Pin the i-th stored variable.
unsigned & recovery_order()
Access function for order of recovery polynomials.
VorticitySmoother(const VorticitySmoother &)
Broken copy constructor.
ExactVorticityFctPt & exact_vorticity_fct_pt()
Access function: Pointer to function that specifies exact vorticity and derivatives (for validation)...
unsigned nvelocity_derivatives_to_recover() const
unsigned npartial_derivative(const unsigned &n) const
Helper function that determines the number of n-th order partial derivatives in d-dimensions. Specifically there are (n+d-1)(choose)(d-1) possible n-th order partial derivatives in d-dimensions. Implementation makes use of the code found at: www.geeksforgeeks.org/space-and-time-efficient-binomial-coefficient/.
unsigned stored_dof_to_recoverable_dof(const unsigned &i) const
Given the STORED dof number, this function returns the global recovered number. For example...
void get_raw_vorticity_third_deriv(const Vector< double > &s, Vector< double > &dvorticity_dxdxdy) const
int maximum_order_of_velocity_derivative() const
The maximum order of derivatives calculated in the velocity recovery.
void get_recovered_vorticity_in_patch(const Vector< ELEMENT *> &patch_el_pt, const unsigned &num_recovery_terms, Vector< double > *&recovered_vorticity_coefficient_pt, unsigned &n_deriv)
Given the vector of elements that make up a patch, compute the vector of recovered vorticity coeffici...
virtual ~VorticitySmoother()
Empty virtual destructor.
unsigned Maximum_order_of_recoverable_vorticity_derivatives
The current maximum order of vorticity derivatives that can be recovered. Currently, we can recover up to the third derivative: omega,d/dx,d/dy, d^2/dx^2,d^2/dxdy,d^2/dy^2, d^3/dx^3,d^3/dx^2dy,d^3/dxdy^2,d^3/dy^3.
void output(std::ostream &outfile, const unsigned &nplot)
Overloaded output function: Output velocity, pressure and the smoothed vorticity. ...
void recover_vorticity(Mesh *mesh_pt)
Recover vorticity from patches.
unsigned npartial_derivative(const unsigned &n) const
Call the function written in VorticityRecoveryHelpers.
unsigned smoothed_vorticity_index() const
Index of smoothed vorticity – followed by derivatives.
Vector< Vector< double > > create_container_for_vorticity_and_derivatives() const
Helper function to create a container for the vorticity and its partial derivatives. If the user wishes to output everything then this also creates space for the velocity derivatives too. This function has been written to allow for generalisation of the storage without (hopefully!) affecting too much.
void recover_vorticity(Mesh *mesh_pt, DocInfo &doc_info)
Recover vorticity from patches – output intermediate steps to directory specified by DocInfo object...
unsigned Maximum_order_of_recoverable_velocity_derivatives
The current maximum order of velocity derivatives that can be recovered. Currently, we can recover the first derivatives: du/dx,du/dy,dv/dx,dv/dy.
unsigned Recovery_order
Order of recovery polynomials.
void output_smoothed_vorticity(std::ostream &outfile, const unsigned &nplot)
Output the velocity, smoothed vorticity and derivatives.
int Maximum_order_of_velocity_derivative
Maximum number of derivatives to retain in the velocity recovery. Note, the value 0 means we don't ca...
int Maximum_order_of_vorticity_derivative
Maximum number of derivatives to retain in the vorticity recovery. Note, the value -1 means we ONLY o...
double timer()
returns the time in seconds after some point in past
unsigned nrecovery_order() const
Get the recovery order.
void shape(const double &s, double *Psi)
Definition for 1D Lagrange shape functions. The value of all the shape functions at the local coordin...
void initialise(const _Tp &__value)
Iterate over all values and set to the desired value.
void get_interpolated_values(const Vector< double > &s, Vector< double > &values)
Get the function value u in Vector. Note: Given the generality of the interface (this function is usu...
class VorticityRecoveryHelpers::RecoveryHelper Recovery_helper
void set_maximum_order_of_vorticity_derivative(const int &max_deriv)
The maximum order of derivatives calculated in the vorticity recovery.
void get_raw_velocity_deriv(const Vector< double > &s, double &dveloc_dx, const unsigned &index) const
Get raw derivative of velocity.
void get_raw_vorticity_deriv(const Vector< double > &s, double &dvorticity_dx, const unsigned &index) const
Get raw derivative of smoothed vorticity.
void get_raw_vorticity_second_deriv(const Vector< double > &s, Vector< double > &dvorticity_dxdy) const
Get raw derivative of smoothed derivative vorticity.
unsigned required_nvalue(const unsigned &n) const
Number of values required at local node n. In order to simplify matters, we allocate storage for pres...
void broken_assign(const std::string &class_name)
Issue error message and terminate execution.
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
void vorticity_and_its_derivs(const Vector< double > &s, Vector< Vector< double > > &vort_and_derivs) const
Compute smoothed vorticity and its derivatives.
std::pair< unsigned, unsigned > recovered_dof_to_container_id(const unsigned &i) const
Helper function that, given the local dof number of the i-th vorticity or velocity derivative...
void scalar_value_paraview(std::ofstream &file_out, const unsigned &i, const unsigned &nplot) const
Write values of the i-th scalar field at the plot points. Needs to be implemented for each new specif...
unsigned get_maximum_order_of_recoverable_velocity_derivative() const
The maximum order of velocity derivative that can be recovered. This is set in the constructor and sh...
ExactVorticityFctPt exact_vorticity_fct_pt() const
Access function: Pointer to function that specifies exact vorticity and derivatives (for validation) ...
VorticitySmoother(const unsigned &recovery_order)
Constructor: Set order of recovery shape functions.
Integral * integral_rec(const bool &is_q_mesh)
unsigned ncont_interpolated_values() const
Number of continuously interpolated values:
unsigned Number_of_values_per_field
Number of values per field; how many of the following do we want: u,v,p,omega,d/dx,d/dy, d^2/dx^2,d^2/dxdy,d^2/dy^2, d^3/dx^3,d^3/dx^2dy,d^3/dxdy^2,d^3/dy^3, du/dx,du/dy,dv/dx,dv/dy.
Class to indicate which derivatives of the vorticity/ velocity we want to recover. We choose to immediately instantiate an object of this class by dropping the semi-colon after the class description.
void output_analytical_veloc_and_vorticity(std::ostream &outfile, const unsigned &nplot)
Output exact velocity, vorticity, derivatives and indicator based on functions specified by two funct...
RecoveryHelper()
Constructor.
void operator=(const VorticitySmoother &)
Broken assignment operator.
unsigned Number_of_values_per_field
Number of values per field; how many of the following do we want: u,v,p,omega,d/dx,d/dy, d^2/dx^2,d^2/dxdy,d^2/dy^2, d^3/dx^3,d^3/dx^2dy,d^3/dxdy^2,d^3/dy^3, du/dx,du/dy,dv/dx,dv/dy.
Smoother for vorticity in 2D.
unsigned N_dim
Number of dimensions in the element.
std::string to_string(T object, unsigned float_precision=8)
Conversion function that should work for anything with operator<< defined (at least all basic types)...
unsigned Smoothed_vorticity_index
Index of smoothed vorticity – followed by derivatives; in 2D this has value 3.
void calculate_number_of_values_per_field()
Calculates the number of values per field given the number of vorticity and velocity derivatives to r...