26 #ifndef OOMPH_QUARTER_TUBE_MESH_TEMPLATE_CC 
   27 #define OOMPH_QUARTER_TUBE_MESH_TEMPLATE_CC 
   43   template<
class ELEMENT>
 
   45                                             const Vector<double>& xi_lo,
 
   46                                             const double& fract_mid,
 
   47                                             const Vector<double>& xi_hi,
 
   48                                             const unsigned& nlayer,
 
   49                                             TimeStepper* time_stepper_pt)
 
   50     : Wall_pt(wall_pt), Xi_lo(xi_lo), Fract_mid(fract_mid), Xi_hi(xi_hi)
 
   53     MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(3);
 
   62     Boundary_coordinate_exists[3] = 
true;
 
   65     unsigned nelem = 3 * nlayer;
 
   66     Element_pt.resize(nelem);
 
   69     ELEMENT* dummy_el_pt = 
new ELEMENT;
 
   72     unsigned n_p = dummy_el_pt->nnode_1d();
 
   78     unsigned nnodes_total =
 
   79       (n_p * n_p + (n_p - 1) * n_p + (n_p - 1) * (n_p - 1)) *
 
   80       (1 + nlayer * (n_p - 1));
 
   81     Node_pt.resize(nnodes_total);
 
   88     Vector<double> zeta(2);
 
   91     for (
unsigned ielem = 0; ielem < nelem; ielem++)
 
   94       Element_pt[ielem] = 
new ELEMENT;
 
   97       for (
unsigned i2 = 0; i2 < n_p; i2++)
 
  100         for (
unsigned i1 = 0; i1 < n_p; i1++)
 
  103           for (
unsigned i0 = 0; i0 < n_p; i0++)
 
  106             unsigned jnod_local = i0 + i1 * n_p + i2 * n_p * n_p;
 
  109             Node* node_pt = finite_element_pt(ielem)->construct_node(
 
  110               jnod_local, time_stepper_pt);
 
  113             s[0] = -1.0 + 2.0 * double(i0) / double(n_p - 1);
 
  114             s[1] = -1.0 + 2.0 * double(i1) / double(n_p - 1);
 
  115             s[2] = -1.0 + 2.0 * double(i2) / double(n_p - 1);
 
  116             Domain_pt->macro_element_pt(ielem)->macro_map(s, r);
 
  118             node_pt->x(0) = r[0];
 
  119             node_pt->x(1) = r[1];
 
  120             node_pt->x(2) = r[2];
 
  127     unsigned node_count = 0;
 
  130     double node_kill_tol = 1.0e-12;
 
  136     for (
unsigned ielem = 0; ielem < nelem; ielem++)
 
  139       unsigned ilayer = unsigned(ielem / 3);
 
  150           for (
unsigned i2 = 0; i2 < n_p; i2++)
 
  153             for (
unsigned i1 = 0; i1 < n_p; i1++)
 
  156               for (
unsigned i0 = 0; i0 < n_p; i0++)
 
  159                 unsigned jnod_local = i0 + i1 * n_p + i2 * n_p * n_p;
 
  166                 if ((i2 == 0) && (ilayer > 0))
 
  169                   unsigned ielem_neigh = ielem - 3;
 
  172                   unsigned i0_neigh = i0;
 
  173                   unsigned i1_neigh = i1;
 
  174                   unsigned i2_neigh = n_p - 1;
 
  175                   unsigned jnod_local_neigh =
 
  176                     i0_neigh + i1_neigh * n_p + i2_neigh * n_p * n_p;
 
  179                   for (
unsigned i = 0; i < 3; i++)
 
  181                     double error = std::fabs(
 
  182                       finite_element_pt(ielem)->node_pt(jnod_local)->x(i) -
 
  183                       finite_element_pt(ielem_neigh)
 
  184                         ->node_pt(jnod_local_neigh)
 
  186                     if (error > node_kill_tol)
 
  188                       oomph_info << 
"Error in node killing for i " << i << 
" " 
  189                                  << error << std::endl;
 
  195                   delete finite_element_pt(ielem)->node_pt(jnod_local);
 
  199                   finite_element_pt(ielem)->node_pt(jnod_local) =
 
  200                     finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
 
  206                   Node_pt[node_count] =
 
  207                     finite_element_pt(ielem)->node_pt(jnod_local);
 
  212                   if ((i2 == 0) && (ilayer == 0))
 
  214                     this->convert_to_boundary_node(Node_pt[node_count]);
 
  215                     add_boundary_node(0, Node_pt[node_count]);
 
  219                   if ((i2 == n_p - 1) && (ilayer == nlayer - 1))
 
  221                     this->convert_to_boundary_node(Node_pt[node_count]);
 
  222                     add_boundary_node(4, Node_pt[node_count]);
 
  228                     this->convert_to_boundary_node(Node_pt[node_count]);
 
  229                     add_boundary_node(1, Node_pt[node_count]);
 
  235                     this->convert_to_boundary_node(Node_pt[node_count]);
 
  236                     add_boundary_node(2, Node_pt[node_count]);
 
  255           for (
unsigned i2 = 0; i2 < n_p; i2++)
 
  258             for (
unsigned i1 = 0; i1 < n_p; i1++)
 
  261               for (
unsigned i0 = 0; i0 < n_p; i0++)
 
  264                 unsigned jnod_local = i0 + i1 * n_p + i2 * n_p * n_p;
 
  271                 if ((i2 == 0) && (ilayer > 0))
 
  274                   unsigned ielem_neigh = ielem - 3;
 
  277                   unsigned i0_neigh = i0;
 
  278                   unsigned i1_neigh = i1;
 
  279                   unsigned i2_neigh = n_p - 1;
 
  280                   unsigned jnod_local_neigh =
 
  281                     i0_neigh + i1_neigh * n_p + i2_neigh * n_p * n_p;
 
  285                   for (
unsigned i = 0; i < 3; i++)
 
  287                     double error = std::fabs(
 
  288                       finite_element_pt(ielem)->node_pt(jnod_local)->x(i) -
 
  289                       finite_element_pt(ielem_neigh)
 
  290                         ->node_pt(jnod_local_neigh)
 
  292                     if (error > node_kill_tol)
 
  294                       oomph_info << 
"Error in node killing for i " << i << 
" " 
  295                                  << error << std::endl;
 
  301                   delete finite_element_pt(ielem)->node_pt(jnod_local);
 
  305                   finite_element_pt(ielem)->node_pt(jnod_local) =
 
  306                     finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
 
  315                     unsigned ielem_neigh = ielem - 1;
 
  318                     unsigned i0_neigh = n_p - 1;
 
  319                     unsigned i1_neigh = i1;
 
  320                     unsigned i2_neigh = i2;
 
  321                     unsigned jnod_local_neigh =
 
  322                       i0_neigh + i1_neigh * n_p + i2_neigh * n_p * n_p;
 
  326                     for (
unsigned i = 0; i < 3; i++)
 
  328                       double error = std::fabs(
 
  329                         finite_element_pt(ielem)->node_pt(jnod_local)->x(i) -
 
  330                         finite_element_pt(ielem_neigh)
 
  331                           ->node_pt(jnod_local_neigh)
 
  333                       if (error > node_kill_tol)
 
  335                         oomph_info << 
"Error in node killing for i " << i << 
" " 
  336                                    << error << std::endl;
 
  342                     delete finite_element_pt(ielem)->node_pt(jnod_local);
 
  346                     finite_element_pt(ielem)->node_pt(jnod_local) =
 
  347                       finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
 
  354                   Node_pt[node_count] =
 
  355                     finite_element_pt(ielem)->node_pt(jnod_local);
 
  360                   if ((i2 == 0) && (ilayer == 0))
 
  362                     this->convert_to_boundary_node(Node_pt[node_count]);
 
  363                     add_boundary_node(0, Node_pt[node_count]);
 
  367                   if ((i2 == n_p - 1) && (ilayer == nlayer - 1))
 
  369                     this->convert_to_boundary_node(Node_pt[node_count]);
 
  370                     add_boundary_node(4, Node_pt[node_count]);
 
  376                     this->convert_to_boundary_node(Node_pt[node_count]);
 
  377                     add_boundary_node(2, Node_pt[node_count]);
 
  383                     this->convert_to_boundary_node(Node_pt[node_count]);
 
  384                     add_boundary_node(3, Node_pt[node_count]);
 
  389                               (double(ilayer) + double(i2) / double(n_p - 1)) *
 
  393                     zeta[1] = 
Xi_lo[1] + double(i1) / double(n_p - 1) * 0.5 *
 
  396                     Node_pt[node_count]->set_coordinates_on_boundary(3, zeta);
 
  414           for (
unsigned i2 = 0; i2 < n_p; i2++)
 
  417             for (
unsigned i1 = 0; i1 < n_p; i1++)
 
  420               for (
unsigned i0 = 0; i0 < n_p; i0++)
 
  423                 unsigned jnod_local = i0 + i1 * n_p + i2 * n_p * n_p;
 
  430                 if ((i2 == 0) && (ilayer > 0))
 
  433                   unsigned ielem_neigh = ielem - 3;
 
  436                   unsigned i0_neigh = i0;
 
  437                   unsigned i1_neigh = i1;
 
  438                   unsigned i2_neigh = n_p - 1;
 
  439                   unsigned jnod_local_neigh =
 
  440                     i0_neigh + i1_neigh * n_p + i2_neigh * n_p * n_p;
 
  443                   for (
unsigned i = 0; i < 3; i++)
 
  445                     double error = std::fabs(
 
  446                       finite_element_pt(ielem)->node_pt(jnod_local)->x(i) -
 
  447                       finite_element_pt(ielem_neigh)
 
  448                         ->node_pt(jnod_local_neigh)
 
  450                     if (error > node_kill_tol)
 
  452                       oomph_info << 
"Error in node killing for i " << i << 
" " 
  453                                  << error << std::endl;
 
  459                   delete finite_element_pt(ielem)->node_pt(jnod_local);
 
  463                   finite_element_pt(ielem)->node_pt(jnod_local) =
 
  464                     finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
 
  474                     unsigned ielem_neigh = ielem - 1;
 
  477                     unsigned i0_neigh = i1;
 
  478                     unsigned i1_neigh = n_p - 1;
 
  479                     unsigned i2_neigh = i2;
 
  480                     unsigned jnod_local_neigh =
 
  481                       i0_neigh + i1_neigh * n_p + i2_neigh * n_p * n_p;
 
  484                     for (
unsigned i = 0; i < 3; i++)
 
  486                       double error = std::fabs(
 
  487                         finite_element_pt(ielem)->node_pt(jnod_local)->x(i) -
 
  488                         finite_element_pt(ielem_neigh)
 
  489                           ->node_pt(jnod_local_neigh)
 
  491                       if (error > node_kill_tol)
 
  493                         oomph_info << 
"Error in node killing for i " << i << 
" " 
  494                                    << error << std::endl;
 
  500                     delete finite_element_pt(ielem)->node_pt(jnod_local);
 
  504                     finite_element_pt(ielem)->node_pt(jnod_local) =
 
  505                       finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
 
  510                   if ((i1 == 0) && (i0 != n_p - 1))
 
  513                     unsigned ielem_neigh = ielem - 2;
 
  516                     unsigned i0_neigh = i0;
 
  517                     unsigned i1_neigh = n_p - 1;
 
  518                     unsigned i2_neigh = i2;
 
  519                     unsigned jnod_local_neigh =
 
  520                       i0_neigh + i1_neigh * n_p + i2_neigh * n_p * n_p;
 
  523                     for (
unsigned i = 0; i < 3; i++)
 
  525                       double error = std::fabs(
 
  526                         finite_element_pt(ielem)->node_pt(jnod_local)->x(i) -
 
  527                         finite_element_pt(ielem_neigh)
 
  528                           ->node_pt(jnod_local_neigh)
 
  530                       if (error > node_kill_tol)
 
  532                         oomph_info << 
"Error in node killing for i " << i << 
" " 
  533                                    << error << std::endl;
 
  539                     delete finite_element_pt(ielem)->node_pt(jnod_local);
 
  543                     finite_element_pt(ielem)->node_pt(jnod_local) =
 
  544                       finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
 
  550                     Node_pt[node_count] =
 
  551                       finite_element_pt(ielem)->node_pt(jnod_local);
 
  556                     if ((i2 == 0) && (ilayer == 0))
 
  558                       this->convert_to_boundary_node(Node_pt[node_count]);
 
  559                       add_boundary_node(0, Node_pt[node_count]);
 
  563                     if ((i2 == n_p - 1) && (ilayer == nlayer - 1))
 
  565                       this->convert_to_boundary_node(Node_pt[node_count]);
 
  566                       add_boundary_node(4, Node_pt[node_count]);
 
  572                       this->convert_to_boundary_node(Node_pt[node_count]);
 
  573                       add_boundary_node(1, Node_pt[node_count]);
 
  580                       this->convert_to_boundary_node(Node_pt[node_count]);
 
  581                       add_boundary_node(3, Node_pt[node_count]);
 
  587                         (double(ilayer) + double(i2) / double(n_p - 1)) *
 
  591                       zeta[1] = 
Xi_hi[1] - double(i0) / double(n_p - 1) * 0.5 *
 
  594                       Node_pt[node_count]->set_coordinates_on_boundary(3, zeta);
 
  612       std::ostringstream error_stream;
 
  613       error_stream << 
"Error in killing nodes\n" 
  614                    << 
"The most probable cause is that the domain is not\n" 
  615                    << 
"compatible with the mesh.\n" 
  616                    << 
"For the QuarterTubeMesh, the domain must be\n" 
  617                    << 
"topologically consistent with a quarter tube with a\n" 
  618                    << 
"non-curved centreline.\n";
 
  620         error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
 
  624     setup_boundary_element_info();
 
  658   template<
class ELEMENT>
 
  660     ELEMENT>::setup_algebraic_node_update()
 
  664     AlgebraicElementBase* algebraic_element_pt =
 
  665       dynamic_cast<AlgebraicElementBase*
>(Mesh::element_pt(0));
 
  667     if (algebraic_element_pt == 0)
 
  669       std::ostringstream error_message;
 
  671         << 
"Element in AlgebraicRefineableQuarterTubeMesh must be\n ";
 
  672       error_message << 
"derived from AlgebraicElementBase\n";
 
  673       error_message << 
"but it is of type:  " 
  674                     << 
typeid(Mesh::element_pt(0)).name() << std::endl;
 
  675       std::string function_name = 
"AlgebraicRefineableQuarterTubeMesh::";
 
  676       function_name += 
"setup_algebraic_node_update()";
 
  678         error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
 
  683     unsigned nnodes_3d = Mesh::finite_element_pt(0)->nnode();
 
  686     unsigned nnodes_1d = Mesh::finite_element_pt(0)->nnode_1d();
 
  687     unsigned nnodes_2d = nnodes_1d * nnodes_1d;
 
  691     unsigned tl_node = nnodes_2d - nnodes_1d;
 
  692     unsigned br_node = nnodes_1d - 1;
 
  696     double x_c_element = Mesh::finite_element_pt(1)->node_pt(tl_node)->x(0);
 
  697     double y_c_element = Mesh::finite_element_pt(1)->node_pt(tl_node)->x(1);
 
  701     double x_wall = Mesh::finite_element_pt(1)->node_pt(br_node)->x(0);
 
  705     double y_wall = Mesh::finite_element_pt(2)->node_pt(tl_node)->x(1);
 
  708     Lambda_x = Centre_box_size * x_c_element / x_wall;
 
  709     Lambda_y = Centre_box_size * y_c_element / y_wall;
 
  712     unsigned nelements = Mesh::nelement();
 
  715     for (
unsigned e = 0; e < nelements; e++)
 
  718       FiniteElement* el_pt = Mesh::finite_element_pt(e);
 
  721       unsigned region_id = e % 3;
 
  725       unsigned nstart = nnodes_2d;
 
  732       for (
unsigned n = nstart; n < nnodes_3d; n++)
 
  740         double z = el_pt->node_pt(n)->x(2);
 
  744         Vector<double> xi(2);
 
  747         GeomObject* obj_br_pt;
 
  748         Vector<double> s_br(2);
 
  749         this->Wall_pt->locate_zeta(xi, obj_br_pt, s_br);
 
  754         GeomObject* obj_tl_pt;
 
  755         Vector<double> s_tl(2);
 
  756         this->Wall_pt->locate_zeta(xi, obj_tl_pt, s_tl);
 
  763           double x = el_pt->node_pt(n)->x(0);
 
  764           double y = el_pt->node_pt(n)->x(1);
 
  767           Vector<GeomObject*> geom_object_pt(2);
 
  770           geom_object_pt[0] = obj_br_pt;
 
  773           geom_object_pt[1] = obj_tl_pt;
 
  776           Vector<double> ref_value(7);
 
  779           ref_value[0] = x / x_c_element;
 
  782           ref_value[1] = y / y_c_element;
 
  793           ref_value[3] = s_br[0];
 
  794           ref_value[4] = s_br[1];
 
  798           ref_value[5] = s_tl[0];
 
  799           ref_value[6] = s_tl[1];
 
  802           static_cast<AlgebraicNode*
>(el_pt->node_pt(n))
 
  803             ->add_node_update_info(Central_region, 
 
  811         else if (region_id == 1)
 
  814           double fract = 1.0 / double(nnodes_1d - 1);
 
  817           double rho_0 = fract * double(n % nnodes_1d);
 
  820           double rho_1 = fract * double((n / nnodes_1d) % nnodes_1d);
 
  830           GeomObject* obj_wall_pt;
 
  831           Vector<double> s_wall(2);
 
  832           this->Wall_pt->locate_zeta(xi, obj_wall_pt, s_wall);
 
  835           Vector<GeomObject*> geom_object_pt(3);
 
  838           geom_object_pt[0] = obj_br_pt;
 
  841           geom_object_pt[1] = obj_tl_pt;
 
  844           geom_object_pt[2] = obj_wall_pt;
 
  847           Vector<double> ref_value(9);
 
  850           ref_value[0] = rho_0;
 
  853           ref_value[1] = rho_1;
 
  860           ref_value[3] = s_br[0];
 
  861           ref_value[4] = s_br[1];
 
  865           ref_value[5] = s_tl[0];
 
  866           ref_value[6] = s_tl[1];
 
  870           ref_value[7] = s_wall[0];
 
  871           ref_value[8] = s_wall[1];
 
  874           static_cast<AlgebraicNode*
>(el_pt->node_pt(n))
 
  875             ->add_node_update_info(Lower_right_region, 
 
  883         else if (region_id == 2)
 
  886           double fract = 1.0 / double(nnodes_1d - 1);
 
  889           double rho_0 = fract * double(n % nnodes_1d);
 
  892           double rho_1 = fract * double((n / nnodes_1d) % nnodes_1d);
 
  902           GeomObject* obj_wall_pt;
 
  903           Vector<double> s_wall(2);
 
  904           this->Wall_pt->locate_zeta(xi, obj_wall_pt, s_wall);
 
  907           Vector<GeomObject*> geom_object_pt(3);
 
  910           geom_object_pt[0] = obj_br_pt;
 
  913           geom_object_pt[1] = obj_tl_pt;
 
  916           geom_object_pt[2] = obj_wall_pt;
 
  919           Vector<double> ref_value(9);
 
  922           ref_value[0] = rho_0;
 
  925           ref_value[1] = rho_1;
 
  932           ref_value[3] = s_br[0];
 
  933           ref_value[4] = s_br[1];
 
  937           ref_value[5] = s_tl[0];
 
  938           ref_value[6] = s_tl[1];
 
  942           ref_value[7] = s_wall[0];
 
  943           ref_value[8] = s_wall[1];
 
  946           static_cast<AlgebraicNode*
>(el_pt->node_pt(n))
 
  947             ->add_node_update_info(Upper_left_region, 
 
  960   template<
class ELEMENT>
 
  962     const unsigned& t, AlgebraicNode*& node_pt)
 
  978     if (t > node_pt->position_time_stepper_pt()->nprev_values())
 
  980       std::string error_message =
 
  981         "Trying to update the nodal position at a time level\n";
 
  982       error_message += 
"beyond the number of previous values in the nodes'\n";
 
  983       error_message += 
"position timestepper. This seems highly suspect!\n";
 
  984       error_message += 
"If you're sure the code behaves correctly\n";
 
  985       error_message += 
"in your application, remove this warning \n";
 
  986       error_message += 
"or recompile with PARNOID switched off.\n";
 
  988       std::string function_name = 
"AlgebraicRefineableQuarterTubeMesh::";
 
  989       function_name += 
"node_update_central_region()",
 
  991           error_message, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
 
  996     Vector<double> ref_value(node_pt->vector_ref_value(Central_region));
 
 1000     Vector<GeomObject*> geom_object_pt(
 
 1001       node_pt->vector_geom_object_pt(Central_region));
 
 1004     double rho_x = ref_value[0];
 
 1007     double rho_y = ref_value[1];
 
 1012     GeomObject* obj_br_pt = geom_object_pt[0];
 
 1015     Vector<double> s_br(2);
 
 1016     s_br[0] = ref_value[3];
 
 1017     s_br[1] = ref_value[4];
 
 1020     unsigned n_dim = obj_br_pt->ndim();
 
 1021     Vector<double> r_br(n_dim);
 
 1022     obj_br_pt->position(t, s_br, r_br);
 
 1027     GeomObject* obj_tl_pt = geom_object_pt[1];
 
 1030     Vector<double> s_tl(2);
 
 1031     s_tl[0] = ref_value[5];
 
 1032     s_tl[1] = ref_value[6];
 
 1035     Vector<double> r_tl(n_dim);
 
 1036     obj_tl_pt->position(t, s_tl, r_tl);
 
 1039     node_pt->x(t, 0) = r_br[0] * Lambda_x * rho_x;
 
 1040     node_pt->x(t, 1) = r_tl[1] * Lambda_y * rho_y;
 
 1041     node_pt->x(t, 2) = (r_br[2] + r_tl[2]) * 0.5;
 
 1049   template<
class ELEMENT>
 
 1051     ELEMENT>::node_update_lower_right_region(
const unsigned& t,
 
 1052                                              AlgebraicNode*& node_pt)
 
 1068     if (t > node_pt->position_time_stepper_pt()->nprev_values())
 
 1070       std::string error_message =
 
 1071         "Trying to update the nodal position at a time level";
 
 1072       error_message += 
"beyond the number of previous values in the nodes'";
 
 1073       error_message += 
"position timestepper. This seems highly suspect!";
 
 1074       error_message += 
"If you're sure the code behaves correctly";
 
 1075       error_message += 
"in your application, remove this warning ";
 
 1076       error_message += 
"or recompile with PARNOID switched off.";
 
 1078       std::string function_name = 
"AlgebraicRefineableQuarterTubeSectorMesh::";
 
 1079       function_name += 
"node_update_lower_right_region()",
 
 1080         throw OomphLibError(
 
 1081           error_message, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
 
 1086     Vector<double> ref_value(node_pt->vector_ref_value(Lower_right_region));
 
 1090     Vector<GeomObject*> geom_object_pt(
 
 1091       node_pt->vector_geom_object_pt(Lower_right_region));
 
 1094     double rho_0 = ref_value[0];
 
 1097     rho_0 = this->Domain_pt->s_squashed(rho_0);
 
 1100     double rho_1 = ref_value[1];
 
 1105     GeomObject* obj_br_pt = geom_object_pt[0];
 
 1108     Vector<double> s_br(2);
 
 1109     s_br[0] = ref_value[3];
 
 1110     s_br[1] = ref_value[4];
 
 1113     unsigned n_dim = obj_br_pt->ndim();
 
 1116     Vector<double> r_br(n_dim);
 
 1117     obj_br_pt->position(t, s_br, r_br);
 
 1122     GeomObject* obj_tl_pt = geom_object_pt[1];
 
 1125     Vector<double> s_tl(2);
 
 1126     s_tl[0] = ref_value[5];
 
 1127     s_tl[1] = ref_value[6];
 
 1129     Vector<double> r_tl(n_dim);
 
 1130     obj_tl_pt->position(t, s_tl, r_tl);
 
 1135     GeomObject* obj_wall_pt = geom_object_pt[2];
 
 1138     Vector<double> s_wall(2);
 
 1139     s_wall[0] = ref_value[7];
 
 1140     s_wall[1] = ref_value[8];
 
 1142     Vector<double> r_wall(n_dim);
 
 1143     obj_wall_pt->position(t, s_wall, r_wall);
 
 1146     Vector<double> r_corner(n_dim);
 
 1147     r_corner[0] = Lambda_x * r_br[0];
 
 1148     r_corner[1] = Lambda_y * r_tl[1];
 
 1149     r_corner[2] = (r_br[2] + r_tl[2]) * 0.5;
 
 1152     Vector<double> r_left(n_dim);
 
 1153     r_left[0] = r_corner[0];
 
 1154     r_left[1] = rho_1 * r_corner[1];
 
 1155     r_left[2] = r_corner[2];
 
 1158     node_pt->x(t, 0) = r_left[0] + rho_0 * (r_wall[0] - r_left[0]);
 
 1159     node_pt->x(t, 1) = r_left[1] + rho_0 * (r_wall[1] - r_left[1]);
 
 1160     node_pt->x(t, 2) = r_left[2] + rho_0 * (r_wall[2] - r_left[2]);
 
 1166   template<
class ELEMENT>
 
 1168     ELEMENT>::node_update_upper_left_region(
const unsigned& t,
 
 1169                                             AlgebraicNode*& node_pt)
 
 1185     if (t > node_pt->position_time_stepper_pt()->nprev_values())
 
 1187       std::string error_message =
 
 1188         "Trying to update the nodal position at a time level";
 
 1189       error_message += 
"beyond the number of previous values in the nodes'";
 
 1190       error_message += 
"position timestepper. This seems highly suspect!";
 
 1191       error_message += 
"If you're sure the code behaves correctly";
 
 1192       error_message += 
"in your application, remove this warning ";
 
 1193       error_message += 
"or recompile with PARNOID switched off.";
 
 1195       std::string function_name = 
"AlgebraicRefineableQuarterTubeMesh::";
 
 1196       function_name += 
"node_update_upper_left_region()";
 
 1198       throw OomphLibError(
 
 1199         error_message, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
 
 1204     Vector<double> ref_value(node_pt->vector_ref_value(Upper_left_region));
 
 1208     Vector<GeomObject*> geom_object_pt(
 
 1209       node_pt->vector_geom_object_pt(Upper_left_region));
 
 1212     double rho_0 = ref_value[0];
 
 1215     double rho_1 = ref_value[1];
 
 1218     rho_1 = this->Domain_pt->s_squashed(rho_1);
 
 1223     GeomObject* obj_br_pt = geom_object_pt[0];
 
 1226     unsigned n_dim = obj_br_pt->ndim();
 
 1229     Vector<double> s_br(2);
 
 1230     s_br[0] = ref_value[3];
 
 1231     s_br[1] = ref_value[4];
 
 1234     Vector<double> r_br(n_dim);
 
 1235     obj_br_pt->position(t, s_br, r_br);
 
 1240     GeomObject* obj_tl_pt = node_pt->geom_object_pt(1);
 
 1243     Vector<double> s_tl(2);
 
 1244     s_tl[0] = ref_value[5];
 
 1245     s_tl[1] = ref_value[6];
 
 1247     Vector<double> r_tl(n_dim);
 
 1248     obj_tl_pt->position(t, s_tl, r_tl);
 
 1253     GeomObject* obj_wall_pt = node_pt->geom_object_pt(2);
 
 1256     Vector<double> s_wall(2);
 
 1257     s_wall[0] = ref_value[7];
 
 1258     s_wall[1] = ref_value[8];
 
 1260     Vector<double> r_wall(n_dim);
 
 1261     obj_wall_pt->position(t, s_wall, r_wall);
 
 1264     Vector<double> r_corner(n_dim);
 
 1265     r_corner[0] = Lambda_x * r_br[0];
 
 1266     r_corner[1] = Lambda_y * r_tl[1];
 
 1267     r_corner[2] = (r_br[2] + r_tl[2]) * 0.5;
 
 1270     Vector<double> r_top(n_dim);
 
 1271     r_top[0] = rho_0 * r_corner[0];
 
 1272     r_top[1] = r_corner[1];
 
 1273     r_top[2] = r_corner[2];
 
 1276     node_pt->x(t, 0) = r_top[0] + rho_1 * (r_wall[0] - r_top[0]);
 
 1277     node_pt->x(t, 1) = r_top[1] + rho_1 * (r_wall[1] - r_top[1]);
 
 1278     node_pt->x(t, 2) = r_top[2] + rho_1 * (r_wall[2] - r_top[2]);
 
 1286   template<
class ELEMENT>
 
 1288     ELEMENT>::update_node_update_in_region(AlgebraicNode*& node_pt,
 
 1292     Vector<double> ref_value(node_pt->vector_ref_value(region_id));
 
 1295     Vector<GeomObject*> geom_object_pt(
 
 1296       node_pt->vector_geom_object_pt(region_id));
 
 1299     node_pt->kill_node_update_info(region_id);
 
 1313     double z = ref_value[2];
 
 1319     Vector<double> xi(2);
 
 1324     GeomObject* obj_br_pt;
 
 1325     Vector<double> s_br(2);
 
 1326     this->Wall_pt->locate_zeta(xi, obj_br_pt, s_br);
 
 1329     geom_object_pt[0] = obj_br_pt;
 
 1332     ref_value[3] = s_br[0];
 
 1333     ref_value[4] = s_br[1];
 
 1343     GeomObject* obj_tl_pt;
 
 1344     Vector<double> s_tl(2);
 
 1345     this->Wall_pt->locate_zeta(xi, obj_tl_pt, s_tl);
 
 1348     geom_object_pt[1] = obj_tl_pt;
 
 1351     ref_value[5] = s_tl[0];
 
 1352     ref_value[6] = s_tl[1];
 
 1354     if (region_id != Central_region)
 
 1360       if (region_id == Lower_right_region)
 
 1363         double rho_1 = ref_value[1];
 
 1366         xi[1] = xi_lo + rho_1 * fract_mid * (xi_hi - xi_lo);
 
 1371         double rho_0 = ref_value[0];
 
 1374         xi[1] = xi_hi - rho_0 * (1.0 - fract_mid) * (xi_hi - xi_lo);
 
 1379       GeomObject* obj_wall_pt;
 
 1380       Vector<double> s_wall(2);
 
 1381       this->Wall_pt->locate_zeta(xi, obj_wall_pt, s_wall);
 
 1384       geom_object_pt[2] = obj_wall_pt;
 
 1387       ref_value[7] = s_wall[0];
 
 1388       ref_value[8] = s_wall[1];
 
 1392     node_pt->add_node_update_info(region_id, 
 
AlgebraicMesh version of RefineableQuarterTubeMesh.
 
void node_update_central_region(const unsigned &t, AlgebraicNode *&node_pt)
Algebraic update function for a node that is located in the central region.
 
Quarter tube as domain. Domain is bounded by curved boundary which is represented by a GeomObject....
 
3D quarter tube mesh class. The domain is specified by the GeomObject that identifies boundary 3....
 
QuarterTubeDomain * Domain_pt
Pointer to domain.
 
Vector< double > Xi_lo
Lower limits for the coordinates along the wall.
 
QuarterTubeMesh(GeomObject *wall_pt, const Vector< double > &xi_lo, const double &fract_mid, const Vector< double > &xi_hi, const unsigned &nlayer, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass pointer to geometric object that specifies the wall, start and end coordinates on t...
 
Vector< double > Xi_hi
Upper limits for the coordinates along the wall.
 
GeomObject *& wall_pt()
Access function to GeomObject representing wall.
 
////////////////////////////////////////////////////////////////////// //////////////////////////////...