oomph::BrickFromTetMesh< ELEMENT > Class Template Reference

#include <brick_from_tet_mesh.template.h>

+ Inheritance diagram for oomph::BrickFromTetMesh< ELEMENT >:

Public Member Functions

 BrickFromTetMesh (const std::string xda_file_name, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
 Constructor: Pass xda file name. More...
 
 BrickFromTetMesh (const std::string &node_file_name, const std::string &element_file_name, const std::string &face_file_name, const bool &split_corner_elements, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper, const bool &use_attributes=false)
 Constructor: Pass the files required for the tetgen mesh. More...
 
 BrickFromTetMesh (const std::string xda_file_name, XdaTetMesh< TElement< 3, 3 >> *&xda_tet_mesh_pt, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
 
Vector< unsignedoomph_lib_boundary_ids (const unsigned &xda_boundary_id)
 
- Public Member Functions inherited from oomph::BrickMeshBase
 BrickMeshBase ()
 Constructor (empty) More...
 
 BrickMeshBase (const BrickMeshBase &)=delete
 Broken copy constructor. More...
 
virtual ~BrickMeshBase ()
 Broken assignment operator. More...
 
void setup_boundary_element_info ()
 
void setup_boundary_element_info (std::ostream &outfile)
 
- Public Member Functions inherited from oomph::Mesh
 Mesh ()
 Default constructor. More...
 
 Mesh (const Vector< Mesh * > &sub_mesh_pt)
 
void merge_meshes (const Vector< Mesh * > &sub_mesh_pt)
 
virtual void reset_boundary_element_info (Vector< unsigned > &ntmp_boundary_elements, Vector< Vector< unsigned >> &ntmp_boundary_elements_in_region, Vector< FiniteElement * > &deleted_elements)
 Virtual function to perform the reset boundary elements info rutines. More...
 
template<class BULK_ELEMENT >
void doc_boundary_coordinates (const unsigned &b, std::ofstream &the_file)
 
virtual void scale_mesh (const double &factor)
 
 Mesh (const Mesh &dummy)=delete
 Broken copy constructor. More...
 
void operator= (const Mesh &)=delete
 Broken assignment operator. More...
 
virtual ~Mesh ()
 Virtual Destructor to clean up all memory. More...
 
void flush_element_and_node_storage ()
 
void flush_element_storage ()
 
void flush_node_storage ()
 
Node *& node_pt (const unsigned long &n)
 Return pointer to global node n. More...
 
Nodenode_pt (const unsigned long &n) const
 Return pointer to global node n (const version) More...
 
GeneralisedElement *& element_pt (const unsigned long &e)
 Return pointer to element e. More...
 
GeneralisedElementelement_pt (const unsigned long &e) const
 Return pointer to element e (const version) More...
 
const Vector< GeneralisedElement * > & element_pt () const
 Return reference to the Vector of elements. More...
 
Vector< GeneralisedElement * > & element_pt ()
 Return reference to the Vector of elements. More...
 
FiniteElementfinite_element_pt (const unsigned &e) const
 
Node *& boundary_node_pt (const unsigned &b, const unsigned &n)
 Return pointer to node n on boundary b. More...
 
Nodeboundary_node_pt (const unsigned &b, const unsigned &n) const
 Return pointer to node n on boundary b. More...
 
void set_nboundary (const unsigned &nbound)
 Set the number of boundaries in the mesh. More...
 
void remove_boundary_nodes ()
 Clear all pointers to boundary nodes. More...
 
void remove_boundary_nodes (const unsigned &b)
 
void remove_boundary_node (const unsigned &b, Node *const &node_pt)
 Remove a node from the boundary b. More...
 
void add_boundary_node (const unsigned &b, Node *const &node_pt)
 Add a (pointer to) a node to the b-th boundary. More...
 
void copy_boundary_node_data_from_nodes ()
 
bool boundary_coordinate_exists (const unsigned &i) const
 Indicate whether the i-th boundary has an intrinsic coordinate. More...
 
unsigned long nelement () const
 Return number of elements in the mesh. More...
 
unsigned long nnode () const
 Return number of nodes in the mesh. More...
 
unsigned ndof_types () const
 Return number of dof types in mesh. More...
 
unsigned elemental_dimension () const
 Return number of elemental dimension in mesh. More...
 
unsigned nodal_dimension () const
 Return number of nodal dimension in mesh. More...
 
void add_node_pt (Node *const &node_pt)
 Add a (pointer to a) node to the mesh. More...
 
void add_element_pt (GeneralisedElement *const &element_pt)
 Add a (pointer to) an element to the mesh. More...
 
virtual void node_update (const bool &update_all_solid_nodes=false)
 
virtual void reorder_nodes (const bool &use_old_ordering=true)
 
virtual void get_node_reordering (Vector< Node * > &reordering, const bool &use_old_ordering=true) const
 
template<class BULK_ELEMENT , template< class > class FACE_ELEMENT>
void build_face_mesh (const unsigned &b, Mesh *const &face_mesh_pt)
 
unsigned self_test ()
 Self-test: Check elements and nodes. Return 0 for OK. More...
 
void max_and_min_element_size (double &max_size, double &min_size)
 
double total_size ()
 
void check_inverted_elements (bool &mesh_has_inverted_elements, std::ofstream &inverted_element_file)
 
void check_inverted_elements (bool &mesh_has_inverted_elements)
 
unsigned check_for_repeated_nodes (const double &epsilon=1.0e-12)
 
Vector< Node * > prune_dead_nodes ()
 
unsigned nboundary () const
 Return number of boundaries. More...
 
unsigned long nboundary_node (const unsigned &ibound) const
 Return number of nodes on a particular boundary. More...
 
FiniteElementboundary_element_pt (const unsigned &b, const unsigned &e) const
 Return pointer to e-th finite element on boundary b. More...
 
Nodeget_some_non_boundary_node () const
 
unsigned nboundary_element (const unsigned &b) const
 Return number of finite elements that are adjacent to boundary b. More...
 
int face_index_at_boundary (const unsigned &b, const unsigned &e) const
 
virtual void dump (std::ofstream &dump_file, const bool &use_old_ordering=true) const
 Dump the data in the mesh into a file for restart. More...
 
void dump (const std::string &dump_file_name, const bool &use_old_ordering=true) const
 Dump the data in the mesh into a file for restart. More...
 
virtual void read (std::ifstream &restart_file)
 Read solution from restart file. More...
 
void output_paraview (std::ofstream &file_out, const unsigned &nplot) const
 
void output_fct_paraview (std::ofstream &file_out, const unsigned &nplot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt) const
 
void output_fct_paraview (std::ofstream &file_out, const unsigned &nplot, const double &time, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt) const
 
void output (std::ostream &outfile)
 Output for all elements. More...
 
void output (std::ostream &outfile, const unsigned &n_plot)
 Output at f(n_plot) points in each element. More...
 
void output (FILE *file_pt)
 Output for all elements (C-style output) More...
 
void output (FILE *file_pt, const unsigned &nplot)
 Output at f(n_plot) points in each element (C-style output) More...
 
void output (const std::string &output_filename)
 Output for all elements. More...
 
void output (const std::string &output_filename, const unsigned &n_plot)
 Output at f(n_plot) points in each element. More...
 
void output_fct (std::ostream &outfile, const unsigned &n_plot, FiniteElement::SteadyExactSolutionFctPt)
 Output a given Vector function at f(n_plot) points in each element. More...
 
void output_fct (std::ostream &outfile, const unsigned &n_plot, const double &time, FiniteElement::UnsteadyExactSolutionFctPt)
 
void output_boundaries (std::ostream &outfile)
 Output the nodes on the boundaries (into separate tecplot zones) More...
 
void output_boundaries (const std::string &output_filename)
 
void assign_initial_values_impulsive ()
 Assign initial values for an impulsive start. More...
 
void shift_time_values ()
 
void calculate_predictions ()
 
void set_nodal_and_elemental_time_stepper (TimeStepper *const &time_stepper_pt, const bool &preserve_existing_data)
 
virtual void set_mesh_level_time_stepper (TimeStepper *const &time_stepper_pt, const bool &preserve_existing_data)
 
void set_consistent_pinned_values_for_continuation (ContinuationStorageScheme *const &continuation_stepper_pt)
 Set consistent values for pinned data in continuation. More...
 
bool does_pointer_correspond_to_mesh_data (double *const &parameter_pt)
 Does the double pointer correspond to any mesh data. More...
 
void set_nodal_time_stepper (TimeStepper *const &time_stepper_pt, const bool &preserve_existing_data)
 Set the timestepper associated with the nodal data in the mesh. More...
 
void set_elemental_internal_time_stepper (TimeStepper *const &time_stepper_pt, const bool &preserve_existing_data)
 
virtual void compute_norm (double &norm)
 
virtual void compute_norm (Vector< double > &norm)
 
virtual void compute_error (std::ostream &outfile, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt, const double &time, double &error, double &norm)
 
virtual void compute_error (std::ostream &outfile, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, double &error, double &norm)
 
virtual void compute_error (FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, double &error, double &norm)
 
virtual void compute_error (FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, Vector< double > &error, Vector< double > &norm)
 
virtual void compute_error (std::ostream &outfile, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt, const double &time, Vector< double > &error, Vector< double > &norm)
 
virtual void compute_error (std::ostream &outfile, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, Vector< double > &error, Vector< double > &norm)
 
virtual void compute_error (FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt, const double &time, double &error, double &norm)
 Returns the norm of the error and that of the exact solution. More...
 
virtual void compute_error (FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt, const double &time, Vector< double > &error, Vector< double > &norm)
 
bool is_mesh_distributed () const
 Boolean to indicate if Mesh has been distributed. More...
 
OomphCommunicatorcommunicator_pt () const
 
void delete_all_external_storage ()
 Wipe the storage for all externally-based elements. More...
 

Private Member Functions

void build_mesh (XdaTetMesh< TElement< 3, 3 >> *tet_mesh_pt, TimeStepper *time_stepper_pt)
 Build fct: Pass pointer to existing tet mesh. More...
 
void build_mesh (TetgenMesh< TElement< 3, 3 >> *tet_mesh_pt, TimeStepper *time_stepper_pt)
 Build fct: Pass pointer to existing tet mesh. More...
 

Private Attributes

Vector< Vector< unsigned > > Boundary_id
 

Additional Inherited Members

- Public Types inherited from oomph::Mesh
typedef void(FiniteElement::* SteadyExactSolutionFctPt) (const Vector< double > &x, Vector< double > &soln)
 
typedef void(FiniteElement::* UnsteadyExactSolutionFctPt) (const double &time, const Vector< double > &x, Vector< double > &soln)
 
- Static Public Attributes inherited from oomph::Mesh
static Steady< 0 > Default_TimeStepper
 The Steady Timestepper. More...
 
static bool Suppress_warning_about_empty_mesh_level_time_stepper_function
 Static boolean flag to control warning about mesh level timesteppers. More...
 
- Protected Member Functions inherited from oomph::Mesh
unsigned long assign_global_eqn_numbers (Vector< double * > &Dof_pt)
 Assign (global) equation numbers to the nodes. More...
 
void describe_dofs (std::ostream &out, const std::string &current_string) const
 
void describe_local_dofs (std::ostream &out, const std::string &current_string) const
 
void assign_local_eqn_numbers (const bool &store_local_dof_pt)
 Assign local equation numbers in all elements. More...
 
void convert_to_boundary_node (Node *&node_pt, const Vector< FiniteElement * > &finite_element_pt)
 
void convert_to_boundary_node (Node *&node_pt)
 
- Protected Attributes inherited from oomph::Mesh
Vector< Vector< Node * > > Boundary_node_pt
 
bool Lookup_for_elements_next_boundary_is_setup
 
Vector< Vector< FiniteElement * > > Boundary_element_pt
 
Vector< Vector< int > > Face_index_at_boundary
 
Vector< Node * > Node_pt
 Vector of pointers to nodes. More...
 
Vector< GeneralisedElement * > Element_pt
 Vector of pointers to generalised elements. More...
 
std::vector< boolBoundary_coordinate_exists
 

Detailed Description

template<class ELEMENT>
class oomph::BrickFromTetMesh< ELEMENT >

Brick mesh built by brickifying an existing tet mesh – each tet gets split into four bricks. Can only be built with quadratic (27 node) elements.

Constructor & Destructor Documentation

◆ BrickFromTetMesh() [1/3]

template<class ELEMENT >
oomph::BrickFromTetMesh< ELEMENT >::BrickFromTetMesh ( const std::string  xda_file_name,
TimeStepper time_stepper_pt = &Mesh::Default_TimeStepper 
)
inline

Constructor: Pass xda file name.

66  {
67  // Mesh can only be built with 3D Qelements.
68  MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(3,
69  3);
70 
71  // Build temporary tet mesh
72  XdaTetMesh<TElement<3, 3>>* tmp_mesh_pt =
73  new XdaTetMesh<TElement<3, 3>>(xda_file_name, time_stepper_pt);
74 
75  // Actually build the mesh
76  build_mesh(tmp_mesh_pt, time_stepper_pt);
77 
78  // Now kill the temporary mesh
79  delete tmp_mesh_pt;
80  }
void build_mesh(XdaTetMesh< TElement< 3, 3 >> *tet_mesh_pt, TimeStepper *time_stepper_pt)
Build fct: Pass pointer to existing tet mesh.
Definition: brick_from_tet_mesh.template.cc:39

References oomph::BrickFromTetMesh< ELEMENT >::build_mesh().

◆ BrickFromTetMesh() [2/3]

template<class ELEMENT >
oomph::BrickFromTetMesh< ELEMENT >::BrickFromTetMesh ( const std::string &  node_file_name,
const std::string &  element_file_name,
const std::string &  face_file_name,
const bool split_corner_elements,
TimeStepper time_stepper_pt = &Mesh::Default_TimeStepper,
const bool use_attributes = false 
)
inline

Constructor: Pass the files required for the tetgen mesh.

89  {
90  // Mesh can only be built with 3D Qelements.
91  MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(3,
92  3);
93 
94  // Build temporary tet mesh
95  TetgenMesh<TElement<3, 3>>* tmp_mesh_pt =
96  new TetgenMesh<TElement<3, 3>>(node_file_name,
97  element_file_name,
98  face_file_name,
99  split_corner_elements,
100  time_stepper_pt,
101  use_attributes);
102 
103  // Actually build the mesh
104  build_mesh(tmp_mesh_pt, time_stepper_pt);
105 
106  // Now kill the temporary mesh
107  delete tmp_mesh_pt;
108  }

References oomph::BrickFromTetMesh< ELEMENT >::build_mesh().

◆ BrickFromTetMesh() [3/3]

template<class ELEMENT >
oomph::BrickFromTetMesh< ELEMENT >::BrickFromTetMesh ( const std::string  xda_file_name,
XdaTetMesh< TElement< 3, 3 >> *&  xda_tet_mesh_pt,
TimeStepper time_stepper_pt = &Mesh::Default_TimeStepper 
)
inline

Constructor: Pass xda file name. This returns a pointer to the internally built XdaTetMesh for external use. Note that YOU are responsible for deleting this mesh.

117  {
118  // Mesh can only be built with 3D Qelements.
119  MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(3,
120  3);
121 
122  // Build temporary tet mesh
123  xda_tet_mesh_pt =
124  new XdaTetMesh<TElement<3, 3>>(xda_file_name, time_stepper_pt);
125 
126  // Actually build the brick mesh
127  build_mesh(xda_tet_mesh_pt, time_stepper_pt);
128 
129  // Note that we're keeping the tet mesh alive for external use...
130  }

References oomph::BrickFromTetMesh< ELEMENT >::build_mesh().

Member Function Documentation

◆ build_mesh() [1/2]

template<class ELEMENT >
void oomph::BrickFromTetMesh< ELEMENT >::build_mesh ( TetgenMesh< TElement< 3, 3 >> *  tet_mesh_pt,
TimeStepper time_stepper_pt 
)
private

Build fct: Pass pointer to existing tet mesh.

Build fct: Pass pointer to existing tet mesh and timestepper Specialisation for TetgenMesh<TElement<3,3> >

4898  {
4899  // Mesh can only be built with 3D Qelements.
4900  MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(3, 3);
4901 
4902  // Figure out if the tet mesh is a solid mesh
4903  bool tet_mesh_is_solid_mesh = false;
4904  if (dynamic_cast<SolidFiniteElement*>(tet_mesh_pt->element_pt(0)) != 0)
4905  {
4906  tet_mesh_is_solid_mesh = true;
4907  }
4908 
4909  // Setup lookup scheme for local coordinates on triangular faces.
4910  // The local coordinates identify the points on the triangular
4911  // FaceElements on which we place the bottom layer of the
4912  // brick nodes.
4913  Vector<Vector<double>> s_face(19);
4914  for (unsigned i = 0; i < 19; i++)
4915  {
4916  s_face[i].resize(2);
4917 
4918  switch (i)
4919  {
4920  // Vertex nodes
4921 
4922  case 0:
4923  s_face[i][0] = 1.0;
4924  s_face[i][1] = 0.0;
4925  break;
4926 
4927  case 1:
4928  s_face[i][0] = 0.0;
4929  s_face[i][1] = 1.0;
4930  break;
4931 
4932  case 2:
4933  s_face[i][0] = 0.0;
4934  s_face[i][1] = 0.0;
4935  break;
4936 
4937  // Midside nodes
4938 
4939  case 3:
4940  s_face[i][0] = 0.5;
4941  s_face[i][1] = 0.5;
4942  break;
4943 
4944  case 4:
4945  s_face[i][0] = 0.0;
4946  s_face[i][1] = 0.5;
4947  break;
4948 
4949  case 5:
4950  s_face[i][0] = 0.5;
4951  s_face[i][1] = 0.0;
4952  break;
4953 
4954 
4955  // Quarter side nodes
4956 
4957  case 6:
4958  s_face[i][0] = 0.75;
4959  s_face[i][1] = 0.25;
4960  break;
4961 
4962  case 7:
4963  s_face[i][0] = 0.25;
4964  s_face[i][1] = 0.75;
4965  break;
4966 
4967  case 8:
4968  s_face[i][0] = 0.0;
4969  s_face[i][1] = 0.75;
4970  break;
4971 
4972  case 9:
4973  s_face[i][0] = 0.0;
4974  s_face[i][1] = 0.25;
4975  break;
4976 
4977  case 10:
4978  s_face[i][0] = 0.25;
4979  s_face[i][1] = 0.0;
4980  break;
4981 
4982  case 11:
4983  s_face[i][0] = 0.75;
4984  s_face[i][1] = 0.0;
4985  break;
4986 
4987  // Central node
4988 
4989  case 12:
4990  s_face[i][0] = 1.0 / 3.0;
4991  s_face[i][1] = 1.0 / 3.0;
4992  break;
4993 
4994 
4995  // Vertical internal midside nodes connecting 2 and 3
4996 
4997  case 13:
4998  s_face[i][0] = 5.0 / 24.0;
4999  s_face[i][1] = 5.0 / 24.0;
5000  break;
5001 
5002  case 14:
5003  s_face[i][0] = 5.0 / 12.0;
5004  s_face[i][1] = 5.0 / 12.0;
5005  break;
5006 
5007  // Internal midside nodes connecting nodes 0 and 4
5008 
5009  case 15:
5010  s_face[i][1] = 5.0 / 24.0;
5011  s_face[i][0] = 7.0 / 12.0; // 1.0-2.0*5.0/24.0;
5012  break;
5013 
5014  case 16:
5015  s_face[i][1] = 5.0 / 12.0;
5016  s_face[i][0] = 1.0 / 6.0; // 1.0-2.0*5.0/12.0;
5017  break;
5018 
5019 
5020  // Internal midside nodes connecting nodes 1 and 5
5021 
5022  case 17:
5023  s_face[i][0] = 5.0 / 24.0;
5024  s_face[i][1] = 7.0 / 12.0; // 1.0-2.0*5.0/24.0;
5025  break;
5026 
5027  case 18:
5028  s_face[i][0] = 5.0 / 12.0;
5029  s_face[i][1] = 1.0 / 6.0; // 1.0-2.0*5.0/12.0;
5030  break;
5031  }
5032  }
5033 
5034  // Set number of boundaries
5035  unsigned nb = tet_mesh_pt->nboundary();
5036  set_nboundary(nb);
5037 
5038  // Get ready for boundary lookup scheme
5039  Boundary_element_pt.resize(nb);
5040  Face_index_at_boundary.resize(nb);
5041 
5042  // Maps to check which nodes have already been done
5043 
5044  // Map that stores the new brick node corresponding to an existing tet node
5045  std::map<Node*, Node*> tet_node_node_pt;
5046 
5047  // Map that stores node on an edge between two brick nodes
5048  std::map<Edge, Node*> brick_edge_node_pt;
5049 
5050  // Map that stores node on face spanned by three tet nodes
5051  std::map<TFace, Node*> tet_face_node_pt;
5052 
5053  // Create the four Dummy bricks:
5054  //------------------------------
5055  Vector<DummyBrickElement*> dummy_q_el_pt(4);
5056  for (unsigned e = 0; e < 4; e++)
5057  {
5058  dummy_q_el_pt[e] = new DummyBrickElement;
5059  for (unsigned j = 0; j < 8; j++)
5060  {
5061  dummy_q_el_pt[e]->construct_node(j);
5062  }
5063  }
5064 
5065  // Loop over the elements in the tet mesh
5066  unsigned n_el_tet = tet_mesh_pt->nelement();
5067  for (unsigned e_tet = 0; e_tet < n_el_tet; e_tet++)
5068  {
5069  // Cast to ten-noded tet
5070  TElement<3, 3>* tet_el_pt =
5071  dynamic_cast<TElement<3, 3>*>(tet_mesh_pt->element_pt(e_tet));
5072 
5073 #ifdef PARANOID
5074  if (tet_el_pt == 0)
5075  {
5076  std::ostringstream error_stream;
5077  error_stream
5078  << "BrickFromTetMesh can only built from tet mesh containing\n"
5079  << "ten-noded tets.\n";
5080  throw OomphLibError(
5081  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
5082  }
5083 #endif
5084 
5085  // Storage for the centroid node for this tet
5086  Node* centroid_node_pt = 0;
5087 
5088  // Internal mid brick-face nodes
5089  Node* top_mid_face_node0_pt = 0;
5090  Node* right_mid_face_node0_pt = 0;
5091  Node* back_mid_face_node0_pt = 0;
5092 
5093  Node* top_mid_face_node1_pt = 0;
5094  Node* right_mid_face_node1_pt = 0;
5095 
5096  Node* top_mid_face_node2_pt = 0;
5097 
5098  // Newly created brick elements
5099  FiniteElement* brick_el0_pt = 0;
5100  FiniteElement* brick_el1_pt = 0;
5101  FiniteElement* brick_el2_pt = 0;
5102  FiniteElement* brick_el3_pt = 0;
5103 
5104 
5105  // First brick element is centred at node 0 of tet:
5106  //-------------------------------------------------
5107  {
5108  // Assign coordinates of dummy element
5109  for (unsigned j = 0; j < 8; j++)
5110  {
5111  Node* nod_pt = dummy_q_el_pt[0]->node_pt(j);
5112  Vector<double> s_tet(3);
5113  Vector<double> x_tet(3);
5114  switch (j)
5115  {
5116  case 0:
5117  tet_el_pt->local_coordinate_of_node(0, s_tet);
5118  nod_pt->set_value(0, s_tet[0]);
5119  nod_pt->set_value(1, s_tet[1]);
5120  nod_pt->set_value(2, s_tet[2]);
5121  tet_el_pt->interpolated_x(s_tet, x_tet);
5122  nod_pt->x(0) = x_tet[0];
5123  nod_pt->x(1) = x_tet[1];
5124  nod_pt->x(2) = x_tet[2];
5125  break;
5126  case 1:
5127  tet_el_pt->local_coordinate_of_node(4, s_tet);
5128  nod_pt->set_value(0, s_tet[0]);
5129  nod_pt->set_value(1, s_tet[1]);
5130  nod_pt->set_value(2, s_tet[2]);
5131  tet_el_pt->interpolated_x(s_tet, x_tet);
5132  nod_pt->x(0) = x_tet[0];
5133  nod_pt->x(1) = x_tet[1];
5134  nod_pt->x(2) = x_tet[2];
5135  break;
5136  case 2:
5137  tet_el_pt->local_coordinate_of_node(6, s_tet);
5138  nod_pt->set_value(0, s_tet[0]);
5139  nod_pt->set_value(1, s_tet[1]);
5140  nod_pt->set_value(2, s_tet[2]);
5141  tet_el_pt->interpolated_x(s_tet, x_tet);
5142  nod_pt->x(0) = x_tet[0];
5143  nod_pt->x(1) = x_tet[1];
5144  nod_pt->x(2) = x_tet[2];
5145  break;
5146  case 3:
5147  // label 13 in initial sketch: Mid face node on face spanned by
5148  // tet nodes 0,1,3
5149  s_tet[0] = 1.0 / 3.0;
5150  s_tet[1] = 1.0 / 3.0;
5151  s_tet[2] = 0.0;
5152  nod_pt->set_value(0, s_tet[0]);
5153  nod_pt->set_value(1, s_tet[1]);
5154  nod_pt->set_value(2, s_tet[2]);
5155  tet_el_pt->interpolated_x(s_tet, x_tet);
5156  nod_pt->x(0) = x_tet[0];
5157  nod_pt->x(1) = x_tet[1];
5158  nod_pt->x(2) = x_tet[2];
5159  break;
5160  case 4:
5161  tet_el_pt->local_coordinate_of_node(5, s_tet);
5162  nod_pt->set_value(0, s_tet[0]);
5163  nod_pt->set_value(1, s_tet[1]);
5164  nod_pt->set_value(2, s_tet[2]);
5165  tet_el_pt->interpolated_x(s_tet, x_tet);
5166  nod_pt->x(0) = x_tet[0];
5167  nod_pt->x(1) = x_tet[1];
5168  nod_pt->x(2) = x_tet[2];
5169  break;
5170  case 5:
5171  // label 11 in initial sketch: Mid face node on face spanned
5172  // by tet nodes 0,1,2
5173  s_tet[0] = 1.0 / 3.0;
5174  s_tet[1] = 1.0 / 3.0;
5175  s_tet[2] = 1.0 / 3.0;
5176  nod_pt->set_value(0, s_tet[0]);
5177  nod_pt->set_value(1, s_tet[1]);
5178  nod_pt->set_value(2, s_tet[2]);
5179  tet_el_pt->interpolated_x(s_tet, x_tet);
5180  nod_pt->x(0) = x_tet[0];
5181  nod_pt->x(1) = x_tet[1];
5182  nod_pt->x(2) = x_tet[2];
5183  break;
5184  case 6:
5185  // label 12 in initial sketch: Mid face node on face
5186  // spanned by tet nodes 0,2,3
5187  s_tet[0] = 1.0 / 3.0;
5188  s_tet[1] = 0.0;
5189  s_tet[2] = 1.0 / 3.0;
5190  nod_pt->set_value(0, s_tet[0]);
5191  nod_pt->set_value(1, s_tet[1]);
5192  nod_pt->set_value(2, s_tet[2]);
5193  tet_el_pt->interpolated_x(s_tet, x_tet);
5194  nod_pt->x(0) = x_tet[0];
5195  nod_pt->x(1) = x_tet[1];
5196  nod_pt->x(2) = x_tet[2];
5197  break;
5198  case 7:
5199  // label 14 in initial sketch: Centroid
5200  s_tet[0] = 0.25;
5201  s_tet[1] = 0.25;
5202  s_tet[2] = 0.25;
5203  nod_pt->set_value(0, s_tet[0]);
5204  nod_pt->set_value(1, s_tet[1]);
5205  nod_pt->set_value(2, s_tet[2]);
5206  tet_el_pt->interpolated_x(s_tet, x_tet);
5207  nod_pt->x(0) = x_tet[0];
5208  nod_pt->x(1) = x_tet[1];
5209  nod_pt->x(2) = x_tet[2];
5210  break;
5211  }
5212  }
5213 
5214 
5215  // Create actual zeroth brick element
5216  FiniteElement* el_pt = new ELEMENT;
5217  brick_el0_pt = el_pt;
5218  Element_pt.push_back(el_pt);
5219 
5220  TFace face0(
5221  tet_el_pt->node_pt(0), tet_el_pt->node_pt(1), tet_el_pt->node_pt(2));
5222 
5223  TFace face1(
5224  tet_el_pt->node_pt(0), tet_el_pt->node_pt(2), tet_el_pt->node_pt(3));
5225 
5226  TFace face2(
5227  tet_el_pt->node_pt(0), tet_el_pt->node_pt(1), tet_el_pt->node_pt(3));
5228 
5229 
5230  // Tet vertex nodes along edges emanating from node 0 in brick
5231  Vector<Vector<unsigned>> tet_edge_node(3);
5232  tet_edge_node[0].resize(2);
5233  tet_edge_node[0][0] = 4;
5234  tet_edge_node[0][1] = 1;
5235  tet_edge_node[1].resize(2);
5236  tet_edge_node[1][0] = 6;
5237  tet_edge_node[1][1] = 3;
5238  tet_edge_node[2].resize(2);
5239  tet_edge_node[2][0] = 5;
5240  tet_edge_node[2][1] = 2;
5241 
5242  // Node number of tet vertex that node 0 in brick is centred on
5243  unsigned central_tet_vertex = 0;
5244 
5245  Node* tet_node_pt = 0;
5246  Node* old_node_pt = 0;
5247 
5248  // Corner node
5249  {
5250  unsigned j = 0;
5251 
5252  // Need new node?
5253  tet_node_pt = tet_el_pt->node_pt(central_tet_vertex);
5254  old_node_pt = tet_node_node_pt[tet_node_pt];
5255  if (old_node_pt == 0)
5256  {
5257  Node* new_node_pt = 0;
5258  if (tet_node_pt->is_on_boundary())
5259  {
5260  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
5261  }
5262  else
5263  {
5264  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
5265  }
5266  tet_node_node_pt[tet_node_pt] = new_node_pt;
5267  Node_pt.push_back(new_node_pt);
5268  Vector<double> s(3);
5269  Vector<double> s_tet(3);
5270  Vector<double> x_tet(3);
5271  el_pt->local_coordinate_of_node(j, s);
5272  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
5273  tet_el_pt->interpolated_x(s_tet, x_tet);
5274  new_node_pt->x(0) = x_tet[0];
5275  new_node_pt->x(1) = x_tet[1];
5276  new_node_pt->x(2) = x_tet[2];
5277  }
5278  // Node already exists
5279  else
5280  {
5281  el_pt->node_pt(j) = old_node_pt;
5282  }
5283  }
5284 
5285 
5286  // Brick vertex node coindides with mid-edge node on tet edge 0
5287  {
5288  unsigned j = 2;
5289 
5290  // Need new node?
5291  tet_node_pt = tet_el_pt->node_pt(tet_edge_node[0][0]);
5292  old_node_pt = tet_node_node_pt[tet_node_pt];
5293  if (old_node_pt == 0)
5294  {
5295  Node* new_node_pt = 0;
5296  if (tet_node_pt->is_on_boundary())
5297  {
5298  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
5299  }
5300  else
5301  {
5302  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
5303  }
5304  tet_node_node_pt[tet_node_pt] = new_node_pt;
5305  Node_pt.push_back(new_node_pt);
5306  Vector<double> s(3);
5307  Vector<double> s_tet(3);
5308  Vector<double> x_tet(3);
5309  el_pt->local_coordinate_of_node(j, s);
5310  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
5311  tet_el_pt->interpolated_x(s_tet, x_tet);
5312  new_node_pt->x(0) = x_tet[0];
5313  new_node_pt->x(1) = x_tet[1];
5314  new_node_pt->x(2) = x_tet[2];
5315  }
5316  // Node already exists
5317  else
5318  {
5319  el_pt->node_pt(j) = old_node_pt;
5320  }
5321  }
5322 
5323 
5324  // Brick vertex node coindides with mid vertex node of tet edge 1
5325  {
5326  unsigned j = 6;
5327 
5328  // Need new node?
5329  tet_node_pt = tet_el_pt->node_pt(tet_edge_node[1][0]);
5330  old_node_pt = tet_node_node_pt[tet_node_pt];
5331  if (old_node_pt == 0)
5332  {
5333  Node* new_node_pt = 0;
5334  if (tet_node_pt->is_on_boundary())
5335  {
5336  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
5337  }
5338  else
5339  {
5340  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
5341  }
5342  tet_node_node_pt[tet_node_pt] = new_node_pt;
5343  Node_pt.push_back(new_node_pt);
5344  Vector<double> s(3);
5345  Vector<double> s_tet(3);
5346  Vector<double> x_tet(3);
5347  el_pt->local_coordinate_of_node(j, s);
5348  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
5349  tet_el_pt->interpolated_x(s_tet, x_tet);
5350  new_node_pt->x(0) = x_tet[0];
5351  new_node_pt->x(1) = x_tet[1];
5352  new_node_pt->x(2) = x_tet[2];
5353  }
5354  // Node already exists
5355  else
5356  {
5357  el_pt->node_pt(j) = old_node_pt;
5358  }
5359  }
5360 
5361 
5362  // Brick vertex node coindides with mid-vertex node of tet edge 2
5363  {
5364  unsigned j = 18;
5365 
5366  // Need new node?
5367  tet_node_pt = tet_el_pt->node_pt(tet_edge_node[2][0]);
5368  old_node_pt = tet_node_node_pt[tet_node_pt];
5369  if (old_node_pt == 0)
5370  {
5371  Node* new_node_pt = 0;
5372  if (tet_node_pt->is_on_boundary())
5373  {
5374  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
5375  }
5376  else
5377  {
5378  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
5379  }
5380  tet_node_node_pt[tet_node_pt] = new_node_pt;
5381  Node_pt.push_back(new_node_pt);
5382  Vector<double> s(3);
5383  Vector<double> s_tet(3);
5384  Vector<double> x_tet(3);
5385  el_pt->local_coordinate_of_node(j, s);
5386  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
5387  tet_el_pt->interpolated_x(s_tet, x_tet);
5388  new_node_pt->x(0) = x_tet[0];
5389  new_node_pt->x(1) = x_tet[1];
5390  new_node_pt->x(2) = x_tet[2];
5391  }
5392  // Node already exists
5393  else
5394  {
5395  el_pt->node_pt(j) = old_node_pt;
5396  }
5397  }
5398 
5399 
5400  // Brick vertex node in the middle of tet face0, spanned by
5401  // tet vertices 0, 1, 2. Enumerated "11" in initial sketch.
5402  {
5403  unsigned j = 20;
5404 
5405  // Need new node?
5406  old_node_pt = tet_face_node_pt[face0];
5407  if (old_node_pt == 0)
5408  {
5409  Node* new_node_pt = 0;
5410  if (face0.is_boundary_face())
5411  {
5412  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
5413  }
5414  else
5415  {
5416  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
5417  }
5418  tet_face_node_pt[face0] = new_node_pt;
5419  Node_pt.push_back(new_node_pt);
5420  Vector<double> s(3);
5421  Vector<double> s_tet(3);
5422  Vector<double> x_tet(3);
5423  el_pt->local_coordinate_of_node(j, s);
5424  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
5425  tet_el_pt->interpolated_x(s_tet, x_tet);
5426  new_node_pt->x(0) = x_tet[0];
5427  new_node_pt->x(1) = x_tet[1];
5428  new_node_pt->x(2) = x_tet[2];
5429  }
5430  // Node already exists
5431  else
5432  {
5433  el_pt->node_pt(j) = old_node_pt;
5434  }
5435  }
5436 
5437  // Brick vertex node in the middle of tet face1, spanned by
5438  // tet vertices 0, 2, 3. Enumerated "12" in initial sketch.
5439  {
5440  unsigned j = 24;
5441 
5442  // Need new node?
5443  old_node_pt = tet_face_node_pt[face1];
5444  if (old_node_pt == 0)
5445  {
5446  Node* new_node_pt = 0;
5447  if (face1.is_boundary_face())
5448  {
5449  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
5450  }
5451  else
5452  {
5453  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
5454  }
5455  tet_face_node_pt[face1] = new_node_pt;
5456  Node_pt.push_back(new_node_pt);
5457  Vector<double> s(3);
5458  Vector<double> s_tet(3);
5459  Vector<double> x_tet(3);
5460  el_pt->local_coordinate_of_node(j, s);
5461  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
5462  tet_el_pt->interpolated_x(s_tet, x_tet);
5463  new_node_pt->x(0) = x_tet[0];
5464  new_node_pt->x(1) = x_tet[1];
5465  new_node_pt->x(2) = x_tet[2];
5466  }
5467  // Node already exists
5468  else
5469  {
5470  el_pt->node_pt(j) = old_node_pt;
5471  }
5472  }
5473 
5474  // Brick vertex node in the middle of tet face2, spanned by
5475  // tet vertices 0, 1, 3. Enumerated "13" in initial sketch.
5476  {
5477  unsigned j = 8;
5478 
5479  // Need new node?
5480  old_node_pt = tet_face_node_pt[face2];
5481  if (old_node_pt == 0)
5482  {
5483  Node* new_node_pt = 0;
5484  if (face2.is_boundary_face())
5485  {
5486  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
5487  }
5488  else
5489  {
5490  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
5491  }
5492  tet_face_node_pt[face2] = new_node_pt;
5493  Node_pt.push_back(new_node_pt);
5494  Vector<double> s(3);
5495  Vector<double> s_tet(3);
5496  Vector<double> x_tet(3);
5497  el_pt->local_coordinate_of_node(j, s);
5498  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
5499  tet_el_pt->interpolated_x(s_tet, x_tet);
5500  new_node_pt->x(0) = x_tet[0];
5501  new_node_pt->x(1) = x_tet[1];
5502  new_node_pt->x(2) = x_tet[2];
5503  }
5504  // Node already exists
5505  else
5506  {
5507  el_pt->node_pt(j) = old_node_pt;
5508  }
5509  }
5510 
5511  // Brick vertex node in centroid of tet. Only built for first element.
5512  // Enumerated "13" in initial sketch.
5513  {
5514  unsigned j = 26;
5515 
5516  // Always new
5517  {
5518  Node* new_node_pt = el_pt->construct_node(j, time_stepper_pt);
5519  centroid_node_pt = new_node_pt;
5520  Node_pt.push_back(new_node_pt);
5521  Vector<double> s(3);
5522  Vector<double> s_tet(3);
5523  Vector<double> x_tet(3);
5524  el_pt->local_coordinate_of_node(j, s);
5525  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
5526  tet_el_pt->interpolated_x(s_tet, x_tet);
5527  new_node_pt->x(0) = x_tet[0];
5528  new_node_pt->x(1) = x_tet[1];
5529  new_node_pt->x(2) = x_tet[2];
5530  }
5531  }
5532 
5533 
5534  // Internal brick node -- always built
5535  {
5536  unsigned j = 13;
5537 
5538  // Always new
5539  {
5540  Node* new_node_pt = el_pt->construct_node(j, time_stepper_pt);
5541  Node_pt.push_back(new_node_pt);
5542  Vector<double> s(3);
5543  Vector<double> s_tet(3);
5544  Vector<double> x_tet(3);
5545  el_pt->local_coordinate_of_node(j, s);
5546  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
5547  tet_el_pt->interpolated_x(s_tet, x_tet);
5548  new_node_pt->x(0) = x_tet[0];
5549  new_node_pt->x(1) = x_tet[1];
5550  new_node_pt->x(2) = x_tet[2];
5551  }
5552  }
5553 
5554  // Brick edge node between brick nodes 0 and 2
5555  {
5556  unsigned j = 1;
5557 
5558  // Need new node?
5559  Edge edge(el_pt->node_pt(0), el_pt->node_pt(2));
5560  old_node_pt = brick_edge_node_pt[edge];
5561  if (old_node_pt == 0)
5562  {
5563  Node* new_node_pt = 0;
5564  if (edge.is_boundary_edge())
5565  {
5566  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
5567  }
5568  else
5569  {
5570  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
5571  }
5572  brick_edge_node_pt[edge] = new_node_pt;
5573  Node_pt.push_back(new_node_pt);
5574  Vector<double> s(3);
5575  Vector<double> s_tet(3);
5576  Vector<double> x_tet(3);
5577  el_pt->local_coordinate_of_node(j, s);
5578  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
5579  tet_el_pt->interpolated_x(s_tet, x_tet);
5580  new_node_pt->x(0) = x_tet[0];
5581  new_node_pt->x(1) = x_tet[1];
5582  new_node_pt->x(2) = x_tet[2];
5583  }
5584  // Node already exists
5585  else
5586  {
5587  el_pt->node_pt(j) = old_node_pt;
5588  }
5589  }
5590 
5591 
5592  // Brick edge node between brick nodes 0 and 6
5593  {
5594  unsigned j = 3;
5595 
5596  // Need new node?
5597  Edge edge(el_pt->node_pt(0), el_pt->node_pt(6));
5598  old_node_pt = brick_edge_node_pt[edge];
5599  if (old_node_pt == 0)
5600  {
5601  Node* new_node_pt = 0;
5602  if (edge.is_boundary_edge())
5603  {
5604  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
5605  }
5606  else
5607  {
5608  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
5609  }
5610  brick_edge_node_pt[edge] = new_node_pt;
5611  Node_pt.push_back(new_node_pt);
5612  Vector<double> s(3);
5613  Vector<double> s_tet(3);
5614  Vector<double> x_tet(3);
5615  el_pt->local_coordinate_of_node(j, s);
5616  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
5617  tet_el_pt->interpolated_x(s_tet, x_tet);
5618  new_node_pt->x(0) = x_tet[0];
5619  new_node_pt->x(1) = x_tet[1];
5620  new_node_pt->x(2) = x_tet[2];
5621  }
5622  // Node already exists
5623  else
5624  {
5625  el_pt->node_pt(j) = old_node_pt;
5626  }
5627  }
5628 
5629  // Brick edge node between brick nodes 2 and 8
5630  {
5631  unsigned j = 5;
5632 
5633  // Need new node?
5634  Edge edge(el_pt->node_pt(2), el_pt->node_pt(8));
5635  old_node_pt = brick_edge_node_pt[edge];
5636  if (old_node_pt == 0)
5637  {
5638  Node* new_node_pt = 0;
5639  if (edge.is_boundary_edge())
5640  {
5641  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
5642  }
5643  else
5644  {
5645  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
5646  }
5647  brick_edge_node_pt[edge] = new_node_pt;
5648  Node_pt.push_back(new_node_pt);
5649  Vector<double> s(3);
5650  Vector<double> s_tet(3);
5651  Vector<double> x_tet(3);
5652  el_pt->local_coordinate_of_node(j, s);
5653  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
5654  tet_el_pt->interpolated_x(s_tet, x_tet);
5655  new_node_pt->x(0) = x_tet[0];
5656  new_node_pt->x(1) = x_tet[1];
5657  new_node_pt->x(2) = x_tet[2];
5658  }
5659  // Node already exists
5660  else
5661  {
5662  el_pt->node_pt(j) = old_node_pt;
5663  }
5664  }
5665 
5666  // Brick edge node between brick nodes 6 and 8
5667  {
5668  unsigned j = 7;
5669 
5670  // Need new node?
5671  Edge edge(el_pt->node_pt(6), el_pt->node_pt(8));
5672  old_node_pt = brick_edge_node_pt[edge];
5673  if (old_node_pt == 0)
5674  {
5675  Node* new_node_pt = 0;
5676  if (edge.is_boundary_edge())
5677  {
5678  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
5679  }
5680  else
5681  {
5682  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
5683  }
5684  brick_edge_node_pt[edge] = new_node_pt;
5685  Node_pt.push_back(new_node_pt);
5686  Vector<double> s(3);
5687  Vector<double> s_tet(3);
5688  Vector<double> x_tet(3);
5689  el_pt->local_coordinate_of_node(j, s);
5690  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
5691  tet_el_pt->interpolated_x(s_tet, x_tet);
5692  new_node_pt->x(0) = x_tet[0];
5693  new_node_pt->x(1) = x_tet[1];
5694  new_node_pt->x(2) = x_tet[2];
5695  }
5696  // Node already exists
5697  else
5698  {
5699  el_pt->node_pt(j) = old_node_pt;
5700  }
5701  }
5702 
5703  // Brick edge node between brick nodes 18 and 20
5704  {
5705  unsigned j = 19;
5706 
5707  // Need new node?
5708  Edge edge(el_pt->node_pt(18), el_pt->node_pt(20));
5709  old_node_pt = brick_edge_node_pt[edge];
5710  if (old_node_pt == 0)
5711  {
5712  Node* new_node_pt = 0;
5713  if (edge.is_boundary_edge())
5714  {
5715  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
5716  }
5717  else
5718  {
5719  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
5720  }
5721  brick_edge_node_pt[edge] = new_node_pt;
5722  Node_pt.push_back(new_node_pt);
5723  Vector<double> s(3);
5724  Vector<double> s_tet(3);
5725  Vector<double> x_tet(3);
5726  el_pt->local_coordinate_of_node(j, s);
5727  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
5728  tet_el_pt->interpolated_x(s_tet, x_tet);
5729  new_node_pt->x(0) = x_tet[0];
5730  new_node_pt->x(1) = x_tet[1];
5731  new_node_pt->x(2) = x_tet[2];
5732  }
5733  // Node already exists
5734  else
5735  {
5736  el_pt->node_pt(j) = old_node_pt;
5737  }
5738  }
5739 
5740 
5741  // Brick edge node between brick nodes 18 and 24
5742  {
5743  unsigned j = 21;
5744 
5745  // Need new node?
5746  Edge edge(el_pt->node_pt(18), el_pt->node_pt(24));
5747  old_node_pt = brick_edge_node_pt[edge];
5748  if (old_node_pt == 0)
5749  {
5750  Node* new_node_pt = 0;
5751  if (edge.is_boundary_edge())
5752  {
5753  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
5754  }
5755  else
5756  {
5757  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
5758  }
5759  brick_edge_node_pt[edge] = new_node_pt;
5760  Node_pt.push_back(new_node_pt);
5761  Vector<double> s(3);
5762  Vector<double> s_tet(3);
5763  Vector<double> x_tet(3);
5764  el_pt->local_coordinate_of_node(j, s);
5765  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
5766  tet_el_pt->interpolated_x(s_tet, x_tet);
5767  new_node_pt->x(0) = x_tet[0];
5768  new_node_pt->x(1) = x_tet[1];
5769  new_node_pt->x(2) = x_tet[2];
5770  }
5771  // Node already exists
5772  else
5773  {
5774  el_pt->node_pt(j) = old_node_pt;
5775  }
5776  }
5777 
5778  // Brick edge node between brick nodes 20 and 26
5779  {
5780  unsigned j = 23;
5781 
5782  // Need new node?
5783  Edge edge(el_pt->node_pt(20), el_pt->node_pt(26));
5784  old_node_pt = brick_edge_node_pt[edge];
5785  if (old_node_pt == 0)
5786  {
5787  Node* new_node_pt = 0;
5788  if (edge.is_boundary_edge())
5789  {
5790  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
5791  }
5792  else
5793  {
5794  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
5795  }
5796  brick_edge_node_pt[edge] = new_node_pt;
5797  Node_pt.push_back(new_node_pt);
5798  Vector<double> s(3);
5799  Vector<double> s_tet(3);
5800  Vector<double> x_tet(3);
5801  el_pt->local_coordinate_of_node(j, s);
5802  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
5803  tet_el_pt->interpolated_x(s_tet, x_tet);
5804  new_node_pt->x(0) = x_tet[0];
5805  new_node_pt->x(1) = x_tet[1];
5806  new_node_pt->x(2) = x_tet[2];
5807  }
5808  // Node already exists
5809  else
5810  {
5811  el_pt->node_pt(j) = old_node_pt;
5812  }
5813  }
5814 
5815 
5816  // Brick edge node between brick nodes 24 and 26
5817  {
5818  unsigned j = 25;
5819 
5820  // Need new node?
5821  Edge edge(el_pt->node_pt(24), el_pt->node_pt(26));
5822  old_node_pt = brick_edge_node_pt[edge];
5823  if (old_node_pt == 0)
5824  {
5825  Node* new_node_pt = 0;
5826  if (edge.is_boundary_edge())
5827  {
5828  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
5829  }
5830  else
5831  {
5832  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
5833  }
5834  brick_edge_node_pt[edge] = new_node_pt;
5835  Node_pt.push_back(new_node_pt);
5836  Vector<double> s(3);
5837  Vector<double> s_tet(3);
5838  Vector<double> x_tet(3);
5839  el_pt->local_coordinate_of_node(j, s);
5840  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
5841  tet_el_pt->interpolated_x(s_tet, x_tet);
5842  new_node_pt->x(0) = x_tet[0];
5843  new_node_pt->x(1) = x_tet[1];
5844  new_node_pt->x(2) = x_tet[2];
5845  }
5846  // Node already exists
5847  else
5848  {
5849  el_pt->node_pt(j) = old_node_pt;
5850  }
5851  }
5852 
5853  // Brick edge node between brick nodes 0 and 18
5854  {
5855  unsigned j = 9;
5856 
5857  // Need new node?
5858  Edge edge(el_pt->node_pt(0), el_pt->node_pt(18));
5859  old_node_pt = brick_edge_node_pt[edge];
5860  if (old_node_pt == 0)
5861  {
5862  Node* new_node_pt = 0;
5863  if (edge.is_boundary_edge())
5864  {
5865  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
5866  }
5867  else
5868  {
5869  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
5870  }
5871  brick_edge_node_pt[edge] = new_node_pt;
5872  Node_pt.push_back(new_node_pt);
5873  Vector<double> s(3);
5874  Vector<double> s_tet(3);
5875  Vector<double> x_tet(3);
5876  el_pt->local_coordinate_of_node(j, s);
5877  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
5878  tet_el_pt->interpolated_x(s_tet, x_tet);
5879  new_node_pt->x(0) = x_tet[0];
5880  new_node_pt->x(1) = x_tet[1];
5881  new_node_pt->x(2) = x_tet[2];
5882  }
5883  // Node already exists
5884  else
5885  {
5886  el_pt->node_pt(j) = old_node_pt;
5887  }
5888  }
5889 
5890 
5891  // Brick edge node between brick nodes 2 and 20
5892  {
5893  unsigned j = 11;
5894 
5895  // Need new node?
5896  Edge edge(el_pt->node_pt(2), el_pt->node_pt(20));
5897  old_node_pt = brick_edge_node_pt[edge];
5898  if (old_node_pt == 0)
5899  {
5900  Node* new_node_pt = 0;
5901  if (edge.is_boundary_edge())
5902  {
5903  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
5904  }
5905  else
5906  {
5907  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
5908  }
5909  brick_edge_node_pt[edge] = new_node_pt;
5910  Node_pt.push_back(new_node_pt);
5911  Vector<double> s(3);
5912  Vector<double> s_tet(3);
5913  Vector<double> x_tet(3);
5914  el_pt->local_coordinate_of_node(j, s);
5915  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
5916  tet_el_pt->interpolated_x(s_tet, x_tet);
5917  new_node_pt->x(0) = x_tet[0];
5918  new_node_pt->x(1) = x_tet[1];
5919  new_node_pt->x(2) = x_tet[2];
5920  }
5921  // Node already exists
5922  else
5923  {
5924  el_pt->node_pt(j) = old_node_pt;
5925  }
5926  }
5927 
5928 
5929  // Brick edge node between brick nodes 6 and 24
5930  {
5931  unsigned j = 15;
5932 
5933  // Need new node?
5934  Edge edge(el_pt->node_pt(6), el_pt->node_pt(24));
5935  old_node_pt = brick_edge_node_pt[edge];
5936  if (old_node_pt == 0)
5937  {
5938  Node* new_node_pt = 0;
5939  if (edge.is_boundary_edge())
5940  {
5941  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
5942  }
5943  else
5944  {
5945  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
5946  }
5947  brick_edge_node_pt[edge] = new_node_pt;
5948  Node_pt.push_back(new_node_pt);
5949  Vector<double> s(3);
5950  Vector<double> s_tet(3);
5951  Vector<double> x_tet(3);
5952  el_pt->local_coordinate_of_node(j, s);
5953  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
5954  tet_el_pt->interpolated_x(s_tet, x_tet);
5955  new_node_pt->x(0) = x_tet[0];
5956  new_node_pt->x(1) = x_tet[1];
5957  new_node_pt->x(2) = x_tet[2];
5958  }
5959  // Node already exists
5960  else
5961  {
5962  el_pt->node_pt(j) = old_node_pt;
5963  }
5964  }
5965 
5966 
5967  // Brick edge node between brick nodes 8 and 26
5968  {
5969  unsigned j = 17;
5970 
5971  // Need new node?
5972  Edge edge(el_pt->node_pt(8), el_pt->node_pt(26));
5973  old_node_pt = brick_edge_node_pt[edge];
5974  if (old_node_pt == 0)
5975  {
5976  Node* new_node_pt = 0;
5977  if (edge.is_boundary_edge())
5978  {
5979  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
5980  }
5981  else
5982  {
5983  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
5984  }
5985  brick_edge_node_pt[edge] = new_node_pt;
5986  Node_pt.push_back(new_node_pt);
5987  Vector<double> s(3);
5988  Vector<double> s_tet(3);
5989  Vector<double> x_tet(3);
5990  el_pt->local_coordinate_of_node(j, s);
5991  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
5992  tet_el_pt->interpolated_x(s_tet, x_tet);
5993  new_node_pt->x(0) = x_tet[0];
5994  new_node_pt->x(1) = x_tet[1];
5995  new_node_pt->x(2) = x_tet[2];
5996  }
5997  // Node already exists
5998  else
5999  {
6000  el_pt->node_pt(j) = old_node_pt;
6001  }
6002  }
6003 
6004 
6005  // Mid brick-face node associated with face
6006  // spanned by mid-vertex nodes associated with tet edges 0 and 2
6007  {
6008  unsigned j = 10;
6009 
6010  // Need new node?
6011  TFace face(tet_el_pt->node_pt(central_tet_vertex),
6012  tet_el_pt->node_pt(tet_edge_node[0][0]),
6013  tet_el_pt->node_pt(tet_edge_node[2][0]));
6014 
6015  old_node_pt = tet_face_node_pt[face];
6016  if (old_node_pt == 0)
6017  {
6018  Node* new_node_pt = 0;
6019  if (face.is_boundary_face())
6020  {
6021  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
6022  }
6023  else
6024  {
6025  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
6026  }
6027  tet_face_node_pt[face] = new_node_pt;
6028  Node_pt.push_back(new_node_pt);
6029  Vector<double> s(3);
6030  Vector<double> s_tet(3);
6031  Vector<double> x_tet(3);
6032  el_pt->local_coordinate_of_node(j, s);
6033  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
6034  tet_el_pt->interpolated_x(s_tet, x_tet);
6035  new_node_pt->x(0) = x_tet[0];
6036  new_node_pt->x(1) = x_tet[1];
6037  new_node_pt->x(2) = x_tet[2];
6038  }
6039  // Node already exists
6040  else
6041  {
6042  el_pt->node_pt(j) = old_node_pt;
6043  }
6044  }
6045 
6046 
6047  // Mid brick-face node associated with face
6048  // spanned by mid-vertex nodes associated with tet edges 1 and 2
6049  {
6050  unsigned j = 12;
6051 
6052  // Need new node?
6053  TFace face(tet_el_pt->node_pt(central_tet_vertex),
6054  tet_el_pt->node_pt(tet_edge_node[1][0]),
6055  tet_el_pt->node_pt(tet_edge_node[2][0]));
6056 
6057  old_node_pt = tet_face_node_pt[face];
6058  if (old_node_pt == 0)
6059  {
6060  Node* new_node_pt = 0;
6061  if (face.is_boundary_face())
6062  {
6063  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
6064  }
6065  else
6066  {
6067  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
6068  }
6069  tet_face_node_pt[face] = new_node_pt;
6070  Node_pt.push_back(new_node_pt);
6071  Vector<double> s(3);
6072  Vector<double> s_tet(3);
6073  Vector<double> x_tet(3);
6074  el_pt->local_coordinate_of_node(j, s);
6075  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
6076  tet_el_pt->interpolated_x(s_tet, x_tet);
6077  new_node_pt->x(0) = x_tet[0];
6078  new_node_pt->x(1) = x_tet[1];
6079  new_node_pt->x(2) = x_tet[2];
6080  }
6081  // Node already exists
6082  else
6083  {
6084  el_pt->node_pt(j) = old_node_pt;
6085  }
6086  }
6087 
6088 
6089  // Mid brick-face node associated with face
6090  // spanned by mid-vertex nodes associated with tet edges 0 and 1
6091  {
6092  unsigned j = 4;
6093 
6094  // Need new node?
6095  TFace face(tet_el_pt->node_pt(central_tet_vertex),
6096  tet_el_pt->node_pt(tet_edge_node[0][0]),
6097  tet_el_pt->node_pt(tet_edge_node[1][0]));
6098 
6099  old_node_pt = tet_face_node_pt[face];
6100  if (old_node_pt == 0)
6101  {
6102  Node* new_node_pt = 0;
6103  if (face.is_boundary_face())
6104  {
6105  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
6106  }
6107  else
6108  {
6109  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
6110  }
6111  tet_face_node_pt[face] = new_node_pt;
6112  Node_pt.push_back(new_node_pt);
6113  Vector<double> s(3);
6114  Vector<double> s_tet(3);
6115  Vector<double> x_tet(3);
6116  el_pt->local_coordinate_of_node(j, s);
6117  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
6118  tet_el_pt->interpolated_x(s_tet, x_tet);
6119  new_node_pt->x(0) = x_tet[0];
6120  new_node_pt->x(1) = x_tet[1];
6121  new_node_pt->x(2) = x_tet[2];
6122  }
6123  // Node already exists
6124  else
6125  {
6126  el_pt->node_pt(j) = old_node_pt;
6127  }
6128  }
6129 
6130 
6131  // Top mid brick-face node -- only built by first element
6132  {
6133  unsigned j = 22;
6134  Node* new_node_pt = el_pt->construct_node(j, time_stepper_pt);
6135  Node_pt.push_back(new_node_pt);
6136  Vector<double> s(3);
6137  Vector<double> s_tet(3);
6138  Vector<double> x_tet(3);
6139  el_pt->local_coordinate_of_node(j, s);
6140  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
6141  top_mid_face_node0_pt = new_node_pt;
6142  tet_el_pt->interpolated_x(s_tet, x_tet);
6143  new_node_pt->x(0) = x_tet[0];
6144  new_node_pt->x(1) = x_tet[1];
6145  new_node_pt->x(2) = x_tet[2];
6146  }
6147 
6148 
6149  // Right mid brick-face node -- only built by first element
6150  {
6151  unsigned j = 14;
6152  Node* new_node_pt = el_pt->construct_node(j, time_stepper_pt);
6153  Node_pt.push_back(new_node_pt);
6154  Vector<double> s(3);
6155  Vector<double> s_tet(3);
6156  Vector<double> x_tet(3);
6157  el_pt->local_coordinate_of_node(j, s);
6158  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
6159  right_mid_face_node0_pt = new_node_pt;
6160  tet_el_pt->interpolated_x(s_tet, x_tet);
6161  new_node_pt->x(0) = x_tet[0];
6162  new_node_pt->x(1) = x_tet[1];
6163  new_node_pt->x(2) = x_tet[2];
6164  }
6165 
6166 
6167  // Back mid brick-face node -- only built by first element
6168  {
6169  unsigned j = 16;
6170  Node* new_node_pt = el_pt->construct_node(j, time_stepper_pt);
6171  Node_pt.push_back(new_node_pt);
6172  Vector<double> s(3);
6173  Vector<double> s_tet(3);
6174  Vector<double> x_tet(3);
6175  el_pt->local_coordinate_of_node(j, s);
6176  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
6177  back_mid_face_node0_pt = new_node_pt;
6178  tet_el_pt->interpolated_x(s_tet, x_tet);
6179  new_node_pt->x(0) = x_tet[0];
6180  new_node_pt->x(1) = x_tet[1];
6181  new_node_pt->x(2) = x_tet[2];
6182  }
6183  }
6184 
6185 
6186  // Second brick element is centred at node 1 of tet:
6187  //--------------------------------------------------
6188  {
6189  // Assign coordinates of dummy element
6190  for (unsigned j = 0; j < 8; j++)
6191  {
6192  Node* nod_pt = dummy_q_el_pt[1]->node_pt(j);
6193  Vector<double> s_tet(3);
6194  Vector<double> x_tet(3);
6195  switch (j)
6196  {
6197  case 0:
6198  tet_el_pt->local_coordinate_of_node(1, s_tet);
6199  nod_pt->set_value(0, s_tet[0]);
6200  nod_pt->set_value(1, s_tet[1]);
6201  nod_pt->set_value(2, s_tet[2]);
6202  tet_el_pt->interpolated_x(s_tet, x_tet);
6203  nod_pt->x(0) = x_tet[0];
6204  nod_pt->x(1) = x_tet[1];
6205  nod_pt->x(2) = x_tet[2];
6206  break;
6207  case 1:
6208  tet_el_pt->local_coordinate_of_node(9, s_tet);
6209  nod_pt->set_value(0, s_tet[0]);
6210  nod_pt->set_value(1, s_tet[1]);
6211  nod_pt->set_value(2, s_tet[2]);
6212  tet_el_pt->interpolated_x(s_tet, x_tet);
6213  nod_pt->x(0) = x_tet[0];
6214  nod_pt->x(1) = x_tet[1];
6215  nod_pt->x(2) = x_tet[2];
6216  break;
6217  case 2:
6218  tet_el_pt->local_coordinate_of_node(4, s_tet);
6219  nod_pt->set_value(0, s_tet[0]);
6220  nod_pt->set_value(1, s_tet[1]);
6221  nod_pt->set_value(2, s_tet[2]);
6222  tet_el_pt->interpolated_x(s_tet, x_tet);
6223  nod_pt->x(0) = x_tet[0];
6224  nod_pt->x(1) = x_tet[1];
6225  nod_pt->x(2) = x_tet[2];
6226  break;
6227  case 3:
6228  // label 13 in initial sketch: Mid face node on face
6229  // spanned by tet nodes 0,1,3
6230  s_tet[0] = 1.0 / 3.0;
6231  s_tet[1] = 1.0 / 3.0;
6232  s_tet[2] = 0.0;
6233  nod_pt->set_value(0, s_tet[0]);
6234  nod_pt->set_value(1, s_tet[1]);
6235  nod_pt->set_value(2, s_tet[2]);
6236  tet_el_pt->interpolated_x(s_tet, x_tet);
6237  nod_pt->x(0) = x_tet[0];
6238  nod_pt->x(1) = x_tet[1];
6239  nod_pt->x(2) = x_tet[2];
6240  break;
6241  case 4:
6242  tet_el_pt->local_coordinate_of_node(7, s_tet);
6243  nod_pt->set_value(0, s_tet[0]);
6244  nod_pt->set_value(1, s_tet[1]);
6245  nod_pt->set_value(2, s_tet[2]);
6246  tet_el_pt->interpolated_x(s_tet, x_tet);
6247  nod_pt->x(0) = x_tet[0];
6248  nod_pt->x(1) = x_tet[1];
6249  nod_pt->x(2) = x_tet[2];
6250  break;
6251  case 5:
6252  // label 10 in initial sketch: Mid face node on face
6253  // spanned by tet nodes 1,2,3
6254  s_tet[0] = 0.0;
6255  s_tet[1] = 1.0 / 3.0;
6256  s_tet[2] = 1.0 / 3.0;
6257  nod_pt->set_value(0, s_tet[0]);
6258  nod_pt->set_value(1, s_tet[1]);
6259  nod_pt->set_value(2, s_tet[2]);
6260  tet_el_pt->interpolated_x(s_tet, x_tet);
6261  nod_pt->x(0) = x_tet[0];
6262  nod_pt->x(1) = x_tet[1];
6263  nod_pt->x(2) = x_tet[2];
6264  break;
6265  case 6:
6266  // label 11 in initial sketch: Mid face node on face
6267  // spanned by tet nodes 0,1,2
6268  s_tet[0] = 1.0 / 3.0;
6269  s_tet[1] = 1.0 / 3.0;
6270  s_tet[2] = 1.0 / 3.0;
6271  nod_pt->set_value(0, s_tet[0]);
6272  nod_pt->set_value(1, s_tet[1]);
6273  nod_pt->set_value(2, s_tet[2]);
6274  tet_el_pt->interpolated_x(s_tet, x_tet);
6275  nod_pt->x(0) = x_tet[0];
6276  nod_pt->x(1) = x_tet[1];
6277  nod_pt->x(2) = x_tet[2];
6278  break;
6279  case 7:
6280  // label 14 in initial sketch: Centroid
6281  s_tet[0] = 0.25;
6282  s_tet[1] = 0.25;
6283  s_tet[2] = 0.25;
6284  nod_pt->set_value(0, s_tet[0]);
6285  nod_pt->set_value(1, s_tet[1]);
6286  nod_pt->set_value(2, s_tet[2]);
6287  tet_el_pt->interpolated_x(s_tet, x_tet);
6288  nod_pt->x(0) = x_tet[0];
6289  nod_pt->x(1) = x_tet[1];
6290  nod_pt->x(2) = x_tet[2];
6291  break;
6292  }
6293  }
6294 
6295 
6296  // Create actual first brick element
6297  FiniteElement* el_pt = new ELEMENT;
6298  brick_el1_pt = el_pt;
6299  Element_pt.push_back(el_pt);
6300 
6301  TFace face0(
6302  tet_el_pt->node_pt(1), tet_el_pt->node_pt(3), tet_el_pt->node_pt(2));
6303 
6304  TFace face1(
6305  tet_el_pt->node_pt(1), tet_el_pt->node_pt(0), tet_el_pt->node_pt(2));
6306 
6307  TFace face2(
6308  tet_el_pt->node_pt(1), tet_el_pt->node_pt(0), tet_el_pt->node_pt(3));
6309 
6310  // Tet vertex nodes along edges emanating from node 0 in brick
6311  Vector<Vector<unsigned>> tet_edge_node(3);
6312  tet_edge_node[0].resize(2);
6313  tet_edge_node[0][0] = 9;
6314  tet_edge_node[0][1] = 3;
6315  tet_edge_node[1].resize(2);
6316  tet_edge_node[1][0] = 4;
6317  tet_edge_node[1][1] = 0;
6318  tet_edge_node[2].resize(2);
6319  tet_edge_node[2][0] = 7;
6320  tet_edge_node[2][1] = 2;
6321 
6322  // Node number of tet vertex that node 0 in brick is centred on
6323  unsigned central_tet_vertex = 1;
6324 
6325  Node* tet_node_pt = 0;
6326  Node* old_node_pt = 0;
6327 
6328  // Corner node
6329  {
6330  unsigned j = 0;
6331 
6332  // Need new node?
6333  tet_node_pt = tet_el_pt->node_pt(central_tet_vertex);
6334  old_node_pt = tet_node_node_pt[tet_node_pt];
6335  if (old_node_pt == 0)
6336  {
6337  Node* new_node_pt = 0;
6338  if (tet_node_pt->is_on_boundary())
6339  {
6340  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
6341  }
6342  else
6343  {
6344  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
6345  }
6346  tet_node_node_pt[tet_node_pt] = new_node_pt;
6347  Node_pt.push_back(new_node_pt);
6348  Vector<double> s(3);
6349  Vector<double> s_tet(3);
6350  Vector<double> x_tet(3);
6351  el_pt->local_coordinate_of_node(j, s);
6352  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
6353  tet_el_pt->interpolated_x(s_tet, x_tet);
6354  new_node_pt->x(0) = x_tet[0];
6355  new_node_pt->x(1) = x_tet[1];
6356  new_node_pt->x(2) = x_tet[2];
6357  }
6358  // Node already exists
6359  else
6360  {
6361  el_pt->node_pt(j) = old_node_pt;
6362  }
6363  }
6364 
6365 
6366  // Brick vertex node coindides with mid-edge node on tet edge 0
6367  {
6368  unsigned j = 2;
6369 
6370  // Need new node?
6371  tet_node_pt = tet_el_pt->node_pt(tet_edge_node[0][0]);
6372  old_node_pt = tet_node_node_pt[tet_node_pt];
6373  if (old_node_pt == 0)
6374  {
6375  Node* new_node_pt = 0;
6376  if (tet_node_pt->is_on_boundary())
6377  {
6378  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
6379  }
6380  else
6381  {
6382  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
6383  }
6384  tet_node_node_pt[tet_node_pt] = new_node_pt;
6385  Node_pt.push_back(new_node_pt);
6386  Vector<double> s(3);
6387  Vector<double> s_tet(3);
6388  Vector<double> x_tet(3);
6389  el_pt->local_coordinate_of_node(j, s);
6390  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
6391  tet_el_pt->interpolated_x(s_tet, x_tet);
6392  new_node_pt->x(0) = x_tet[0];
6393  new_node_pt->x(1) = x_tet[1];
6394  new_node_pt->x(2) = x_tet[2];
6395  }
6396  // Node already exists
6397  else
6398  {
6399  el_pt->node_pt(j) = old_node_pt;
6400  }
6401  }
6402 
6403 
6404  // Brick vertex node coindides with mid vertex node of tet edge 1
6405  {
6406  unsigned j = 6;
6407 
6408  // Need new node?
6409  tet_node_pt = tet_el_pt->node_pt(tet_edge_node[1][0]);
6410  old_node_pt = tet_node_node_pt[tet_node_pt];
6411  if (old_node_pt == 0)
6412  {
6413  Node* new_node_pt = 0;
6414  if (tet_node_pt->is_on_boundary())
6415  {
6416  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
6417  }
6418  else
6419  {
6420  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
6421  }
6422  tet_node_node_pt[tet_node_pt] = new_node_pt;
6423  Node_pt.push_back(new_node_pt);
6424  Vector<double> s(3);
6425  Vector<double> s_tet(3);
6426  Vector<double> x_tet(3);
6427  el_pt->local_coordinate_of_node(j, s);
6428  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
6429  tet_el_pt->interpolated_x(s_tet, x_tet);
6430  new_node_pt->x(0) = x_tet[0];
6431  new_node_pt->x(1) = x_tet[1];
6432  new_node_pt->x(2) = x_tet[2];
6433  }
6434  // Node already exists
6435  else
6436  {
6437  el_pt->node_pt(j) = old_node_pt;
6438  }
6439  }
6440 
6441 
6442  // Brick vertex node coindides with mid-vertex node of tet edge 2
6443  {
6444  unsigned j = 18;
6445 
6446  // Need new node?
6447  tet_node_pt = tet_el_pt->node_pt(tet_edge_node[2][0]);
6448  old_node_pt = tet_node_node_pt[tet_node_pt];
6449  if (old_node_pt == 0)
6450  {
6451  Node* new_node_pt = 0;
6452  if (tet_node_pt->is_on_boundary())
6453  {
6454  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
6455  }
6456  else
6457  {
6458  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
6459  }
6460  tet_node_node_pt[tet_node_pt] = new_node_pt;
6461  Node_pt.push_back(new_node_pt);
6462  Vector<double> s(3);
6463  Vector<double> s_tet(3);
6464  Vector<double> x_tet(3);
6465  el_pt->local_coordinate_of_node(j, s);
6466  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
6467  tet_el_pt->interpolated_x(s_tet, x_tet);
6468  new_node_pt->x(0) = x_tet[0];
6469  new_node_pt->x(1) = x_tet[1];
6470  new_node_pt->x(2) = x_tet[2];
6471  }
6472  // Node already exists
6473  else
6474  {
6475  el_pt->node_pt(j) = old_node_pt;
6476  }
6477  }
6478 
6479 
6480  // Brick vertex node in the middle of tet face0
6481  {
6482  unsigned j = 20;
6483 
6484  // Need new node?
6485  old_node_pt = tet_face_node_pt[face0];
6486  if (old_node_pt == 0)
6487  {
6488  Node* new_node_pt = 0;
6489  if (face0.is_boundary_face())
6490  {
6491  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
6492  }
6493  else
6494  {
6495  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
6496  }
6497  tet_face_node_pt[face0] = new_node_pt;
6498  Node_pt.push_back(new_node_pt);
6499  Vector<double> s(3);
6500  Vector<double> s_tet(3);
6501  Vector<double> x_tet(3);
6502  el_pt->local_coordinate_of_node(j, s);
6503  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
6504  tet_el_pt->interpolated_x(s_tet, x_tet);
6505  new_node_pt->x(0) = x_tet[0];
6506  new_node_pt->x(1) = x_tet[1];
6507  new_node_pt->x(2) = x_tet[2];
6508  }
6509  // Node already exists
6510  else
6511  {
6512  el_pt->node_pt(j) = old_node_pt;
6513  }
6514  }
6515 
6516  // Brick vertex node in the middle of tet face1
6517  {
6518  unsigned j = 24;
6519 
6520  // Need new node?
6521  old_node_pt = tet_face_node_pt[face1];
6522  if (old_node_pt == 0)
6523  {
6524  Node* new_node_pt = 0;
6525  if (face1.is_boundary_face())
6526  {
6527  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
6528  }
6529  else
6530  {
6531  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
6532  }
6533  tet_face_node_pt[face1] = new_node_pt;
6534  Node_pt.push_back(new_node_pt);
6535  Vector<double> s(3);
6536  Vector<double> s_tet(3);
6537  Vector<double> x_tet(3);
6538  el_pt->local_coordinate_of_node(j, s);
6539  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
6540  tet_el_pt->interpolated_x(s_tet, x_tet);
6541  new_node_pt->x(0) = x_tet[0];
6542  new_node_pt->x(1) = x_tet[1];
6543  new_node_pt->x(2) = x_tet[2];
6544  }
6545  // Node already exists
6546  else
6547  {
6548  el_pt->node_pt(j) = old_node_pt;
6549  }
6550  }
6551 
6552  // Brick vertex node in the middle of face2
6553  {
6554  unsigned j = 8;
6555 
6556  // Need new node?
6557  old_node_pt = tet_face_node_pt[face2];
6558  if (old_node_pt == 0)
6559  {
6560  Node* new_node_pt = 0;
6561  if (face2.is_boundary_face())
6562  {
6563  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
6564  }
6565  else
6566  {
6567  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
6568  }
6569  tet_face_node_pt[face2] = new_node_pt;
6570  Node_pt.push_back(new_node_pt);
6571  Vector<double> s(3);
6572  Vector<double> s_tet(3);
6573  Vector<double> x_tet(3);
6574  el_pt->local_coordinate_of_node(j, s);
6575  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
6576  tet_el_pt->interpolated_x(s_tet, x_tet);
6577  new_node_pt->x(0) = x_tet[0];
6578  new_node_pt->x(1) = x_tet[1];
6579  new_node_pt->x(2) = x_tet[2];
6580  }
6581  // Node already exists
6582  else
6583  {
6584  el_pt->node_pt(j) = old_node_pt;
6585  }
6586  }
6587 
6588 
6589  // Brick vertex node in centroid of tet. Only built for first element.
6590  // Enumerated "13" in initial sketch.
6591  {
6592  unsigned j = 26;
6593 
6594  // Always copied
6595  el_pt->node_pt(j) = centroid_node_pt;
6596  }
6597 
6598 
6599  // Internal brick node -- always built
6600  {
6601  unsigned j = 13;
6602 
6603  // Always new
6604  {
6605  Node* new_node_pt = el_pt->construct_node(j, time_stepper_pt);
6606  Node_pt.push_back(new_node_pt);
6607  Vector<double> s(3);
6608  Vector<double> s_tet(3);
6609  Vector<double> x_tet(3);
6610  el_pt->local_coordinate_of_node(j, s);
6611  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
6612  tet_el_pt->interpolated_x(s_tet, x_tet);
6613  new_node_pt->x(0) = x_tet[0];
6614  new_node_pt->x(1) = x_tet[1];
6615  new_node_pt->x(2) = x_tet[2];
6616  }
6617  }
6618 
6619 
6620  // Brick edge node between brick nodes 0 and 2
6621  {
6622  unsigned j = 1;
6623 
6624  // Need new node?
6625  Edge edge(el_pt->node_pt(0), el_pt->node_pt(2));
6626  old_node_pt = brick_edge_node_pt[edge];
6627  if (old_node_pt == 0)
6628  {
6629  Node* new_node_pt = 0;
6630  if (edge.is_boundary_edge())
6631  {
6632  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
6633  }
6634  else
6635  {
6636  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
6637  }
6638  brick_edge_node_pt[edge] = new_node_pt;
6639  Node_pt.push_back(new_node_pt);
6640  Vector<double> s(3);
6641  Vector<double> s_tet(3);
6642  Vector<double> x_tet(3);
6643  el_pt->local_coordinate_of_node(j, s);
6644  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
6645  tet_el_pt->interpolated_x(s_tet, x_tet);
6646  new_node_pt->x(0) = x_tet[0];
6647  new_node_pt->x(1) = x_tet[1];
6648  new_node_pt->x(2) = x_tet[2];
6649  }
6650  // Node already exists
6651  else
6652  {
6653  el_pt->node_pt(j) = old_node_pt;
6654  }
6655  }
6656 
6657 
6658  // Brick edge node between brick nodes 0 and 6
6659  {
6660  unsigned j = 3;
6661 
6662  // Need new node?
6663  Edge edge(el_pt->node_pt(0), el_pt->node_pt(6));
6664  old_node_pt = brick_edge_node_pt[edge];
6665  if (old_node_pt == 0)
6666  {
6667  Node* new_node_pt = 0;
6668  if (edge.is_boundary_edge())
6669  {
6670  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
6671  }
6672  else
6673  {
6674  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
6675  }
6676  brick_edge_node_pt[edge] = new_node_pt;
6677  Node_pt.push_back(new_node_pt);
6678  Vector<double> s(3);
6679  Vector<double> s_tet(3);
6680  Vector<double> x_tet(3);
6681  el_pt->local_coordinate_of_node(j, s);
6682  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
6683  tet_el_pt->interpolated_x(s_tet, x_tet);
6684  new_node_pt->x(0) = x_tet[0];
6685  new_node_pt->x(1) = x_tet[1];
6686  new_node_pt->x(2) = x_tet[2];
6687  }
6688  // Node already exists
6689  else
6690  {
6691  el_pt->node_pt(j) = old_node_pt;
6692  }
6693  }
6694 
6695 
6696  // Brick edge node between brick nodes 2 and 8
6697  {
6698  unsigned j = 5;
6699 
6700  // Need new node?
6701  Edge edge(el_pt->node_pt(2), el_pt->node_pt(8));
6702  old_node_pt = brick_edge_node_pt[edge];
6703  if (old_node_pt == 0)
6704  {
6705  Node* new_node_pt = 0;
6706  if (edge.is_boundary_edge())
6707  {
6708  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
6709  }
6710  else
6711  {
6712  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
6713  }
6714  brick_edge_node_pt[edge] = new_node_pt;
6715  Node_pt.push_back(new_node_pt);
6716  Vector<double> s(3);
6717  Vector<double> s_tet(3);
6718  Vector<double> x_tet(3);
6719  el_pt->local_coordinate_of_node(j, s);
6720  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
6721  tet_el_pt->interpolated_x(s_tet, x_tet);
6722  new_node_pt->x(0) = x_tet[0];
6723  new_node_pt->x(1) = x_tet[1];
6724  new_node_pt->x(2) = x_tet[2];
6725  }
6726  // Node already exists
6727  else
6728  {
6729  el_pt->node_pt(j) = old_node_pt;
6730  }
6731  }
6732 
6733  // Brick edge node between brick nodes 6 and 8
6734  {
6735  unsigned j = 7;
6736 
6737  // Need new node?
6738  Edge edge(el_pt->node_pt(6), el_pt->node_pt(8));
6739  old_node_pt = brick_edge_node_pt[edge];
6740  if (old_node_pt == 0)
6741  {
6742  Node* new_node_pt = 0;
6743  if (edge.is_boundary_edge())
6744  {
6745  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
6746  }
6747  else
6748  {
6749  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
6750  }
6751  brick_edge_node_pt[edge] = new_node_pt;
6752  Node_pt.push_back(new_node_pt);
6753  Vector<double> s(3);
6754  Vector<double> s_tet(3);
6755  Vector<double> x_tet(3);
6756  el_pt->local_coordinate_of_node(j, s);
6757  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
6758  tet_el_pt->interpolated_x(s_tet, x_tet);
6759  new_node_pt->x(0) = x_tet[0];
6760  new_node_pt->x(1) = x_tet[1];
6761  new_node_pt->x(2) = x_tet[2];
6762  }
6763  // Node already exists
6764  else
6765  {
6766  el_pt->node_pt(j) = old_node_pt;
6767  }
6768  }
6769 
6770  // Brick edge node between brick nodes 18 and 20
6771  {
6772  unsigned j = 19;
6773 
6774  // Need new node?
6775  Edge edge(el_pt->node_pt(18), el_pt->node_pt(20));
6776  old_node_pt = brick_edge_node_pt[edge];
6777  if (old_node_pt == 0)
6778  {
6779  Node* new_node_pt = 0;
6780  if (edge.is_boundary_edge())
6781  {
6782  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
6783  }
6784  else
6785  {
6786  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
6787  }
6788  brick_edge_node_pt[edge] = new_node_pt;
6789  Node_pt.push_back(new_node_pt);
6790  Vector<double> s(3);
6791  Vector<double> s_tet(3);
6792  Vector<double> x_tet(3);
6793  el_pt->local_coordinate_of_node(j, s);
6794  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
6795  tet_el_pt->interpolated_x(s_tet, x_tet);
6796  new_node_pt->x(0) = x_tet[0];
6797  new_node_pt->x(1) = x_tet[1];
6798  new_node_pt->x(2) = x_tet[2];
6799  }
6800  // Node already exists
6801  else
6802  {
6803  el_pt->node_pt(j) = old_node_pt;
6804  }
6805  }
6806 
6807 
6808  // Brick edge node between brick nodes 18 and 24
6809  {
6810  unsigned j = 21;
6811 
6812  // Need new node?
6813  Edge edge(el_pt->node_pt(18), el_pt->node_pt(24));
6814  old_node_pt = brick_edge_node_pt[edge];
6815  if (old_node_pt == 0)
6816  {
6817  Node* new_node_pt = 0;
6818  if (edge.is_boundary_edge())
6819  {
6820  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
6821  }
6822  else
6823  {
6824  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
6825  }
6826  brick_edge_node_pt[edge] = new_node_pt;
6827  Node_pt.push_back(new_node_pt);
6828  Vector<double> s(3);
6829  Vector<double> s_tet(3);
6830  Vector<double> x_tet(3);
6831  el_pt->local_coordinate_of_node(j, s);
6832  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
6833  tet_el_pt->interpolated_x(s_tet, x_tet);
6834  new_node_pt->x(0) = x_tet[0];
6835  new_node_pt->x(1) = x_tet[1];
6836  new_node_pt->x(2) = x_tet[2];
6837  }
6838  // Node already exists
6839  else
6840  {
6841  el_pt->node_pt(j) = old_node_pt;
6842  }
6843  }
6844 
6845  // Brick edge node between brick nodes 20 and 26
6846  {
6847  unsigned j = 23;
6848 
6849  // Need new node?
6850  Edge edge(el_pt->node_pt(20), el_pt->node_pt(26));
6851  old_node_pt = brick_edge_node_pt[edge];
6852  if (old_node_pt == 0)
6853  {
6854  Node* new_node_pt = 0;
6855  if (edge.is_boundary_edge())
6856  {
6857  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
6858  }
6859  else
6860  {
6861  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
6862  }
6863  brick_edge_node_pt[edge] = new_node_pt;
6864  Node_pt.push_back(new_node_pt);
6865  Vector<double> s(3);
6866  Vector<double> s_tet(3);
6867  Vector<double> x_tet(3);
6868  el_pt->local_coordinate_of_node(j, s);
6869  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
6870  tet_el_pt->interpolated_x(s_tet, x_tet);
6871  new_node_pt->x(0) = x_tet[0];
6872  new_node_pt->x(1) = x_tet[1];
6873  new_node_pt->x(2) = x_tet[2];
6874  }
6875  // Node already exists
6876  else
6877  {
6878  el_pt->node_pt(j) = old_node_pt;
6879  }
6880  }
6881 
6882 
6883  // Brick edge node between brick nodes 24 and 26
6884  {
6885  unsigned j = 25;
6886 
6887  // Need new node?
6888  Edge edge(el_pt->node_pt(24), el_pt->node_pt(26));
6889  old_node_pt = brick_edge_node_pt[edge];
6890  if (old_node_pt == 0)
6891  {
6892  Node* new_node_pt = 0;
6893  if (edge.is_boundary_edge())
6894  {
6895  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
6896  }
6897  else
6898  {
6899  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
6900  }
6901  brick_edge_node_pt[edge] = new_node_pt;
6902  Node_pt.push_back(new_node_pt);
6903  Vector<double> s(3);
6904  Vector<double> s_tet(3);
6905  Vector<double> x_tet(3);
6906  el_pt->local_coordinate_of_node(j, s);
6907  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
6908  tet_el_pt->interpolated_x(s_tet, x_tet);
6909  new_node_pt->x(0) = x_tet[0];
6910  new_node_pt->x(1) = x_tet[1];
6911  new_node_pt->x(2) = x_tet[2];
6912  }
6913  // Node already exists
6914  else
6915  {
6916  el_pt->node_pt(j) = old_node_pt;
6917  }
6918  }
6919 
6920  // Brick edge node between brick nodes 0 and 18
6921  {
6922  unsigned j = 9;
6923 
6924  // Need new node?
6925  Edge edge(el_pt->node_pt(0), el_pt->node_pt(18));
6926  old_node_pt = brick_edge_node_pt[edge];
6927  if (old_node_pt == 0)
6928  {
6929  Node* new_node_pt = 0;
6930  if (edge.is_boundary_edge())
6931  {
6932  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
6933  }
6934  else
6935  {
6936  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
6937  }
6938  brick_edge_node_pt[edge] = new_node_pt;
6939  Node_pt.push_back(new_node_pt);
6940  Vector<double> s(3);
6941  Vector<double> s_tet(3);
6942  Vector<double> x_tet(3);
6943  el_pt->local_coordinate_of_node(j, s);
6944  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
6945  tet_el_pt->interpolated_x(s_tet, x_tet);
6946  new_node_pt->x(0) = x_tet[0];
6947  new_node_pt->x(1) = x_tet[1];
6948  new_node_pt->x(2) = x_tet[2];
6949  }
6950  // Node already exists
6951  else
6952  {
6953  el_pt->node_pt(j) = old_node_pt;
6954  }
6955  }
6956 
6957 
6958  // Brick edge node between brick nodes 2 and 20
6959  {
6960  unsigned j = 11;
6961 
6962  // Need new node?
6963  Edge edge(el_pt->node_pt(2), el_pt->node_pt(20));
6964  old_node_pt = brick_edge_node_pt[edge];
6965  if (old_node_pt == 0)
6966  {
6967  Node* new_node_pt = 0;
6968  if (edge.is_boundary_edge())
6969  {
6970  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
6971  }
6972  else
6973  {
6974  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
6975  }
6976  brick_edge_node_pt[edge] = new_node_pt;
6977  Node_pt.push_back(new_node_pt);
6978  Vector<double> s(3);
6979  Vector<double> s_tet(3);
6980  Vector<double> x_tet(3);
6981  el_pt->local_coordinate_of_node(j, s);
6982  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
6983  tet_el_pt->interpolated_x(s_tet, x_tet);
6984  new_node_pt->x(0) = x_tet[0];
6985  new_node_pt->x(1) = x_tet[1];
6986  new_node_pt->x(2) = x_tet[2];
6987  }
6988  // Node already exists
6989  else
6990  {
6991  el_pt->node_pt(j) = old_node_pt;
6992  }
6993  }
6994 
6995 
6996  // Brick edge node between brick nodes 6 and 24
6997  {
6998  unsigned j = 15;
6999 
7000  // Need new node?
7001  Edge edge(el_pt->node_pt(6), el_pt->node_pt(24));
7002  old_node_pt = brick_edge_node_pt[edge];
7003  if (old_node_pt == 0)
7004  {
7005  Node* new_node_pt = 0;
7006  if (edge.is_boundary_edge())
7007  {
7008  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
7009  }
7010  else
7011  {
7012  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
7013  }
7014  brick_edge_node_pt[edge] = new_node_pt;
7015  Node_pt.push_back(new_node_pt);
7016  Vector<double> s(3);
7017  Vector<double> s_tet(3);
7018  Vector<double> x_tet(3);
7019  el_pt->local_coordinate_of_node(j, s);
7020  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
7021  tet_el_pt->interpolated_x(s_tet, x_tet);
7022  new_node_pt->x(0) = x_tet[0];
7023  new_node_pt->x(1) = x_tet[1];
7024  new_node_pt->x(2) = x_tet[2];
7025  }
7026  // Node already exists
7027  else
7028  {
7029  el_pt->node_pt(j) = old_node_pt;
7030  }
7031  }
7032 
7033 
7034  // Brick edge node between brick nodes 8 and 26
7035  {
7036  unsigned j = 17;
7037 
7038  // Need new node?
7039  Edge edge(el_pt->node_pt(8), el_pt->node_pt(26));
7040  old_node_pt = brick_edge_node_pt[edge];
7041  if (old_node_pt == 0)
7042  {
7043  Node* new_node_pt = 0;
7044  if (edge.is_boundary_edge())
7045  {
7046  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
7047  }
7048  else
7049  {
7050  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
7051  }
7052  brick_edge_node_pt[edge] = new_node_pt;
7053  Node_pt.push_back(new_node_pt);
7054  Vector<double> s(3);
7055  Vector<double> s_tet(3);
7056  Vector<double> x_tet(3);
7057  el_pt->local_coordinate_of_node(j, s);
7058  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
7059  tet_el_pt->interpolated_x(s_tet, x_tet);
7060  new_node_pt->x(0) = x_tet[0];
7061  new_node_pt->x(1) = x_tet[1];
7062  new_node_pt->x(2) = x_tet[2];
7063  }
7064  // Node already exists
7065  else
7066  {
7067  el_pt->node_pt(j) = old_node_pt;
7068  }
7069  }
7070 
7071 
7072  // Mid brick-face node associated with face
7073  // spanned by mid-vertex nodes associated with tet edges 0 and 2
7074  {
7075  unsigned j = 10;
7076 
7077  // Need new node?
7078  TFace face(tet_el_pt->node_pt(central_tet_vertex),
7079  tet_el_pt->node_pt(tet_edge_node[0][0]),
7080  tet_el_pt->node_pt(tet_edge_node[2][0]));
7081 
7082  old_node_pt = tet_face_node_pt[face];
7083  if (old_node_pt == 0)
7084  {
7085  Node* new_node_pt = 0;
7086  if (face.is_boundary_face())
7087  {
7088  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
7089  }
7090  else
7091  {
7092  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
7093  }
7094  tet_face_node_pt[face] = new_node_pt;
7095  Node_pt.push_back(new_node_pt);
7096  Vector<double> s(3);
7097  Vector<double> s_tet(3);
7098  Vector<double> x_tet(3);
7099  el_pt->local_coordinate_of_node(j, s);
7100  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
7101  tet_el_pt->interpolated_x(s_tet, x_tet);
7102  new_node_pt->x(0) = x_tet[0];
7103  new_node_pt->x(1) = x_tet[1];
7104  new_node_pt->x(2) = x_tet[2];
7105  }
7106  // Node already exists
7107  else
7108  {
7109  el_pt->node_pt(j) = old_node_pt;
7110  }
7111  }
7112 
7113 
7114  // Mid brick-face node associated with face
7115  // spanned by mid-vertex nodes associated with tet edges 1 and 2
7116  {
7117  unsigned j = 12;
7118 
7119  // Need new node?
7120  TFace face(tet_el_pt->node_pt(central_tet_vertex),
7121  tet_el_pt->node_pt(tet_edge_node[1][0]),
7122  tet_el_pt->node_pt(tet_edge_node[2][0]));
7123 
7124  old_node_pt = tet_face_node_pt[face];
7125  if (old_node_pt == 0)
7126  {
7127  Node* new_node_pt = 0;
7128  if (face.is_boundary_face())
7129  {
7130  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
7131  }
7132  else
7133  {
7134  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
7135  }
7136  tet_face_node_pt[face] = new_node_pt;
7137  Node_pt.push_back(new_node_pt);
7138  Vector<double> s(3);
7139  Vector<double> s_tet(3);
7140  Vector<double> x_tet(3);
7141  el_pt->local_coordinate_of_node(j, s);
7142  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
7143  tet_el_pt->interpolated_x(s_tet, x_tet);
7144  new_node_pt->x(0) = x_tet[0];
7145  new_node_pt->x(1) = x_tet[1];
7146  new_node_pt->x(2) = x_tet[2];
7147  }
7148  // Node already exists
7149  else
7150  {
7151  el_pt->node_pt(j) = old_node_pt;
7152  }
7153  }
7154 
7155 
7156  // Mid brick-face node associated with face
7157  // spanned by mid-vertex nodes associated with tet edges 0 and 1
7158  {
7159  unsigned j = 4;
7160 
7161  // Need new node?
7162  TFace face(tet_el_pt->node_pt(central_tet_vertex),
7163  tet_el_pt->node_pt(tet_edge_node[0][0]),
7164  tet_el_pt->node_pt(tet_edge_node[1][0]));
7165 
7166  old_node_pt = tet_face_node_pt[face];
7167  if (old_node_pt == 0)
7168  {
7169  Node* new_node_pt = 0;
7170  if (face.is_boundary_face())
7171  {
7172  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
7173  }
7174  else
7175  {
7176  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
7177  }
7178  tet_face_node_pt[face] = new_node_pt;
7179  Node_pt.push_back(new_node_pt);
7180  Vector<double> s(3);
7181  Vector<double> s_tet(3);
7182  Vector<double> x_tet(3);
7183  el_pt->local_coordinate_of_node(j, s);
7184  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
7185  tet_el_pt->interpolated_x(s_tet, x_tet);
7186  new_node_pt->x(0) = x_tet[0];
7187  new_node_pt->x(1) = x_tet[1];
7188  new_node_pt->x(2) = x_tet[2];
7189  }
7190  // Node already exists
7191  else
7192  {
7193  el_pt->node_pt(j) = old_node_pt;
7194  }
7195  }
7196 
7197 
7198  // Top mid brick-face node -- only built by this element
7199  {
7200  unsigned j = 22;
7201  Node* new_node_pt = el_pt->construct_node(j, time_stepper_pt);
7202  Node_pt.push_back(new_node_pt);
7203  Vector<double> s(3);
7204  Vector<double> s_tet(3);
7205  Vector<double> x_tet(3);
7206  el_pt->local_coordinate_of_node(j, s);
7207  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
7208  top_mid_face_node1_pt = new_node_pt;
7209  tet_el_pt->interpolated_x(s_tet, x_tet);
7210  new_node_pt->x(0) = x_tet[0];
7211  new_node_pt->x(1) = x_tet[1];
7212  new_node_pt->x(2) = x_tet[2];
7213  }
7214 
7215 
7216  // Right mid brick-face node -- only built by this element
7217  {
7218  unsigned j = 14;
7219  Node* new_node_pt = el_pt->construct_node(j, time_stepper_pt);
7220  Node_pt.push_back(new_node_pt);
7221  Vector<double> s(3);
7222  Vector<double> s_tet(3);
7223  Vector<double> x_tet(3);
7224  el_pt->local_coordinate_of_node(j, s);
7225  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
7226  right_mid_face_node1_pt = new_node_pt;
7227  tet_el_pt->interpolated_x(s_tet, x_tet);
7228  new_node_pt->x(0) = x_tet[0];
7229  new_node_pt->x(1) = x_tet[1];
7230  new_node_pt->x(2) = x_tet[2];
7231  }
7232 
7233 
7234  // Back mid brick-face node copy from previous element
7235  {
7236  unsigned j = 16;
7237 
7238  // Always copied
7239  el_pt->node_pt(j) = right_mid_face_node0_pt;
7240  }
7241  }
7242 
7243 
7244  // Third brick element is centred at node 3 of tet:
7245  //-------------------------------------------------
7246  {
7247  // Assign coordinates of dummy element
7248  for (unsigned j = 0; j < 8; j++)
7249  {
7250  Node* nod_pt = dummy_q_el_pt[2]->node_pt(j);
7251  Vector<double> s_tet(3);
7252  Vector<double> x_tet(3);
7253  switch (j)
7254  {
7255  case 0:
7256  tet_el_pt->local_coordinate_of_node(3, s_tet);
7257  nod_pt->set_value(0, s_tet[0]);
7258  nod_pt->set_value(1, s_tet[1]);
7259  nod_pt->set_value(2, s_tet[2]);
7260  tet_el_pt->interpolated_x(s_tet, x_tet);
7261  nod_pt->x(0) = x_tet[0];
7262  nod_pt->x(1) = x_tet[1];
7263  nod_pt->x(2) = x_tet[2];
7264  break;
7265  case 1:
7266  tet_el_pt->local_coordinate_of_node(6, s_tet);
7267  nod_pt->set_value(0, s_tet[0]);
7268  nod_pt->set_value(1, s_tet[1]);
7269  nod_pt->set_value(2, s_tet[2]);
7270  tet_el_pt->interpolated_x(s_tet, x_tet);
7271  nod_pt->x(0) = x_tet[0];
7272  nod_pt->x(1) = x_tet[1];
7273  nod_pt->x(2) = x_tet[2];
7274  break;
7275  case 2:
7276  tet_el_pt->local_coordinate_of_node(9, s_tet);
7277  nod_pt->set_value(0, s_tet[0]);
7278  nod_pt->set_value(1, s_tet[1]);
7279  nod_pt->set_value(2, s_tet[2]);
7280  tet_el_pt->interpolated_x(s_tet, x_tet);
7281  nod_pt->x(0) = x_tet[0];
7282  nod_pt->x(1) = x_tet[1];
7283  nod_pt->x(2) = x_tet[2];
7284  break;
7285  case 3:
7286  // label 13 in initial sketch: Mid face node on face
7287  // spanned by tet nodes 0,1,3
7288  s_tet[0] = 1.0 / 3.0;
7289  s_tet[1] = 1.0 / 3.0;
7290  s_tet[2] = 0.0;
7291  nod_pt->set_value(0, s_tet[0]);
7292  nod_pt->set_value(1, s_tet[1]);
7293  nod_pt->set_value(2, s_tet[2]);
7294  tet_el_pt->interpolated_x(s_tet, x_tet);
7295  nod_pt->x(0) = x_tet[0];
7296  nod_pt->x(1) = x_tet[1];
7297  nod_pt->x(2) = x_tet[2];
7298  break;
7299  case 4:
7300  tet_el_pt->local_coordinate_of_node(8, s_tet);
7301  nod_pt->set_value(0, s_tet[0]);
7302  nod_pt->set_value(1, s_tet[1]);
7303  nod_pt->set_value(2, s_tet[2]);
7304  tet_el_pt->interpolated_x(s_tet, x_tet);
7305  nod_pt->x(0) = x_tet[0];
7306  nod_pt->x(1) = x_tet[1];
7307  nod_pt->x(2) = x_tet[2];
7308  break;
7309  case 5:
7310  // label 12 in initial sketch: Mid face node on face
7311  // spanned by tet nodes 0,2,3
7312  s_tet[0] = 1.0 / 3.0;
7313  s_tet[1] = 0.0;
7314  s_tet[2] = 1.0 / 3.0;
7315  nod_pt->set_value(0, s_tet[0]);
7316  nod_pt->set_value(1, s_tet[1]);
7317  nod_pt->set_value(2, s_tet[2]);
7318  tet_el_pt->interpolated_x(s_tet, x_tet);
7319  nod_pt->x(0) = x_tet[0];
7320  nod_pt->x(1) = x_tet[1];
7321  nod_pt->x(2) = x_tet[2];
7322  break;
7323  case 6:
7324  // label 10 in initial sketch: Mid face node on face
7325  // spanned by tet nodes 1,2,3
7326  s_tet[0] = 0.0;
7327  s_tet[1] = 1.0 / 3.0;
7328  s_tet[2] = 1.0 / 3.0;
7329  nod_pt->set_value(0, s_tet[0]);
7330  nod_pt->set_value(1, s_tet[1]);
7331  nod_pt->set_value(2, s_tet[2]);
7332  tet_el_pt->interpolated_x(s_tet, x_tet);
7333  nod_pt->x(0) = x_tet[0];
7334  nod_pt->x(1) = x_tet[1];
7335  nod_pt->x(2) = x_tet[2];
7336  break;
7337  case 7:
7338  // label 14 in initial sketch: Centroid
7339  s_tet[0] = 0.25;
7340  s_tet[1] = 0.25;
7341  s_tet[2] = 0.25;
7342  nod_pt->set_value(0, s_tet[0]);
7343  nod_pt->set_value(1, s_tet[1]);
7344  nod_pt->set_value(2, s_tet[2]);
7345  tet_el_pt->interpolated_x(s_tet, x_tet);
7346  nod_pt->x(0) = x_tet[0];
7347  nod_pt->x(1) = x_tet[1];
7348  nod_pt->x(2) = x_tet[2];
7349  break;
7350  }
7351  }
7352 
7353 
7354  // Create actual second brick element
7355  FiniteElement* el_pt = new ELEMENT;
7356  brick_el2_pt = el_pt;
7357  Element_pt.push_back(el_pt);
7358 
7359  TFace face0(
7360  tet_el_pt->node_pt(3), tet_el_pt->node_pt(0), tet_el_pt->node_pt(2));
7361 
7362  TFace face1(
7363  tet_el_pt->node_pt(3), tet_el_pt->node_pt(1), tet_el_pt->node_pt(2));
7364 
7365  TFace face2(
7366  tet_el_pt->node_pt(3), tet_el_pt->node_pt(1), tet_el_pt->node_pt(0));
7367 
7368  // Tet vertex nodes along edges emanating from node 0 in brick
7369  Vector<Vector<unsigned>> tet_edge_node(3);
7370  tet_edge_node[0].resize(2);
7371  tet_edge_node[0][0] = 6;
7372  tet_edge_node[0][1] = 0;
7373  tet_edge_node[1].resize(2);
7374  tet_edge_node[1][0] = 9;
7375  tet_edge_node[1][1] = 1;
7376  tet_edge_node[2].resize(2);
7377  tet_edge_node[2][0] = 8;
7378  tet_edge_node[2][1] = 2;
7379 
7380  // Node number of tet vertex that node 0 in brick is centred on
7381  unsigned central_tet_vertex = 3;
7382 
7383  Node* tet_node_pt = 0;
7384  Node* old_node_pt = 0;
7385 
7386  // Corner node
7387  {
7388  unsigned j = 0;
7389 
7390  // Need new node?
7391  tet_node_pt = tet_el_pt->node_pt(central_tet_vertex);
7392  old_node_pt = tet_node_node_pt[tet_node_pt];
7393  if (old_node_pt == 0)
7394  {
7395  Node* new_node_pt = 0;
7396  if (tet_node_pt->is_on_boundary())
7397  {
7398  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
7399  }
7400  else
7401  {
7402  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
7403  }
7404  tet_node_node_pt[tet_node_pt] = new_node_pt;
7405  Node_pt.push_back(new_node_pt);
7406  Vector<double> s(3);
7407  Vector<double> s_tet(3);
7408  Vector<double> x_tet(3);
7409  el_pt->local_coordinate_of_node(j, s);
7410  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
7411  tet_el_pt->interpolated_x(s_tet, x_tet);
7412  new_node_pt->x(0) = x_tet[0];
7413  new_node_pt->x(1) = x_tet[1];
7414  new_node_pt->x(2) = x_tet[2];
7415  }
7416  // Node already exists
7417  else
7418  {
7419  el_pt->node_pt(j) = old_node_pt;
7420  }
7421  }
7422 
7423 
7424  // Brick vertex node coindides with mid-edge node on tet edge 0
7425  {
7426  unsigned j = 2;
7427 
7428  // Need new node?
7429  tet_node_pt = tet_el_pt->node_pt(tet_edge_node[0][0]);
7430  old_node_pt = tet_node_node_pt[tet_node_pt];
7431  if (old_node_pt == 0)
7432  {
7433  Node* new_node_pt = 0;
7434  if (tet_node_pt->is_on_boundary())
7435  {
7436  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
7437  }
7438  else
7439  {
7440  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
7441  }
7442  tet_node_node_pt[tet_node_pt] = new_node_pt;
7443  Node_pt.push_back(new_node_pt);
7444  Vector<double> s(3);
7445  Vector<double> s_tet(3);
7446  Vector<double> x_tet(3);
7447  el_pt->local_coordinate_of_node(j, s);
7448  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
7449  tet_el_pt->interpolated_x(s_tet, x_tet);
7450  new_node_pt->x(0) = x_tet[0];
7451  new_node_pt->x(1) = x_tet[1];
7452  new_node_pt->x(2) = x_tet[2];
7453  }
7454  // Node already exists
7455  else
7456  {
7457  el_pt->node_pt(j) = old_node_pt;
7458  }
7459  }
7460 
7461 
7462  // Brick vertex node coindides with mid vertex node of tet edge 1
7463  {
7464  unsigned j = 6;
7465 
7466  // Need new node?
7467  tet_node_pt = tet_el_pt->node_pt(tet_edge_node[1][0]);
7468  old_node_pt = tet_node_node_pt[tet_node_pt];
7469  if (old_node_pt == 0)
7470  {
7471  Node* new_node_pt = 0;
7472  if (tet_node_pt->is_on_boundary())
7473  {
7474  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
7475  }
7476  else
7477  {
7478  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
7479  }
7480  tet_node_node_pt[tet_node_pt] = new_node_pt;
7481  Node_pt.push_back(new_node_pt);
7482  Vector<double> s(3);
7483  Vector<double> s_tet(3);
7484  Vector<double> x_tet(3);
7485  el_pt->local_coordinate_of_node(j, s);
7486  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
7487  tet_el_pt->interpolated_x(s_tet, x_tet);
7488  new_node_pt->x(0) = x_tet[0];
7489  new_node_pt->x(1) = x_tet[1];
7490  new_node_pt->x(2) = x_tet[2];
7491  }
7492  // Node already exists
7493  else
7494  {
7495  el_pt->node_pt(j) = old_node_pt;
7496  }
7497  }
7498 
7499 
7500  // Brick vertex node coindides with mid-vertex node of tet edge 2
7501  {
7502  unsigned j = 18;
7503 
7504  // Need new node?
7505  tet_node_pt = tet_el_pt->node_pt(tet_edge_node[2][0]);
7506  old_node_pt = tet_node_node_pt[tet_node_pt];
7507  if (old_node_pt == 0)
7508  {
7509  Node* new_node_pt = 0;
7510  if (tet_node_pt->is_on_boundary())
7511  {
7512  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
7513  }
7514  else
7515  {
7516  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
7517  }
7518  tet_node_node_pt[tet_node_pt] = new_node_pt;
7519  Node_pt.push_back(new_node_pt);
7520  Vector<double> s(3);
7521  Vector<double> s_tet(3);
7522  Vector<double> x_tet(3);
7523  el_pt->local_coordinate_of_node(j, s);
7524  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
7525  tet_el_pt->interpolated_x(s_tet, x_tet);
7526  new_node_pt->x(0) = x_tet[0];
7527  new_node_pt->x(1) = x_tet[1];
7528  new_node_pt->x(2) = x_tet[2];
7529  }
7530  // Node already exists
7531  else
7532  {
7533  el_pt->node_pt(j) = old_node_pt;
7534  }
7535  }
7536 
7537 
7538  // Brick vertex node in the middle of tet face0
7539  {
7540  unsigned j = 20;
7541 
7542  // Need new node?
7543  old_node_pt = tet_face_node_pt[face0];
7544  if (old_node_pt == 0)
7545  {
7546  Node* new_node_pt = 0;
7547  if (face0.is_boundary_face())
7548  {
7549  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
7550  }
7551  else
7552  {
7553  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
7554  }
7555  tet_face_node_pt[face0] = new_node_pt;
7556  Node_pt.push_back(new_node_pt);
7557  Vector<double> s(3);
7558  Vector<double> s_tet(3);
7559  Vector<double> x_tet(3);
7560  el_pt->local_coordinate_of_node(j, s);
7561  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
7562  tet_el_pt->interpolated_x(s_tet, x_tet);
7563  new_node_pt->x(0) = x_tet[0];
7564  new_node_pt->x(1) = x_tet[1];
7565  new_node_pt->x(2) = x_tet[2];
7566  }
7567  // Node already exists
7568  else
7569  {
7570  el_pt->node_pt(j) = old_node_pt;
7571  }
7572  }
7573 
7574  // Brick vertex node in the middle of tet face1
7575  {
7576  unsigned j = 24;
7577 
7578  // Need new node?
7579  old_node_pt = tet_face_node_pt[face1];
7580  if (old_node_pt == 0)
7581  {
7582  Node* new_node_pt = 0;
7583  if (face1.is_boundary_face())
7584  {
7585  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
7586  }
7587  else
7588  {
7589  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
7590  }
7591  tet_face_node_pt[face1] = new_node_pt;
7592  Node_pt.push_back(new_node_pt);
7593  Vector<double> s(3);
7594  Vector<double> s_tet(3);
7595  Vector<double> x_tet(3);
7596  el_pt->local_coordinate_of_node(j, s);
7597  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
7598  tet_el_pt->interpolated_x(s_tet, x_tet);
7599  new_node_pt->x(0) = x_tet[0];
7600  new_node_pt->x(1) = x_tet[1];
7601  new_node_pt->x(2) = x_tet[2];
7602  }
7603  // Node already exists
7604  else
7605  {
7606  el_pt->node_pt(j) = old_node_pt;
7607  }
7608  }
7609 
7610  // Brick vertex node in the middle of tet face2
7611  {
7612  unsigned j = 8;
7613 
7614  // Need new node?
7615  old_node_pt = tet_face_node_pt[face2];
7616  if (old_node_pt == 0)
7617  {
7618  Node* new_node_pt = 0;
7619  if (face2.is_boundary_face())
7620  {
7621  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
7622  }
7623  else
7624  {
7625  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
7626  }
7627  tet_face_node_pt[face2] = new_node_pt;
7628  Node_pt.push_back(new_node_pt);
7629  Vector<double> s(3);
7630  Vector<double> s_tet(3);
7631  Vector<double> x_tet(3);
7632  el_pt->local_coordinate_of_node(j, s);
7633  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
7634  tet_el_pt->interpolated_x(s_tet, x_tet);
7635  new_node_pt->x(0) = x_tet[0];
7636  new_node_pt->x(1) = x_tet[1];
7637  new_node_pt->x(2) = x_tet[2];
7638  }
7639  // Node already exists
7640  else
7641  {
7642  el_pt->node_pt(j) = old_node_pt;
7643  }
7644  }
7645 
7646 
7647  // Brick vertex node in centroid of tet. Only built for first element.
7648  // Enumerated "13" in initial sketch.
7649  {
7650  unsigned j = 26;
7651 
7652  // Always copied
7653  el_pt->node_pt(j) = centroid_node_pt;
7654  }
7655 
7656 
7657  // Internal brick node -- always built
7658  {
7659  unsigned j = 13;
7660 
7661  // Always new
7662  {
7663  Node* new_node_pt = el_pt->construct_node(j, time_stepper_pt);
7664  Node_pt.push_back(new_node_pt);
7665  Vector<double> s(3);
7666  Vector<double> s_tet(3);
7667  Vector<double> x_tet(3);
7668  el_pt->local_coordinate_of_node(j, s);
7669  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
7670  tet_el_pt->interpolated_x(s_tet, x_tet);
7671  new_node_pt->x(0) = x_tet[0];
7672  new_node_pt->x(1) = x_tet[1];
7673  new_node_pt->x(2) = x_tet[2];
7674  }
7675  }
7676 
7677  // Brick edge node between brick nodes 0 and 2
7678  {
7679  unsigned j = 1;
7680 
7681  // Need new node?
7682  Edge edge(el_pt->node_pt(0), el_pt->node_pt(2));
7683  old_node_pt = brick_edge_node_pt[edge];
7684  if (old_node_pt == 0)
7685  {
7686  Node* new_node_pt = 0;
7687  if (edge.is_boundary_edge())
7688  {
7689  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
7690  }
7691  else
7692  {
7693  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
7694  }
7695  brick_edge_node_pt[edge] = new_node_pt;
7696  Node_pt.push_back(new_node_pt);
7697  Vector<double> s(3);
7698  Vector<double> s_tet(3);
7699  Vector<double> x_tet(3);
7700  el_pt->local_coordinate_of_node(j, s);
7701  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
7702  tet_el_pt->interpolated_x(s_tet, x_tet);
7703  new_node_pt->x(0) = x_tet[0];
7704  new_node_pt->x(1) = x_tet[1];
7705  new_node_pt->x(2) = x_tet[2];
7706  }
7707  // Node already exists
7708  else
7709  {
7710  el_pt->node_pt(j) = old_node_pt;
7711  }
7712  }
7713 
7714 
7715  // Brick edge node between brick nodes 0 and 6
7716  {
7717  unsigned j = 3;
7718 
7719  // Need new node?
7720  Edge edge(el_pt->node_pt(0), el_pt->node_pt(6));
7721  old_node_pt = brick_edge_node_pt[edge];
7722  if (old_node_pt == 0)
7723  {
7724  Node* new_node_pt = 0;
7725  if (edge.is_boundary_edge())
7726  {
7727  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
7728  }
7729  else
7730  {
7731  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
7732  }
7733  brick_edge_node_pt[edge] = new_node_pt;
7734  Node_pt.push_back(new_node_pt);
7735  Vector<double> s(3);
7736  Vector<double> s_tet(3);
7737  Vector<double> x_tet(3);
7738  el_pt->local_coordinate_of_node(j, s);
7739  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
7740  tet_el_pt->interpolated_x(s_tet, x_tet);
7741  new_node_pt->x(0) = x_tet[0];
7742  new_node_pt->x(1) = x_tet[1];
7743  new_node_pt->x(2) = x_tet[2];
7744  }
7745  // Node already exists
7746  else
7747  {
7748  el_pt->node_pt(j) = old_node_pt;
7749  }
7750  }
7751 
7752  // Brick edge node between brick nodes 2 and 8
7753  {
7754  unsigned j = 5;
7755 
7756  // Need new node?
7757  Edge edge(el_pt->node_pt(2), el_pt->node_pt(8));
7758  old_node_pt = brick_edge_node_pt[edge];
7759  if (old_node_pt == 0)
7760  {
7761  Node* new_node_pt = 0;
7762  if (edge.is_boundary_edge())
7763  {
7764  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
7765  }
7766  else
7767  {
7768  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
7769  }
7770  brick_edge_node_pt[edge] = new_node_pt;
7771  Node_pt.push_back(new_node_pt);
7772  Vector<double> s(3);
7773  Vector<double> s_tet(3);
7774  Vector<double> x_tet(3);
7775  el_pt->local_coordinate_of_node(j, s);
7776  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
7777  tet_el_pt->interpolated_x(s_tet, x_tet);
7778  new_node_pt->x(0) = x_tet[0];
7779  new_node_pt->x(1) = x_tet[1];
7780  new_node_pt->x(2) = x_tet[2];
7781  }
7782  // Node already exists
7783  else
7784  {
7785  el_pt->node_pt(j) = old_node_pt;
7786  }
7787  }
7788 
7789  // Brick edge node between brick nodes 6 and 8
7790  {
7791  unsigned j = 7;
7792 
7793  // Need new node?
7794  Edge edge(el_pt->node_pt(6), el_pt->node_pt(8));
7795  old_node_pt = brick_edge_node_pt[edge];
7796  if (old_node_pt == 0)
7797  {
7798  Node* new_node_pt = 0;
7799  if (edge.is_boundary_edge())
7800  {
7801  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
7802  }
7803  else
7804  {
7805  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
7806  }
7807  brick_edge_node_pt[edge] = new_node_pt;
7808  Node_pt.push_back(new_node_pt);
7809  Vector<double> s(3);
7810  Vector<double> s_tet(3);
7811  Vector<double> x_tet(3);
7812  el_pt->local_coordinate_of_node(j, s);
7813  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
7814  tet_el_pt->interpolated_x(s_tet, x_tet);
7815  new_node_pt->x(0) = x_tet[0];
7816  new_node_pt->x(1) = x_tet[1];
7817  new_node_pt->x(2) = x_tet[2];
7818  }
7819  // Node already exists
7820  else
7821  {
7822  el_pt->node_pt(j) = old_node_pt;
7823  }
7824  }
7825 
7826  // Brick edge node between brick nodes 18 and 20
7827  {
7828  unsigned j = 19;
7829 
7830  // Need new node?
7831  Edge edge(el_pt->node_pt(18), el_pt->node_pt(20));
7832  old_node_pt = brick_edge_node_pt[edge];
7833  if (old_node_pt == 0)
7834  {
7835  Node* new_node_pt = 0;
7836  if (edge.is_boundary_edge())
7837  {
7838  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
7839  }
7840  else
7841  {
7842  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
7843  }
7844  brick_edge_node_pt[edge] = new_node_pt;
7845  Node_pt.push_back(new_node_pt);
7846  Vector<double> s(3);
7847  Vector<double> s_tet(3);
7848  Vector<double> x_tet(3);
7849  el_pt->local_coordinate_of_node(j, s);
7850  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
7851  tet_el_pt->interpolated_x(s_tet, x_tet);
7852  new_node_pt->x(0) = x_tet[0];
7853  new_node_pt->x(1) = x_tet[1];
7854  new_node_pt->x(2) = x_tet[2];
7855  }
7856  // Node already exists
7857  else
7858  {
7859  el_pt->node_pt(j) = old_node_pt;
7860  }
7861  }
7862 
7863 
7864  // Brick edge node between brick nodes 18 and 24
7865  {
7866  unsigned j = 21;
7867 
7868  // Need new node?
7869  Edge edge(el_pt->node_pt(18), el_pt->node_pt(24));
7870  old_node_pt = brick_edge_node_pt[edge];
7871  if (old_node_pt == 0)
7872  {
7873  Node* new_node_pt = 0;
7874  if (edge.is_boundary_edge())
7875  {
7876  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
7877  }
7878  else
7879  {
7880  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
7881  }
7882  brick_edge_node_pt[edge] = new_node_pt;
7883  Node_pt.push_back(new_node_pt);
7884  Vector<double> s(3);
7885  Vector<double> s_tet(3);
7886  Vector<double> x_tet(3);
7887  el_pt->local_coordinate_of_node(j, s);
7888  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
7889  tet_el_pt->interpolated_x(s_tet, x_tet);
7890  new_node_pt->x(0) = x_tet[0];
7891  new_node_pt->x(1) = x_tet[1];
7892  new_node_pt->x(2) = x_tet[2];
7893  }
7894  // Node already exists
7895  else
7896  {
7897  el_pt->node_pt(j) = old_node_pt;
7898  }
7899  }
7900 
7901  // Brick edge node between brick nodes 20 and 26
7902  {
7903  unsigned j = 23;
7904 
7905  // Need new node?
7906  Edge edge(el_pt->node_pt(20), el_pt->node_pt(26));
7907  old_node_pt = brick_edge_node_pt[edge];
7908  if (old_node_pt == 0)
7909  {
7910  Node* new_node_pt = 0;
7911  if (edge.is_boundary_edge())
7912  {
7913  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
7914  }
7915  else
7916  {
7917  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
7918  }
7919  brick_edge_node_pt[edge] = new_node_pt;
7920  Node_pt.push_back(new_node_pt);
7921  Vector<double> s(3);
7922  Vector<double> s_tet(3);
7923  Vector<double> x_tet(3);
7924  el_pt->local_coordinate_of_node(j, s);
7925  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
7926  tet_el_pt->interpolated_x(s_tet, x_tet);
7927  new_node_pt->x(0) = x_tet[0];
7928  new_node_pt->x(1) = x_tet[1];
7929  new_node_pt->x(2) = x_tet[2];
7930  }
7931  // Node already exists
7932  else
7933  {
7934  el_pt->node_pt(j) = old_node_pt;
7935  }
7936  }
7937 
7938 
7939  // Brick edge node between brick nodes 24 and 26
7940  {
7941  unsigned j = 25;
7942 
7943  // Need new node?
7944  Edge edge(el_pt->node_pt(24), el_pt->node_pt(26));
7945  old_node_pt = brick_edge_node_pt[edge];
7946  if (old_node_pt == 0)
7947  {
7948  Node* new_node_pt = 0;
7949  if (edge.is_boundary_edge())
7950  {
7951  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
7952  }
7953  else
7954  {
7955  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
7956  }
7957  brick_edge_node_pt[edge] = new_node_pt;
7958  Node_pt.push_back(new_node_pt);
7959  Vector<double> s(3);
7960  Vector<double> s_tet(3);
7961  Vector<double> x_tet(3);
7962  el_pt->local_coordinate_of_node(j, s);
7963  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
7964  tet_el_pt->interpolated_x(s_tet, x_tet);
7965  new_node_pt->x(0) = x_tet[0];
7966  new_node_pt->x(1) = x_tet[1];
7967  new_node_pt->x(2) = x_tet[2];
7968  }
7969  // Node already exists
7970  else
7971  {
7972  el_pt->node_pt(j) = old_node_pt;
7973  }
7974  }
7975 
7976  // Brick edge node between brick nodes 0 and 18
7977  {
7978  unsigned j = 9;
7979 
7980  // Need new node?
7981  Edge edge(el_pt->node_pt(0), el_pt->node_pt(18));
7982  old_node_pt = brick_edge_node_pt[edge];
7983  if (old_node_pt == 0)
7984  {
7985  Node* new_node_pt = 0;
7986  if (edge.is_boundary_edge())
7987  {
7988  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
7989  }
7990  else
7991  {
7992  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
7993  }
7994  brick_edge_node_pt[edge] = new_node_pt;
7995  Node_pt.push_back(new_node_pt);
7996  Vector<double> s(3);
7997  Vector<double> s_tet(3);
7998  Vector<double> x_tet(3);
7999  el_pt->local_coordinate_of_node(j, s);
8000  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
8001  tet_el_pt->interpolated_x(s_tet, x_tet);
8002  new_node_pt->x(0) = x_tet[0];
8003  new_node_pt->x(1) = x_tet[1];
8004  new_node_pt->x(2) = x_tet[2];
8005  }
8006  // Node already exists
8007  else
8008  {
8009  el_pt->node_pt(j) = old_node_pt;
8010  }
8011  }
8012 
8013 
8014  // Brick edge node between brick nodes 2 and 20
8015  {
8016  unsigned j = 11;
8017 
8018  // Need new node?
8019  Edge edge(el_pt->node_pt(2), el_pt->node_pt(20));
8020  old_node_pt = brick_edge_node_pt[edge];
8021  if (old_node_pt == 0)
8022  {
8023  Node* new_node_pt = 0;
8024  if (edge.is_boundary_edge())
8025  {
8026  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
8027  }
8028  else
8029  {
8030  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
8031  }
8032  brick_edge_node_pt[edge] = new_node_pt;
8033  Node_pt.push_back(new_node_pt);
8034  Vector<double> s(3);
8035  Vector<double> s_tet(3);
8036  Vector<double> x_tet(3);
8037  el_pt->local_coordinate_of_node(j, s);
8038  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
8039  tet_el_pt->interpolated_x(s_tet, x_tet);
8040  new_node_pt->x(0) = x_tet[0];
8041  new_node_pt->x(1) = x_tet[1];
8042  new_node_pt->x(2) = x_tet[2];
8043  }
8044  // Node already exists
8045  else
8046  {
8047  el_pt->node_pt(j) = old_node_pt;
8048  }
8049  }
8050 
8051 
8052  // Brick edge node between brick nodes 6 and 24
8053  {
8054  unsigned j = 15;
8055 
8056  // Need new node?
8057  Edge edge(el_pt->node_pt(6), el_pt->node_pt(24));
8058  old_node_pt = brick_edge_node_pt[edge];
8059  if (old_node_pt == 0)
8060  {
8061  Node* new_node_pt = 0;
8062  if (edge.is_boundary_edge())
8063  {
8064  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
8065  }
8066  else
8067  {
8068  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
8069  }
8070  brick_edge_node_pt[edge] = new_node_pt;
8071  Node_pt.push_back(new_node_pt);
8072  Vector<double> s(3);
8073  Vector<double> s_tet(3);
8074  Vector<double> x_tet(3);
8075  el_pt->local_coordinate_of_node(j, s);
8076  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
8077  tet_el_pt->interpolated_x(s_tet, x_tet);
8078  new_node_pt->x(0) = x_tet[0];
8079  new_node_pt->x(1) = x_tet[1];
8080  new_node_pt->x(2) = x_tet[2];
8081  }
8082  // Node already exists
8083  else
8084  {
8085  el_pt->node_pt(j) = old_node_pt;
8086  }
8087  }
8088 
8089 
8090  // Brick edge node between brick nodes 8 and 26
8091  {
8092  unsigned j = 17;
8093 
8094  // Need new node?
8095  Edge edge(el_pt->node_pt(8), el_pt->node_pt(26));
8096  old_node_pt = brick_edge_node_pt[edge];
8097  if (old_node_pt == 0)
8098  {
8099  Node* new_node_pt = 0;
8100  if (edge.is_boundary_edge())
8101  {
8102  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
8103  }
8104  else
8105  {
8106  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
8107  }
8108  brick_edge_node_pt[edge] = new_node_pt;
8109  Node_pt.push_back(new_node_pt);
8110  Vector<double> s(3);
8111  Vector<double> s_tet(3);
8112  Vector<double> x_tet(3);
8113  el_pt->local_coordinate_of_node(j, s);
8114  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
8115  tet_el_pt->interpolated_x(s_tet, x_tet);
8116  new_node_pt->x(0) = x_tet[0];
8117  new_node_pt->x(1) = x_tet[1];
8118  new_node_pt->x(2) = x_tet[2];
8119  }
8120  // Node already exists
8121  else
8122  {
8123  el_pt->node_pt(j) = old_node_pt;
8124  }
8125  }
8126 
8127 
8128  // Mid brick-face node associated with face
8129  // spanned by mid-vertex nodes associated with tet edges 0 and 2
8130  {
8131  unsigned j = 10;
8132 
8133  // Need new node?
8134  TFace face(tet_el_pt->node_pt(central_tet_vertex),
8135  tet_el_pt->node_pt(tet_edge_node[0][0]),
8136  tet_el_pt->node_pt(tet_edge_node[2][0]));
8137 
8138  old_node_pt = tet_face_node_pt[face];
8139  if (old_node_pt == 0)
8140  {
8141  Node* new_node_pt = 0;
8142  if (face.is_boundary_face())
8143  {
8144  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
8145  }
8146  else
8147  {
8148  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
8149  }
8150  tet_face_node_pt[face] = new_node_pt;
8151  Node_pt.push_back(new_node_pt);
8152  Vector<double> s(3);
8153  Vector<double> s_tet(3);
8154  Vector<double> x_tet(3);
8155  el_pt->local_coordinate_of_node(j, s);
8156  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
8157  tet_el_pt->interpolated_x(s_tet, x_tet);
8158  new_node_pt->x(0) = x_tet[0];
8159  new_node_pt->x(1) = x_tet[1];
8160  new_node_pt->x(2) = x_tet[2];
8161  }
8162  // Node already exists
8163  else
8164  {
8165  el_pt->node_pt(j) = old_node_pt;
8166  }
8167  }
8168 
8169 
8170  // Mid brick-face node associated with face
8171  // spanned by mid-vertex nodes associated with tet edges 1 and 2
8172  {
8173  unsigned j = 12;
8174 
8175  // Need new node?
8176  TFace face(tet_el_pt->node_pt(central_tet_vertex),
8177  tet_el_pt->node_pt(tet_edge_node[1][0]),
8178  tet_el_pt->node_pt(tet_edge_node[2][0]));
8179  old_node_pt = tet_face_node_pt[face];
8180  if (old_node_pt == 0)
8181  {
8182  Node* new_node_pt = 0;
8183  if (face.is_boundary_face())
8184  {
8185  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
8186  }
8187  else
8188  {
8189  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
8190  }
8191  tet_face_node_pt[face] = new_node_pt;
8192  Node_pt.push_back(new_node_pt);
8193  Vector<double> s(3);
8194  Vector<double> s_tet(3);
8195  Vector<double> x_tet(3);
8196  el_pt->local_coordinate_of_node(j, s);
8197  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
8198  tet_el_pt->interpolated_x(s_tet, x_tet);
8199  new_node_pt->x(0) = x_tet[0];
8200  new_node_pt->x(1) = x_tet[1];
8201  new_node_pt->x(2) = x_tet[2];
8202  }
8203  // Node already exists
8204  else
8205  {
8206  el_pt->node_pt(j) = old_node_pt;
8207  }
8208  }
8209 
8210 
8211  // Mid brick-face node associated with face
8212  // spanned by mid-vertex nodes associated with tet edges 0 and 1
8213  {
8214  unsigned j = 4;
8215 
8216  // Need new node?
8217  TFace face(tet_el_pt->node_pt(central_tet_vertex),
8218  tet_el_pt->node_pt(tet_edge_node[0][0]),
8219  tet_el_pt->node_pt(tet_edge_node[1][0]));
8220 
8221  old_node_pt = tet_face_node_pt[face];
8222  if (old_node_pt == 0)
8223  {
8224  Node* new_node_pt = 0;
8225  if (face.is_boundary_face())
8226  {
8227  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
8228  }
8229  else
8230  {
8231  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
8232  }
8233  tet_face_node_pt[face] = new_node_pt;
8234  Node_pt.push_back(new_node_pt);
8235  Vector<double> s(3);
8236  Vector<double> s_tet(3);
8237  Vector<double> x_tet(3);
8238  el_pt->local_coordinate_of_node(j, s);
8239  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
8240  tet_el_pt->interpolated_x(s_tet, x_tet);
8241  new_node_pt->x(0) = x_tet[0];
8242  new_node_pt->x(1) = x_tet[1];
8243  new_node_pt->x(2) = x_tet[2];
8244  }
8245  // Node already exists
8246  else
8247  {
8248  el_pt->node_pt(j) = old_node_pt;
8249  }
8250  }
8251 
8252 
8253  // Top mid brick-face node -- only built by this element
8254  {
8255  unsigned j = 22;
8256  Node* new_node_pt = el_pt->construct_node(j, time_stepper_pt);
8257  Node_pt.push_back(new_node_pt);
8258  Vector<double> s(3);
8259  Vector<double> s_tet(3);
8260  Vector<double> x_tet(3);
8261  el_pt->local_coordinate_of_node(j, s);
8262  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
8263  top_mid_face_node2_pt = new_node_pt;
8264  tet_el_pt->interpolated_x(s_tet, x_tet);
8265  new_node_pt->x(0) = x_tet[0];
8266  new_node_pt->x(1) = x_tet[1];
8267  new_node_pt->x(2) = x_tet[2];
8268  }
8269 
8270 
8271  // Right mid brick-face node copy from first element
8272  {
8273  unsigned j = 14;
8274 
8275  // Always copied
8276  el_pt->node_pt(j) = back_mid_face_node0_pt;
8277  }
8278 
8279 
8280  // Back mid brick-face node copy from previous element
8281  {
8282  unsigned j = 16;
8283 
8284  // Always copied
8285  el_pt->node_pt(j) = right_mid_face_node1_pt;
8286  }
8287  }
8288 
8289 
8290  // Fourth brick element is centred at node 2 of tet:
8291  //--------------------------------------------------
8292  {
8293  // Assign coordinates of dummy element
8294  for (unsigned j = 0; j < 8; j++)
8295  {
8296  Node* nod_pt = dummy_q_el_pt[3]->node_pt(j);
8297  Vector<double> s_tet(3);
8298  Vector<double> x_tet(3);
8299  switch (j)
8300  {
8301  case 0:
8302  tet_el_pt->local_coordinate_of_node(2, s_tet);
8303  nod_pt->set_value(0, s_tet[0]);
8304  nod_pt->set_value(1, s_tet[1]);
8305  nod_pt->set_value(2, s_tet[2]);
8306  tet_el_pt->interpolated_x(s_tet, x_tet);
8307  nod_pt->x(0) = x_tet[0];
8308  nod_pt->x(1) = x_tet[1];
8309  nod_pt->x(2) = x_tet[2];
8310  break;
8311  case 1:
8312  tet_el_pt->local_coordinate_of_node(7, s_tet);
8313  nod_pt->set_value(0, s_tet[0]);
8314  nod_pt->set_value(1, s_tet[1]);
8315  nod_pt->set_value(2, s_tet[2]);
8316  tet_el_pt->interpolated_x(s_tet, x_tet);
8317  nod_pt->x(0) = x_tet[0];
8318  nod_pt->x(1) = x_tet[1];
8319  nod_pt->x(2) = x_tet[2];
8320  break;
8321  case 2:
8322  tet_el_pt->local_coordinate_of_node(5, s_tet);
8323  nod_pt->set_value(0, s_tet[0]);
8324  nod_pt->set_value(1, s_tet[1]);
8325  nod_pt->set_value(2, s_tet[2]);
8326  tet_el_pt->interpolated_x(s_tet, x_tet);
8327  nod_pt->x(0) = x_tet[0];
8328  nod_pt->x(1) = x_tet[1];
8329  nod_pt->x(2) = x_tet[2];
8330  break;
8331  case 3:
8332  // label 11 in initial sketch: Mid face node on face
8333  // spanned by tet nodes 0,1,2
8334  s_tet[0] = 1.0 / 3.0;
8335  s_tet[1] = 1.0 / 3.0;
8336  s_tet[2] = 1.0 / 3.0;
8337  nod_pt->set_value(0, s_tet[0]);
8338  nod_pt->set_value(1, s_tet[1]);
8339  nod_pt->set_value(2, s_tet[2]);
8340  tet_el_pt->interpolated_x(s_tet, x_tet);
8341  nod_pt->x(0) = x_tet[0];
8342  nod_pt->x(1) = x_tet[1];
8343  nod_pt->x(2) = x_tet[2];
8344  break;
8345  case 4:
8346  tet_el_pt->local_coordinate_of_node(8, s_tet);
8347  nod_pt->set_value(0, s_tet[0]);
8348  nod_pt->set_value(1, s_tet[1]);
8349  nod_pt->set_value(2, s_tet[2]);
8350  tet_el_pt->interpolated_x(s_tet, x_tet);
8351  nod_pt->x(0) = x_tet[0];
8352  nod_pt->x(1) = x_tet[1];
8353  nod_pt->x(2) = x_tet[2];
8354  break;
8355  case 5:
8356  // label 10 in initial sketch: Mid face node on face
8357  // spanned by tet nodes 0,2,3
8358  s_tet[0] = 0.0;
8359  s_tet[1] = 1.0 / 3.0;
8360  s_tet[2] = 1.0 / 3.0;
8361  nod_pt->set_value(0, s_tet[0]);
8362  nod_pt->set_value(1, s_tet[1]);
8363  nod_pt->set_value(2, s_tet[2]);
8364  tet_el_pt->interpolated_x(s_tet, x_tet);
8365  nod_pt->x(0) = x_tet[0];
8366  nod_pt->x(1) = x_tet[1];
8367  nod_pt->x(2) = x_tet[2];
8368  break;
8369  case 6:
8370  // label 12 in initial sketch: Mid face node on face
8371  // spanned by tet nodes 0,2,3
8372  s_tet[0] = 1.0 / 3.0;
8373  s_tet[1] = 0.0;
8374  s_tet[2] = 1.0 / 3.0;
8375  nod_pt->set_value(0, s_tet[0]);
8376  nod_pt->set_value(1, s_tet[1]);
8377  nod_pt->set_value(2, s_tet[2]);
8378  tet_el_pt->interpolated_x(s_tet, x_tet);
8379  nod_pt->x(0) = x_tet[0];
8380  nod_pt->x(1) = x_tet[1];
8381  nod_pt->x(2) = x_tet[2];
8382  break;
8383  case 7:
8384  // label 14 in initial sketch: Centroid
8385  s_tet[0] = 0.25;
8386  s_tet[1] = 0.25;
8387  s_tet[2] = 0.25;
8388  nod_pt->set_value(0, s_tet[0]);
8389  nod_pt->set_value(1, s_tet[1]);
8390  nod_pt->set_value(2, s_tet[2]);
8391  tet_el_pt->interpolated_x(s_tet, x_tet);
8392  nod_pt->x(0) = x_tet[0];
8393  nod_pt->x(1) = x_tet[1];
8394  nod_pt->x(2) = x_tet[2];
8395  break;
8396  }
8397  }
8398 
8399 
8400  // Create actual third brick element
8401  FiniteElement* el_pt = new ELEMENT;
8402  brick_el3_pt = el_pt;
8403  Element_pt.push_back(el_pt);
8404 
8405  TFace face0(
8406  tet_el_pt->node_pt(1), tet_el_pt->node_pt(2), tet_el_pt->node_pt(3));
8407 
8408  TFace face1(
8409  tet_el_pt->node_pt(0), tet_el_pt->node_pt(2), tet_el_pt->node_pt(3));
8410 
8411  TFace face2(
8412  tet_el_pt->node_pt(0), tet_el_pt->node_pt(1), tet_el_pt->node_pt(2));
8413 
8414  // Tet vertex nodes along edges emanating from node 0 in brick
8415  Vector<Vector<unsigned>> tet_edge_node(3);
8416  tet_edge_node[0].resize(2);
8417  tet_edge_node[0][0] = 7;
8418  tet_edge_node[0][1] = 1;
8419  tet_edge_node[1].resize(2);
8420  tet_edge_node[1][0] = 5;
8421  tet_edge_node[1][1] = 0;
8422  tet_edge_node[2].resize(2);
8423  tet_edge_node[2][0] = 8;
8424  tet_edge_node[2][1] = 3;
8425 
8426  // Node number of tet vertex that node 0 in brick is centred on
8427  unsigned central_tet_vertex = 2;
8428 
8429  Node* tet_node_pt = 0;
8430  Node* old_node_pt = 0;
8431 
8432  // Corner node
8433  {
8434  unsigned j = 0;
8435 
8436  // Need new node?
8437  tet_node_pt = tet_el_pt->node_pt(central_tet_vertex);
8438  old_node_pt = tet_node_node_pt[tet_node_pt];
8439  if (old_node_pt == 0)
8440  {
8441  Node* new_node_pt = 0;
8442  if (tet_node_pt->is_on_boundary())
8443  {
8444  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
8445  }
8446  else
8447  {
8448  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
8449  }
8450  tet_node_node_pt[tet_node_pt] = new_node_pt;
8451  Node_pt.push_back(new_node_pt);
8452  Vector<double> s(3);
8453  Vector<double> s_tet(3);
8454  Vector<double> x_tet(3);
8455  el_pt->local_coordinate_of_node(j, s);
8456  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
8457  tet_el_pt->interpolated_x(s_tet, x_tet);
8458  new_node_pt->x(0) = x_tet[0];
8459  new_node_pt->x(1) = x_tet[1];
8460  new_node_pt->x(2) = x_tet[2];
8461  }
8462  // Node already exists
8463  else
8464  {
8465  el_pt->node_pt(j) = old_node_pt;
8466  }
8467  }
8468 
8469 
8470  // Brick vertex node coindides with mid-edge node on tet edge 0
8471  {
8472  unsigned j = 2;
8473 
8474  // Need new node?
8475  tet_node_pt = tet_el_pt->node_pt(tet_edge_node[0][0]);
8476  old_node_pt = tet_node_node_pt[tet_node_pt];
8477  if (old_node_pt == 0)
8478  {
8479  Node* new_node_pt = 0;
8480  if (tet_node_pt->is_on_boundary())
8481  {
8482  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
8483  }
8484  else
8485  {
8486  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
8487  }
8488  tet_node_node_pt[tet_node_pt] = new_node_pt;
8489  Node_pt.push_back(new_node_pt);
8490  Vector<double> s(3);
8491  Vector<double> s_tet(3);
8492  Vector<double> x_tet(3);
8493  el_pt->local_coordinate_of_node(j, s);
8494  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
8495  tet_el_pt->interpolated_x(s_tet, x_tet);
8496  new_node_pt->x(0) = x_tet[0];
8497  new_node_pt->x(1) = x_tet[1];
8498  new_node_pt->x(2) = x_tet[2];
8499  }
8500  // Node already exists
8501  else
8502  {
8503  el_pt->node_pt(j) = old_node_pt;
8504  }
8505  }
8506 
8507 
8508  // Brick vertex node coindides with mid vertex node of tet edge 1
8509  {
8510  unsigned j = 6;
8511 
8512  // Need new node?
8513  tet_node_pt = tet_el_pt->node_pt(tet_edge_node[1][0]);
8514  old_node_pt = tet_node_node_pt[tet_node_pt];
8515  if (old_node_pt == 0)
8516  {
8517  Node* new_node_pt = 0;
8518  if (tet_node_pt->is_on_boundary())
8519  {
8520  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
8521  }
8522  else
8523  {
8524  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
8525  }
8526  tet_node_node_pt[tet_node_pt] = new_node_pt;
8527  Node_pt.push_back(new_node_pt);
8528  Vector<double> s(3);
8529  Vector<double> s_tet(3);
8530  Vector<double> x_tet(3);
8531  el_pt->local_coordinate_of_node(j, s);
8532  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
8533  tet_el_pt->interpolated_x(s_tet, x_tet);
8534  new_node_pt->x(0) = x_tet[0];
8535  new_node_pt->x(1) = x_tet[1];
8536  new_node_pt->x(2) = x_tet[2];
8537  }
8538  // Node already exists
8539  else
8540  {
8541  el_pt->node_pt(j) = old_node_pt;
8542  }
8543  }
8544 
8545 
8546  // Brick vertex node coindides with mid-vertex node of tet edge 2
8547  {
8548  unsigned j = 18;
8549 
8550  // Need new node?
8551  tet_node_pt = tet_el_pt->node_pt(tet_edge_node[2][0]);
8552  old_node_pt = tet_node_node_pt[tet_node_pt];
8553  if (old_node_pt == 0)
8554  {
8555  Node* new_node_pt = 0;
8556  if (tet_node_pt->is_on_boundary())
8557  {
8558  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
8559  }
8560  else
8561  {
8562  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
8563  }
8564  tet_node_node_pt[tet_node_pt] = new_node_pt;
8565  Node_pt.push_back(new_node_pt);
8566  Vector<double> s(3);
8567  Vector<double> s_tet(3);
8568  Vector<double> x_tet(3);
8569  el_pt->local_coordinate_of_node(j, s);
8570  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
8571  tet_el_pt->interpolated_x(s_tet, x_tet);
8572  new_node_pt->x(0) = x_tet[0];
8573  new_node_pt->x(1) = x_tet[1];
8574  new_node_pt->x(2) = x_tet[2];
8575  }
8576  // Node already exists
8577  else
8578  {
8579  el_pt->node_pt(j) = old_node_pt;
8580  }
8581  }
8582 
8583 
8584  // Brick vertex node in the middle of tet face0
8585  {
8586  unsigned j = 20;
8587 
8588  // Need new node?
8589  old_node_pt = tet_face_node_pt[face0];
8590  if (old_node_pt == 0)
8591  {
8592  Node* new_node_pt = 0;
8593  if (face0.is_boundary_face())
8594  {
8595  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
8596  }
8597  else
8598  {
8599  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
8600  }
8601  tet_face_node_pt[face0] = new_node_pt;
8602  Node_pt.push_back(new_node_pt);
8603  Vector<double> s(3);
8604  Vector<double> s_tet(3);
8605  Vector<double> x_tet(3);
8606  el_pt->local_coordinate_of_node(j, s);
8607  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
8608  tet_el_pt->interpolated_x(s_tet, x_tet);
8609  new_node_pt->x(0) = x_tet[0];
8610  new_node_pt->x(1) = x_tet[1];
8611  new_node_pt->x(2) = x_tet[2];
8612  }
8613  // Node already exists
8614  else
8615  {
8616  el_pt->node_pt(j) = old_node_pt;
8617  }
8618  }
8619 
8620  // Brick vertex node in the middle of tet face1
8621  {
8622  unsigned j = 24;
8623 
8624  // Need new node?
8625  old_node_pt = tet_face_node_pt[face1];
8626  if (old_node_pt == 0)
8627  {
8628  Node* new_node_pt = 0;
8629  if (face1.is_boundary_face())
8630  {
8631  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
8632  }
8633  else
8634  {
8635  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
8636  }
8637  tet_face_node_pt[face1] = new_node_pt;
8638  Node_pt.push_back(new_node_pt);
8639  Vector<double> s(3);
8640  Vector<double> s_tet(3);
8641  Vector<double> x_tet(3);
8642  el_pt->local_coordinate_of_node(j, s);
8643  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
8644  tet_el_pt->interpolated_x(s_tet, x_tet);
8645  new_node_pt->x(0) = x_tet[0];
8646  new_node_pt->x(1) = x_tet[1];
8647  new_node_pt->x(2) = x_tet[2];
8648  }
8649  // Node already exists
8650  else
8651  {
8652  el_pt->node_pt(j) = old_node_pt;
8653  }
8654  }
8655 
8656  // Brick vertex node in the middle of tet face2
8657  {
8658  unsigned j = 8;
8659 
8660  // Need new node?
8661  old_node_pt = tet_face_node_pt[face2];
8662  if (old_node_pt == 0)
8663  {
8664  Node* new_node_pt = 0;
8665  if (face2.is_boundary_face())
8666  {
8667  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
8668  }
8669  else
8670  {
8671  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
8672  }
8673  tet_face_node_pt[face2] = new_node_pt;
8674  Node_pt.push_back(new_node_pt);
8675  Vector<double> s(3);
8676  Vector<double> s_tet(3);
8677  Vector<double> x_tet(3);
8678  el_pt->local_coordinate_of_node(j, s);
8679  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
8680  tet_el_pt->interpolated_x(s_tet, x_tet);
8681  new_node_pt->x(0) = x_tet[0];
8682  new_node_pt->x(1) = x_tet[1];
8683  new_node_pt->x(2) = x_tet[2];
8684  }
8685  // Node already exists
8686  else
8687  {
8688  el_pt->node_pt(j) = old_node_pt;
8689  }
8690  }
8691 
8692 
8693  // Brick vertex node in centroid of tet. Only built for first element.
8694  // Enumerated "13" in initial sketch.
8695  {
8696  unsigned j = 26;
8697 
8698  // Always copied
8699  el_pt->node_pt(j) = centroid_node_pt;
8700  }
8701 
8702 
8703  // Internal brick node -- always built
8704  {
8705  unsigned j = 13;
8706 
8707  // Always new
8708  {
8709  Node* new_node_pt = el_pt->construct_node(j, time_stepper_pt);
8710  Node_pt.push_back(new_node_pt);
8711  Vector<double> s(3);
8712  Vector<double> s_tet(3);
8713  Vector<double> x_tet(3);
8714  el_pt->local_coordinate_of_node(j, s);
8715  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
8716  tet_el_pt->interpolated_x(s_tet, x_tet);
8717  new_node_pt->x(0) = x_tet[0];
8718  new_node_pt->x(1) = x_tet[1];
8719  new_node_pt->x(2) = x_tet[2];
8720  }
8721  }
8722 
8723  // Brick edge node between brick nodes 0 and 2
8724  {
8725  unsigned j = 1;
8726 
8727  // Need new node?
8728  Edge edge(el_pt->node_pt(0), el_pt->node_pt(2));
8729  old_node_pt = brick_edge_node_pt[edge];
8730  if (old_node_pt == 0)
8731  {
8732  Node* new_node_pt = 0;
8733  if (edge.is_boundary_edge())
8734  {
8735  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
8736  }
8737  else
8738  {
8739  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
8740  }
8741  brick_edge_node_pt[edge] = new_node_pt;
8742  Node_pt.push_back(new_node_pt);
8743  Vector<double> s(3);
8744  Vector<double> s_tet(3);
8745  Vector<double> x_tet(3);
8746  el_pt->local_coordinate_of_node(j, s);
8747  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
8748  tet_el_pt->interpolated_x(s_tet, x_tet);
8749  new_node_pt->x(0) = x_tet[0];
8750  new_node_pt->x(1) = x_tet[1];
8751  new_node_pt->x(2) = x_tet[2];
8752  }
8753  // Node already exists
8754  else
8755  {
8756  el_pt->node_pt(j) = old_node_pt;
8757  }
8758  }
8759 
8760 
8761  // Brick edge node between brick nodes 0 and 6
8762  {
8763  unsigned j = 3;
8764 
8765  // Need new node?
8766  Edge edge(el_pt->node_pt(0), el_pt->node_pt(6));
8767  old_node_pt = brick_edge_node_pt[edge];
8768  if (old_node_pt == 0)
8769  {
8770  Node* new_node_pt = 0;
8771  if (edge.is_boundary_edge())
8772  {
8773  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
8774  }
8775  else
8776  {
8777  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
8778  }
8779  brick_edge_node_pt[edge] = new_node_pt;
8780  Node_pt.push_back(new_node_pt);
8781  Vector<double> s(3);
8782  Vector<double> s_tet(3);
8783  Vector<double> x_tet(3);
8784  el_pt->local_coordinate_of_node(j, s);
8785  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
8786  tet_el_pt->interpolated_x(s_tet, x_tet);
8787  new_node_pt->x(0) = x_tet[0];
8788  new_node_pt->x(1) = x_tet[1];
8789  new_node_pt->x(2) = x_tet[2];
8790  }
8791  // Node already exists
8792  else
8793  {
8794  el_pt->node_pt(j) = old_node_pt;
8795  }
8796  }
8797 
8798  // Brick edge node between brick nodes 2 and 8
8799  {
8800  unsigned j = 5;
8801 
8802  // Need new node?
8803  Edge edge(el_pt->node_pt(2), el_pt->node_pt(8));
8804  old_node_pt = brick_edge_node_pt[edge];
8805  if (old_node_pt == 0)
8806  {
8807  Node* new_node_pt = 0;
8808  if (edge.is_boundary_edge())
8809  {
8810  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
8811  }
8812  else
8813  {
8814  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
8815  }
8816  brick_edge_node_pt[edge] = new_node_pt;
8817  Node_pt.push_back(new_node_pt);
8818  Vector<double> s(3);
8819  Vector<double> s_tet(3);
8820  Vector<double> x_tet(3);
8821  el_pt->local_coordinate_of_node(j, s);
8822  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
8823  tet_el_pt->interpolated_x(s_tet, x_tet);
8824  new_node_pt->x(0) = x_tet[0];
8825  new_node_pt->x(1) = x_tet[1];
8826  new_node_pt->x(2) = x_tet[2];
8827  }
8828  // Node already exists
8829  else
8830  {
8831  el_pt->node_pt(j) = old_node_pt;
8832  }
8833  }
8834 
8835  // Brick edge node between brick nodes 6 and 8
8836  {
8837  unsigned j = 7;
8838 
8839  // Need new node?
8840  Edge edge(el_pt->node_pt(6), el_pt->node_pt(8));
8841  old_node_pt = brick_edge_node_pt[edge];
8842  if (old_node_pt == 0)
8843  {
8844  Node* new_node_pt = 0;
8845  if (edge.is_boundary_edge())
8846  {
8847  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
8848  }
8849  else
8850  {
8851  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
8852  }
8853  brick_edge_node_pt[edge] = new_node_pt;
8854  Node_pt.push_back(new_node_pt);
8855  Vector<double> s(3);
8856  Vector<double> s_tet(3);
8857  Vector<double> x_tet(3);
8858  el_pt->local_coordinate_of_node(j, s);
8859  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
8860  tet_el_pt->interpolated_x(s_tet, x_tet);
8861  new_node_pt->x(0) = x_tet[0];
8862  new_node_pt->x(1) = x_tet[1];
8863  new_node_pt->x(2) = x_tet[2];
8864  }
8865  // Node already exists
8866  else
8867  {
8868  el_pt->node_pt(j) = old_node_pt;
8869  }
8870  }
8871 
8872  // Brick edge node between brick nodes 18 and 20
8873  {
8874  unsigned j = 19;
8875 
8876  // Need new node?
8877  Edge edge(el_pt->node_pt(18), el_pt->node_pt(20));
8878  old_node_pt = brick_edge_node_pt[edge];
8879  if (old_node_pt == 0)
8880  {
8881  Node* new_node_pt = 0;
8882  if (edge.is_boundary_edge())
8883  {
8884  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
8885  }
8886  else
8887  {
8888  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
8889  }
8890  brick_edge_node_pt[edge] = new_node_pt;
8891  Node_pt.push_back(new_node_pt);
8892  Vector<double> s(3);
8893  Vector<double> s_tet(3);
8894  Vector<double> x_tet(3);
8895  el_pt->local_coordinate_of_node(j, s);
8896  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
8897  tet_el_pt->interpolated_x(s_tet, x_tet);
8898  new_node_pt->x(0) = x_tet[0];
8899  new_node_pt->x(1) = x_tet[1];
8900  new_node_pt->x(2) = x_tet[2];
8901  }
8902  // Node already exists
8903  else
8904  {
8905  el_pt->node_pt(j) = old_node_pt;
8906  }
8907  }
8908 
8909 
8910  // Brick edge node between brick nodes 18 and 24
8911  {
8912  unsigned j = 21;
8913 
8914  // Need new node?
8915  Edge edge(el_pt->node_pt(18), el_pt->node_pt(24));
8916  old_node_pt = brick_edge_node_pt[edge];
8917  if (old_node_pt == 0)
8918  {
8919  Node* new_node_pt = 0;
8920  if (edge.is_boundary_edge())
8921  {
8922  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
8923  }
8924  else
8925  {
8926  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
8927  }
8928  brick_edge_node_pt[edge] = new_node_pt;
8929  Node_pt.push_back(new_node_pt);
8930  Vector<double> s(3);
8931  Vector<double> s_tet(3);
8932  Vector<double> x_tet(3);
8933  el_pt->local_coordinate_of_node(j, s);
8934  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
8935  tet_el_pt->interpolated_x(s_tet, x_tet);
8936  new_node_pt->x(0) = x_tet[0];
8937  new_node_pt->x(1) = x_tet[1];
8938  new_node_pt->x(2) = x_tet[2];
8939  }
8940  // Node already exists
8941  else
8942  {
8943  el_pt->node_pt(j) = old_node_pt;
8944  }
8945  }
8946 
8947  // Brick edge node between brick nodes 20 and 26
8948  {
8949  unsigned j = 23;
8950 
8951  // Need new node?
8952  Edge edge(el_pt->node_pt(20), el_pt->node_pt(26));
8953  old_node_pt = brick_edge_node_pt[edge];
8954  if (old_node_pt == 0)
8955  {
8956  Node* new_node_pt = 0;
8957  if (edge.is_boundary_edge())
8958  {
8959  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
8960  }
8961  else
8962  {
8963  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
8964  }
8965  brick_edge_node_pt[edge] = new_node_pt;
8966  Node_pt.push_back(new_node_pt);
8967  Vector<double> s(3);
8968  Vector<double> s_tet(3);
8969  Vector<double> x_tet(3);
8970  el_pt->local_coordinate_of_node(j, s);
8971  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
8972  tet_el_pt->interpolated_x(s_tet, x_tet);
8973  new_node_pt->x(0) = x_tet[0];
8974  new_node_pt->x(1) = x_tet[1];
8975  new_node_pt->x(2) = x_tet[2];
8976  }
8977  // Node already exists
8978  else
8979  {
8980  el_pt->node_pt(j) = old_node_pt;
8981  }
8982  }
8983 
8984 
8985  // Brick edge node between brick nodes 24 and 26
8986  {
8987  unsigned j = 25;
8988 
8989  // Need new node?
8990  Edge edge(el_pt->node_pt(24), el_pt->node_pt(26));
8991  old_node_pt = brick_edge_node_pt[edge];
8992  if (old_node_pt == 0)
8993  {
8994  Node* new_node_pt = 0;
8995  if (edge.is_boundary_edge())
8996  {
8997  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
8998  }
8999  else
9000  {
9001  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
9002  }
9003  brick_edge_node_pt[edge] = new_node_pt;
9004  Node_pt.push_back(new_node_pt);
9005  Vector<double> s(3);
9006  Vector<double> s_tet(3);
9007  Vector<double> x_tet(3);
9008  el_pt->local_coordinate_of_node(j, s);
9009  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
9010  tet_el_pt->interpolated_x(s_tet, x_tet);
9011  new_node_pt->x(0) = x_tet[0];
9012  new_node_pt->x(1) = x_tet[1];
9013  new_node_pt->x(2) = x_tet[2];
9014  }
9015  // Node already exists
9016  else
9017  {
9018  el_pt->node_pt(j) = old_node_pt;
9019  }
9020  }
9021 
9022  // Brick edge node between brick nodes 0 and 18
9023  {
9024  unsigned j = 9;
9025 
9026  // Need new node?
9027  Edge edge(el_pt->node_pt(0), el_pt->node_pt(18));
9028  old_node_pt = brick_edge_node_pt[edge];
9029  if (old_node_pt == 0)
9030  {
9031  Node* new_node_pt = 0;
9032  if (edge.is_boundary_edge())
9033  {
9034  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
9035  }
9036  else
9037  {
9038  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
9039  }
9040  brick_edge_node_pt[edge] = new_node_pt;
9041  Node_pt.push_back(new_node_pt);
9042  Vector<double> s(3);
9043  Vector<double> s_tet(3);
9044  Vector<double> x_tet(3);
9045  el_pt->local_coordinate_of_node(j, s);
9046  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
9047  tet_el_pt->interpolated_x(s_tet, x_tet);
9048  new_node_pt->x(0) = x_tet[0];
9049  new_node_pt->x(1) = x_tet[1];
9050  new_node_pt->x(2) = x_tet[2];
9051  }
9052  // Node already exists
9053  else
9054  {
9055  el_pt->node_pt(j) = old_node_pt;
9056  }
9057  }
9058 
9059 
9060  // Brick edge node between brick nodes 2 and 20
9061  {
9062  unsigned j = 11;
9063 
9064  // Need new node?
9065  Edge edge(el_pt->node_pt(2), el_pt->node_pt(20));
9066  old_node_pt = brick_edge_node_pt[edge];
9067  if (old_node_pt == 0)
9068  {
9069  Node* new_node_pt = 0;
9070  if (edge.is_boundary_edge())
9071  {
9072  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
9073  }
9074  else
9075  {
9076  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
9077  }
9078  brick_edge_node_pt[edge] = new_node_pt;
9079  Node_pt.push_back(new_node_pt);
9080  Vector<double> s(3);
9081  Vector<double> s_tet(3);
9082  Vector<double> x_tet(3);
9083  el_pt->local_coordinate_of_node(j, s);
9084  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
9085  tet_el_pt->interpolated_x(s_tet, x_tet);
9086  new_node_pt->x(0) = x_tet[0];
9087  new_node_pt->x(1) = x_tet[1];
9088  new_node_pt->x(2) = x_tet[2];
9089  }
9090  // Node already exists
9091  else
9092  {
9093  el_pt->node_pt(j) = old_node_pt;
9094  }
9095  }
9096 
9097 
9098  // Brick edge node between brick nodes 6 and 24
9099  {
9100  unsigned j = 15;
9101 
9102  // Need new node?
9103  Edge edge(el_pt->node_pt(6), el_pt->node_pt(24));
9104  old_node_pt = brick_edge_node_pt[edge];
9105  if (old_node_pt == 0)
9106  {
9107  Node* new_node_pt = 0;
9108  if (edge.is_boundary_edge())
9109  {
9110  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
9111  }
9112  else
9113  {
9114  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
9115  }
9116  brick_edge_node_pt[edge] = new_node_pt;
9117  Node_pt.push_back(new_node_pt);
9118  Vector<double> s(3);
9119  Vector<double> s_tet(3);
9120  Vector<double> x_tet(3);
9121  el_pt->local_coordinate_of_node(j, s);
9122  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
9123  tet_el_pt->interpolated_x(s_tet, x_tet);
9124  new_node_pt->x(0) = x_tet[0];
9125  new_node_pt->x(1) = x_tet[1];
9126  new_node_pt->x(2) = x_tet[2];
9127  }
9128  // Node already exists
9129  else
9130  {
9131  el_pt->node_pt(j) = old_node_pt;
9132  }
9133  }
9134 
9135 
9136  // Brick edge node between brick nodes 8 and 26
9137  {
9138  unsigned j = 17;
9139 
9140  // Need new node?
9141  Edge edge(el_pt->node_pt(8), el_pt->node_pt(26));
9142  old_node_pt = brick_edge_node_pt[edge];
9143  if (old_node_pt == 0)
9144  {
9145  Node* new_node_pt = 0;
9146  if (edge.is_boundary_edge())
9147  {
9148  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
9149  }
9150  else
9151  {
9152  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
9153  }
9154  brick_edge_node_pt[edge] = new_node_pt;
9155  Node_pt.push_back(new_node_pt);
9156  Vector<double> s(3);
9157  Vector<double> s_tet(3);
9158  Vector<double> x_tet(3);
9159  el_pt->local_coordinate_of_node(j, s);
9160  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
9161  tet_el_pt->interpolated_x(s_tet, x_tet);
9162  new_node_pt->x(0) = x_tet[0];
9163  new_node_pt->x(1) = x_tet[1];
9164  new_node_pt->x(2) = x_tet[2];
9165  }
9166  // Node already exists
9167  else
9168  {
9169  el_pt->node_pt(j) = old_node_pt;
9170  }
9171  }
9172 
9173 
9174  // Mid brick-face node associated with face
9175  // spanned by mid-vertex nodes associated with tet edges 0 and 2
9176  {
9177  unsigned j = 10;
9178 
9179  // Need new node?
9180  TFace face(tet_el_pt->node_pt(central_tet_vertex),
9181  tet_el_pt->node_pt(tet_edge_node[0][0]),
9182  tet_el_pt->node_pt(tet_edge_node[2][0]));
9183 
9184  old_node_pt = tet_face_node_pt[face];
9185  if (old_node_pt == 0)
9186  {
9187  Node* new_node_pt = 0;
9188  if (face.is_boundary_face())
9189  {
9190  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
9191  }
9192  else
9193  {
9194  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
9195  }
9196  tet_face_node_pt[face] = new_node_pt;
9197  Node_pt.push_back(new_node_pt);
9198  Vector<double> s(3);
9199  Vector<double> s_tet(3);
9200  Vector<double> x_tet(3);
9201  el_pt->local_coordinate_of_node(j, s);
9202  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
9203  tet_el_pt->interpolated_x(s_tet, x_tet);
9204  new_node_pt->x(0) = x_tet[0];
9205  new_node_pt->x(1) = x_tet[1];
9206  new_node_pt->x(2) = x_tet[2];
9207  }
9208  // Node already exists
9209  else
9210  {
9211  el_pt->node_pt(j) = old_node_pt;
9212  }
9213  }
9214 
9215 
9216  // Mid brick-face node associated with face
9217  // spanned by mid-vertex nodes associated with tet edges 1 and 2
9218  {
9219  unsigned j = 12;
9220 
9221  // Need new node?
9222  TFace face(tet_el_pt->node_pt(central_tet_vertex),
9223  tet_el_pt->node_pt(tet_edge_node[1][0]),
9224  tet_el_pt->node_pt(tet_edge_node[2][0]));
9225 
9226  old_node_pt = tet_face_node_pt[face];
9227  if (old_node_pt == 0)
9228  {
9229  Node* new_node_pt = 0;
9230  if (face.is_boundary_face())
9231  {
9232  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
9233  }
9234  else
9235  {
9236  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
9237  }
9238  tet_face_node_pt[face] = new_node_pt;
9239  Node_pt.push_back(new_node_pt);
9240  Vector<double> s(3);
9241  Vector<double> s_tet(3);
9242  Vector<double> x_tet(3);
9243  el_pt->local_coordinate_of_node(j, s);
9244  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
9245  tet_el_pt->interpolated_x(s_tet, x_tet);
9246  new_node_pt->x(0) = x_tet[0];
9247  new_node_pt->x(1) = x_tet[1];
9248  new_node_pt->x(2) = x_tet[2];
9249  }
9250  // Node already exists
9251  else
9252  {
9253  el_pt->node_pt(j) = old_node_pt;
9254  }
9255  }
9256 
9257 
9258  // Mid brick-face node associated with face
9259  // spanned by mid-vertex nodes associated with tet edges 0 and 1
9260  {
9261  unsigned j = 4;
9262 
9263  // Need new node?
9264  TFace face(tet_el_pt->node_pt(central_tet_vertex),
9265  tet_el_pt->node_pt(tet_edge_node[0][0]),
9266  tet_el_pt->node_pt(tet_edge_node[1][0]));
9267 
9268  old_node_pt = tet_face_node_pt[face];
9269  if (old_node_pt == 0)
9270  {
9271  Node* new_node_pt = 0;
9272  if (face.is_boundary_face())
9273  {
9274  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
9275  }
9276  else
9277  {
9278  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
9279  }
9280  tet_face_node_pt[face] = new_node_pt;
9281  Node_pt.push_back(new_node_pt);
9282  Vector<double> s(3);
9283  Vector<double> s_tet(3);
9284  Vector<double> x_tet(3);
9285  el_pt->local_coordinate_of_node(j, s);
9286  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
9287  tet_el_pt->interpolated_x(s_tet, x_tet);
9288  new_node_pt->x(0) = x_tet[0];
9289  new_node_pt->x(1) = x_tet[1];
9290  new_node_pt->x(2) = x_tet[2];
9291  }
9292  // Node already exists
9293  else
9294  {
9295  el_pt->node_pt(j) = old_node_pt;
9296  }
9297  }
9298 
9299 
9300  // Top mid brick-face node copy from top of second element
9301  {
9302  unsigned j = 22;
9303 
9304  // Always copied
9305  el_pt->node_pt(j) = top_mid_face_node2_pt;
9306  }
9307 
9308 
9309  // Right mid brick-face node copy from top of first element
9310  {
9311  unsigned j = 14;
9312 
9313  // Always copied
9314  el_pt->node_pt(j) = top_mid_face_node1_pt;
9315  }
9316 
9317 
9318  // Back mid brick-face node copy from top of zeroth element
9319  {
9320  unsigned j = 16;
9321 
9322  // Always copied
9323  el_pt->node_pt(j) = top_mid_face_node0_pt;
9324  }
9325  }
9326 
9327 
9328  // Check if the four faces of the tet are on a boundary.
9329  // If they are, add the nodes in the brick mesh to those
9330  // boundaries.
9331 
9332  // Loop over faces of tet (in its own face index enumeration)
9333  for (int face_index = 0; face_index < 4; face_index++)
9334  {
9335  // Identify face and coordinates in it
9336  TFace* face_pt = 0;
9337  switch (face_index)
9338  {
9339  case 0:
9340  // Face 0: s[0]=0; opposite node 0
9341  face_pt = new TFace(tet_el_pt->node_pt(1),
9342  tet_el_pt->node_pt(2),
9343  tet_el_pt->node_pt(3));
9344  break;
9345 
9346  case 1:
9347  // Face 1: s[1]=0; opposite node 1
9348  face_pt = new TFace(tet_el_pt->node_pt(0),
9349  tet_el_pt->node_pt(2),
9350  tet_el_pt->node_pt(3));
9351 
9352  break;
9353 
9354 
9355  case 2:
9356  // Face 2: s[2]=0; opposite node 2
9357  face_pt = new TFace(tet_el_pt->node_pt(0),
9358  tet_el_pt->node_pt(1),
9359  tet_el_pt->node_pt(3));
9360 
9361  break;
9362 
9363  case 3:
9364  // Face 3: s[0]+s[1]+s[2]=1; opposite node 3
9365  face_pt = new TFace(tet_el_pt->node_pt(0),
9366  tet_el_pt->node_pt(1),
9367  tet_el_pt->node_pt(2));
9368  break;
9369  }
9370 
9371 
9372  if (face_pt->is_boundary_face())
9373  {
9374  std::set<unsigned> bnd;
9375  std::set<unsigned>* bnd_pt = &bnd;
9376  face_pt->get_boundaries_pt(bnd_pt);
9377 
9378 #ifdef PARANOID
9379  if ((*bnd_pt).size() > 1)
9380  {
9381  std::ostringstream error_stream;
9382  error_stream << "TFace should only be on one boundary.\n";
9383  throw OomphLibError(error_stream.str(),
9386  }
9387 #endif
9388 
9389  if ((*bnd_pt).size() == 1)
9390  {
9391  // Create new face element
9392  FaceElement* face_el_pt = 0;
9393  if (tet_mesh_is_solid_mesh)
9394  {
9395 #ifdef PARANOID
9396  if (dynamic_cast<SolidTElement<3, 3>*>(tet_el_pt) == 0)
9397  {
9398  std::ostringstream error_stream;
9399  error_stream
9400  << "Tet-element cannot be cast to SolidTElement<3,3>.\n"
9401  << "BrickFromTetMesh can only be built from\n"
9402  << "mesh containing quadratic tets.\n"
9403  << std::endl;
9404  throw OomphLibError(error_stream.str(),
9407  }
9408 #endif
9409  // Build the face element
9410  face_el_pt = new DummyFaceElement<SolidTElement<3, 3>>(
9411  tet_el_pt, face_index);
9412  }
9413  else
9414  {
9415 #ifdef PARANOID
9416  if (dynamic_cast<TElement<3, 3>*>(tet_el_pt) == 0)
9417  {
9418  std::ostringstream error_stream;
9419  error_stream << "Tet-element cannot be cast to TElement<3,3>.\n"
9420  << "BrickFromTetMesh can only be built from\n"
9421  << "mesh containing quadratic tets.\n"
9422  << std::endl;
9423  throw OomphLibError(error_stream.str(),
9426  }
9427 #endif
9428 
9429  // Build the face element
9430  face_el_pt =
9431  new DummyFaceElement<TElement<3, 3>>(tet_el_pt, face_index);
9432  }
9433 
9434 
9435  // Specify boundary id in bulk mesh (needed to extract
9436  // boundary coordinate)
9437  unsigned b = (*(*bnd_pt).begin());
9438  Boundary_coordinate_exists[b] = true;
9439  face_el_pt->set_boundary_number_in_bulk_mesh(b);
9440 
9441  // Now set up the brick nodes on this face, enumerated as
9442  // in s_face
9443  Vector<Node*> brick_face_node_pt(19);
9444 
9445  switch (face_index)
9446  {
9447  case 0:
9448  brick_face_node_pt[0] = brick_el1_pt->node_pt(0);
9449  brick_face_node_pt[1] = brick_el3_pt->node_pt(0);
9450  brick_face_node_pt[2] = brick_el2_pt->node_pt(0);
9451 
9452  brick_face_node_pt[3] = brick_el1_pt->node_pt(18);
9453  brick_face_node_pt[4] = brick_el2_pt->node_pt(18);
9454  brick_face_node_pt[5] = brick_el1_pt->node_pt(2);
9455 
9456  brick_face_node_pt[6] = brick_el1_pt->node_pt(9);
9457  brick_face_node_pt[7] = brick_el3_pt->node_pt(1);
9458  brick_face_node_pt[8] = brick_el3_pt->node_pt(9);
9459 
9460  brick_face_node_pt[9] = brick_el2_pt->node_pt(9);
9461  brick_face_node_pt[10] = brick_el2_pt->node_pt(3);
9462  brick_face_node_pt[11] = brick_el1_pt->node_pt(1);
9463 
9464  brick_face_node_pt[12] = brick_el1_pt->node_pt(20);
9465 
9466  brick_face_node_pt[13] = brick_el2_pt->node_pt(12);
9467  brick_face_node_pt[14] = brick_el1_pt->node_pt(19);
9468 
9469  brick_face_node_pt[15] = brick_el1_pt->node_pt(10);
9470  brick_face_node_pt[16] = brick_el2_pt->node_pt(21);
9471 
9472  brick_face_node_pt[17] = brick_el3_pt->node_pt(10);
9473  brick_face_node_pt[18] = brick_el1_pt->node_pt(11);
9474  break;
9475 
9476  case 1:
9477  brick_face_node_pt[0] = brick_el0_pt->node_pt(0);
9478  brick_face_node_pt[1] = brick_el3_pt->node_pt(0);
9479  brick_face_node_pt[2] = brick_el2_pt->node_pt(0);
9480 
9481  brick_face_node_pt[3] = brick_el0_pt->node_pt(18);
9482  brick_face_node_pt[4] = brick_el2_pt->node_pt(18);
9483  brick_face_node_pt[5] = brick_el0_pt->node_pt(6);
9484 
9485  brick_face_node_pt[6] = brick_el0_pt->node_pt(9);
9486  brick_face_node_pt[7] = brick_el3_pt->node_pt(3);
9487  brick_face_node_pt[8] = brick_el3_pt->node_pt(9);
9488 
9489  brick_face_node_pt[9] = brick_el2_pt->node_pt(9);
9490  brick_face_node_pt[10] = brick_el2_pt->node_pt(1);
9491  brick_face_node_pt[11] = brick_el0_pt->node_pt(3);
9492 
9493  brick_face_node_pt[12] = brick_el0_pt->node_pt(24);
9494 
9495  brick_face_node_pt[13] = brick_el2_pt->node_pt(10);
9496  brick_face_node_pt[14] = brick_el0_pt->node_pt(21);
9497 
9498  brick_face_node_pt[15] = brick_el0_pt->node_pt(12);
9499  brick_face_node_pt[16] = brick_el3_pt->node_pt(21);
9500 
9501  brick_face_node_pt[17] = brick_el3_pt->node_pt(12);
9502  brick_face_node_pt[18] = brick_el0_pt->node_pt(15);
9503  break;
9504 
9505  case 2:
9506  brick_face_node_pt[0] = brick_el0_pt->node_pt(0);
9507  brick_face_node_pt[1] = brick_el1_pt->node_pt(0);
9508  brick_face_node_pt[2] = brick_el2_pt->node_pt(0);
9509 
9510  brick_face_node_pt[3] = brick_el0_pt->node_pt(2);
9511  brick_face_node_pt[4] = brick_el1_pt->node_pt(2);
9512  brick_face_node_pt[5] = brick_el0_pt->node_pt(6);
9513 
9514  brick_face_node_pt[6] = brick_el0_pt->node_pt(1);
9515  brick_face_node_pt[7] = brick_el1_pt->node_pt(3);
9516  brick_face_node_pt[8] = brick_el1_pt->node_pt(1);
9517 
9518  brick_face_node_pt[9] = brick_el2_pt->node_pt(3);
9519  brick_face_node_pt[10] = brick_el2_pt->node_pt(1);
9520  brick_face_node_pt[11] = brick_el0_pt->node_pt(3);
9521 
9522  brick_face_node_pt[12] = brick_el0_pt->node_pt(8);
9523 
9524  brick_face_node_pt[13] = brick_el2_pt->node_pt(4);
9525  brick_face_node_pt[14] = brick_el0_pt->node_pt(5);
9526 
9527  brick_face_node_pt[15] = brick_el0_pt->node_pt(4);
9528  brick_face_node_pt[16] = brick_el1_pt->node_pt(5);
9529 
9530  brick_face_node_pt[17] = brick_el1_pt->node_pt(4);
9531  brick_face_node_pt[18] = brick_el0_pt->node_pt(7);
9532  break;
9533 
9534  case 3:
9535  brick_face_node_pt[0] = brick_el1_pt->node_pt(0);
9536  brick_face_node_pt[1] = brick_el3_pt->node_pt(0);
9537  brick_face_node_pt[2] = brick_el0_pt->node_pt(0);
9538 
9539  brick_face_node_pt[3] = brick_el1_pt->node_pt(18);
9540  brick_face_node_pt[4] = brick_el3_pt->node_pt(6);
9541  brick_face_node_pt[5] = brick_el1_pt->node_pt(6);
9542 
9543  brick_face_node_pt[6] = brick_el1_pt->node_pt(9);
9544  brick_face_node_pt[7] = brick_el3_pt->node_pt(1);
9545  brick_face_node_pt[8] = brick_el3_pt->node_pt(3);
9546 
9547  brick_face_node_pt[9] = brick_el0_pt->node_pt(9);
9548  brick_face_node_pt[10] = brick_el0_pt->node_pt(1);
9549  brick_face_node_pt[11] = brick_el1_pt->node_pt(3);
9550 
9551  brick_face_node_pt[12] = brick_el1_pt->node_pt(24);
9552 
9553  brick_face_node_pt[13] = brick_el0_pt->node_pt(10);
9554  brick_face_node_pt[14] = brick_el1_pt->node_pt(21);
9555 
9556  brick_face_node_pt[15] = brick_el1_pt->node_pt(12);
9557  brick_face_node_pt[16] = brick_el3_pt->node_pt(7);
9558 
9559  brick_face_node_pt[17] = brick_el3_pt->node_pt(4);
9560  brick_face_node_pt[18] = brick_el1_pt->node_pt(15);
9561  break;
9562  }
9563 
9564  // Provide possibility for translation -- may need to add
9565  // face index to this; see ThinLayerBrickOnTetMesh.
9566  Vector<unsigned> translate(19);
9567 
9568  // Initialise with identity mapping
9569  for (unsigned i = 0; i < 19; i++)
9570  {
9571  translate[i] = i;
9572  }
9573 
9574  // Visit all the nodes on that face
9575  for (unsigned j = 0; j < 19; j++)
9576  {
9577  // Which node is it?
9578  Node* brick_node_pt = brick_face_node_pt[translate[j]];
9579 
9580  // Get coordinates etc of point from face
9581  Vector<double> s = s_face[j];
9582  Vector<double> zeta(2);
9583  Vector<double> x(3);
9584  face_el_pt->interpolated_zeta(s, zeta);
9585  face_el_pt->interpolated_x(s, x);
9586 
9587 #ifdef PARANOID
9588  // Check that the coordinates match (within tolerance)
9589  double dist = sqrt(pow(brick_node_pt->x(0) - x[0], 2) +
9590  pow(brick_node_pt->x(1) - x[1], 2) +
9591  pow(brick_node_pt->x(2) - x[2], 2));
9593  {
9594  std::ofstream brick0;
9595  std::ofstream brick1;
9596  std::ofstream brick2;
9597  std::ofstream brick3;
9598  brick0.open("full_brick0.dat");
9599  brick1.open("full_brick1.dat");
9600  brick2.open("full_brick2.dat");
9601  brick3.open("full_brick3.dat");
9602  for (unsigned j = 0; j < 27; j++)
9603  {
9604  brick0 << brick_el0_pt->node_pt(j)->x(0) << " "
9605  << brick_el0_pt->node_pt(j)->x(1) << " "
9606  << brick_el0_pt->node_pt(j)->x(2) << "\n";
9607 
9608  brick1 << brick_el1_pt->node_pt(j)->x(0) << " "
9609  << brick_el1_pt->node_pt(j)->x(1) << " "
9610  << brick_el1_pt->node_pt(j)->x(2) << "\n";
9611 
9612  brick2 << brick_el2_pt->node_pt(j)->x(0) << " "
9613  << brick_el2_pt->node_pt(j)->x(1) << " "
9614  << brick_el2_pt->node_pt(j)->x(2) << "\n";
9615 
9616  brick3 << brick_el3_pt->node_pt(j)->x(0) << " "
9617  << brick_el3_pt->node_pt(j)->x(1) << " "
9618  << brick_el3_pt->node_pt(j)->x(2) << "\n";
9619  }
9620  brick0.close();
9621  brick1.close();
9622  brick2.close();
9623  brick3.close();
9624 
9625  std::ofstream full_face;
9626  full_face.open("full_face.dat");
9627  for (unsigned j = 0; j < 6; j++)
9628  {
9629  full_face << face_el_pt->node_pt(j)->x(0) << " "
9630  << face_el_pt->node_pt(j)->x(1) << " "
9631  << face_el_pt->node_pt(j)->x(2) << "\n";
9632  }
9633  full_face.close();
9634 
9635  // Get normal sign
9636  int normal_sign = face_el_pt->normal_sign();
9637 
9638  std::ostringstream error_stream;
9639  error_stream
9640  << "During assignment of boundary cordinates, the distance\n"
9641  << "between brick node and reference point in \n"
9642  << "triangular FaceElement is " << dist << " which \n"
9643  << "is bigger than the tolerance defined in \n"
9644  << "BrickFromTetMeshHelper::Face_position_tolerance="
9646  << "If this is tolerable, increase the tolerance \n"
9647  << "(it's defined in a namespace and therefore publically\n"
9648  << "accessible). If not, the Face may be inverted in which \n"
9649  << "case you should re-implement the translation scheme,\n"
9650  << "following the pattern used in the "
9651  "ThinLayerBrickOnTetMesh."
9652  << "\nThe required code fragements are already here but \n"
9653  << "the translation is the unit map.\n"
9654  << "To aid the diagnostics, the files full_brick[0-3].dat\n"
9655  << "contain the coordinates of the 27 nodes in the four\n"
9656  << "bricks associated with the current tet and "
9657  "full_face.dat\n"
9658  << "contains the coordinates of the 6 nodes in the "
9659  "FaceElement"
9660  << "\nfrom which the boundary coordinates are extracted.\n"
9661  << "FYI: The normal_sign of the face is: " << normal_sign
9662  << std::endl;
9663  throw OomphLibError(error_stream.str(),
9666  }
9667 #endif
9668 
9669  // Set boundary stuff
9670  add_boundary_node(b, brick_node_pt);
9671  brick_node_pt->set_coordinates_on_boundary(b, zeta);
9672  }
9673 
9674  // Add appropriate brick elements to boundary lookup scheme
9675  switch (face_index)
9676  {
9677  case 0:
9678  Boundary_element_pt[b].push_back(brick_el1_pt);
9679  Face_index_at_boundary[b].push_back(-2);
9680  Boundary_element_pt[b].push_back(brick_el2_pt);
9681  Face_index_at_boundary[b].push_back(-1);
9682  Boundary_element_pt[b].push_back(brick_el3_pt);
9683  Face_index_at_boundary[b].push_back(-2);
9684  break;
9685 
9686  case 1:
9687  Boundary_element_pt[b].push_back(brick_el0_pt);
9688  Face_index_at_boundary[b].push_back(-1);
9689  Boundary_element_pt[b].push_back(brick_el2_pt);
9690  Face_index_at_boundary[b].push_back(-2);
9691  Boundary_element_pt[b].push_back(brick_el3_pt);
9692  Face_index_at_boundary[b].push_back(-1);
9693  break;
9694 
9695  case 2:
9696  Boundary_element_pt[b].push_back(brick_el0_pt);
9697  Face_index_at_boundary[b].push_back(-3);
9698  Boundary_element_pt[b].push_back(brick_el1_pt);
9699  Face_index_at_boundary[b].push_back(-3);
9700  Boundary_element_pt[b].push_back(brick_el2_pt);
9701  Face_index_at_boundary[b].push_back(-3);
9702  break;
9703 
9704  case 3:
9705  Boundary_element_pt[b].push_back(brick_el0_pt);
9706  Face_index_at_boundary[b].push_back(-2);
9707  Boundary_element_pt[b].push_back(brick_el1_pt);
9708  Face_index_at_boundary[b].push_back(-1);
9709  Boundary_element_pt[b].push_back(brick_el3_pt);
9710  Face_index_at_boundary[b].push_back(-3);
9711  break;
9712  }
9713  // Cleanup
9714  delete face_el_pt;
9715  }
9716  }
9717  // Cleanup
9718  delete face_pt;
9719  }
9720  }
9721 
9722  // Lookup scheme has now been setup
9724 
9725  // Get number of distinct boundaries specified
9726  // in the original xda enumeration.
9727  // unsigned n_xda_boundaries=tet_mesh_pt->nboundary();
9728 
9729  // Copy collective IDs across
9730  // Boundary_id.resize(n_xda_boundaries);
9731  // for (unsigned xda_b=0;xda_b<n_xda_boundaries;xda_b++)
9732  // {
9733  // //Boundary_id[xda_b]=tet_mesh_pt->oomph_lib_boundary_ids(xda_b);
9734  // Boundary_id[xda_b]=xda_b;
9735  // }
9736 
9737 
9738  // Cleanup
9739  for (unsigned e = 0; e < 4; e++)
9740  {
9741  for (unsigned j = 0; j < 8; j++)
9742  {
9743  delete dummy_q_el_pt[e]->node_pt(j);
9744  }
9745  delete dummy_q_el_pt[e];
9746  }
9747  }
AnnoyingScalar sqrt(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:134
int i
Definition: BiCGSTAB_step_by_step.cpp:9
Array< double, 1, 3 > e(1./3., 0.5, 2.)
Scalar * b
Definition: benchVecAdd.cpp:17
void add_boundary_node(const unsigned &b, Node *const &node_pt)
Add a (pointer to) a node to the b-th boundary.
Definition: mesh.cc:243
Vector< Node * > Node_pt
Vector of pointers to nodes.
Definition: mesh.h:183
Vector< Vector< FiniteElement * > > Boundary_element_pt
Definition: mesh.h:91
bool Lookup_for_elements_next_boundary_is_setup
Definition: mesh.h:87
std::vector< bool > Boundary_coordinate_exists
Definition: mesh.h:190
Vector< Vector< int > > Face_index_at_boundary
Definition: mesh.h:95
void set_nboundary(const unsigned &nbound)
Set the number of boundaries in the mesh.
Definition: mesh.h:505
Vector< GeneralisedElement * > Element_pt
Vector of pointers to generalised elements.
Definition: mesh.h:186
RealScalar s
Definition: level1_cplx_impl.h:130
int nb
Definition: level2_impl.h:286
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 pow(const bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:625
EIGEN_STRONG_INLINE const Eigen::CwiseBinaryOp< Eigen::internal::scalar_zeta_op< typename DerivedX::Scalar >, const DerivedX, const DerivedQ > zeta(const Eigen::ArrayBase< DerivedX > &x, const Eigen::ArrayBase< DerivedQ > &q)
Definition: SpecialFunctionsArrayAPI.h:152
double Face_position_tolerance
Tolerance for mismatch during setup of boundary coordinates.
Definition: brick_mesh.cc:37
void face1(const Vector< double > &s, Vector< double > &s_bulk)
The translation scheme for the face s0 = 1.0.
Definition: Qelement_face_coordinate_translation_schemes.cc:44
void face0(const Vector< double > &s, Vector< double > &s_bulk)
The translation scheme for the face s0 = -1.0.
Definition: Qelement_face_coordinate_translation_schemes.cc:38
void face2(const Vector< double > &s, Vector< double > &s_bulk)
The translation scheme for the east face (s0 = 1.0)
Definition: Qelement_face_coordinate_translation_schemes.cc:93
list x
Definition: plotDoE.py:28
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2

References b, oomph::FiniteElement::construct_boundary_node(), oomph::FiniteElement::construct_node(), e(), oomph::QElement1FaceToBulkCoordinates::face0(), oomph::QElement1FaceToBulkCoordinates::face1(), oomph::QElement2FaceToBulkCoordinates::face2(), oomph::BrickFromTetMeshHelper::Face_position_tolerance, oomph::TFace::get_boundaries_pt(), i, oomph::FaceElement::interpolated_x(), oomph::FiniteElement::interpolated_zeta(), oomph::Edge::is_boundary_edge(), oomph::TFace::is_boundary_face(), oomph::Node::is_on_boundary(), j, oomph::FiniteElement::local_coordinate_of_node(), nb, oomph::FiniteElement::node_pt(), oomph::FaceElement::normal_sign(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, Eigen::bfloat16_impl::pow(), s, oomph::FaceElement::set_boundary_number_in_bulk_mesh(), oomph::Node::set_coordinates_on_boundary(), oomph::Data::set_value(), sqrt(), plotDoE::x, oomph::Node::x(), and Eigen::zeta().

◆ build_mesh() [2/2]

template<class ELEMENT >
void oomph::BrickFromTetMesh< ELEMENT >::build_mesh ( XdaTetMesh< TElement< 3, 3 >> *  tet_mesh_pt,
TimeStepper time_stepper_pt 
)
private

Build fct: Pass pointer to existing tet mesh.

Build fct: Pass pointer to existing tet mesh and timestepper Specialisation for XdaTetMesh<TElement<3,3> >

41  {
42  // Mesh can only be built with 3D Qelements.
43  MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(3, 3);
44 
45  // Figure out if the tet mesh is a solid mesh
46  bool tet_mesh_is_solid_mesh = false;
47  if (dynamic_cast<SolidFiniteElement*>(tet_mesh_pt->element_pt(0)) != 0)
48  {
49  tet_mesh_is_solid_mesh = true;
50  }
51 
52  // Setup lookup scheme for local coordinates on triangular faces.
53  // The local coordinates identify the points on the triangular
54  // FaceElements on which we place the bottom layer of the
55  // brick nodes.
56  Vector<Vector<double>> s_face(19);
57  for (unsigned i = 0; i < 19; i++)
58  {
59  s_face[i].resize(2);
60 
61  switch (i)
62  {
63  // Vertex nodes
64 
65  case 0:
66  s_face[i][0] = 1.0;
67  s_face[i][1] = 0.0;
68  break;
69 
70  case 1:
71  s_face[i][0] = 0.0;
72  s_face[i][1] = 1.0;
73  break;
74 
75  case 2:
76  s_face[i][0] = 0.0;
77  s_face[i][1] = 0.0;
78  break;
79 
80  // Midside nodes
81 
82  case 3:
83  s_face[i][0] = 0.5;
84  s_face[i][1] = 0.5;
85  break;
86 
87  case 4:
88  s_face[i][0] = 0.0;
89  s_face[i][1] = 0.5;
90  break;
91 
92  case 5:
93  s_face[i][0] = 0.5;
94  s_face[i][1] = 0.0;
95  break;
96 
97 
98  // Quarter side nodes
99 
100  case 6:
101  s_face[i][0] = 0.75;
102  s_face[i][1] = 0.25;
103  break;
104 
105  case 7:
106  s_face[i][0] = 0.25;
107  s_face[i][1] = 0.75;
108  break;
109 
110  case 8:
111  s_face[i][0] = 0.0;
112  s_face[i][1] = 0.75;
113  break;
114 
115  case 9:
116  s_face[i][0] = 0.0;
117  s_face[i][1] = 0.25;
118  break;
119 
120  case 10:
121  s_face[i][0] = 0.25;
122  s_face[i][1] = 0.0;
123  break;
124 
125  case 11:
126  s_face[i][0] = 0.75;
127  s_face[i][1] = 0.0;
128  break;
129 
130  // Central node
131 
132  case 12:
133  s_face[i][0] = 1.0 / 3.0;
134  s_face[i][1] = 1.0 / 3.0;
135  break;
136 
137 
138  // Vertical internal midside nodes connecting 2 and 3
139 
140  case 13:
141  s_face[i][0] = 5.0 / 24.0;
142  s_face[i][1] = 5.0 / 24.0;
143  break;
144 
145  case 14:
146  s_face[i][0] = 5.0 / 12.0;
147  s_face[i][1] = 5.0 / 12.0;
148  break;
149 
150  // Internal midside nodes connecting nodes 0 and 4
151 
152  case 15:
153  s_face[i][1] = 5.0 / 24.0;
154  s_face[i][0] = 7.0 / 12.0; // 1.0-2.0*5.0/24.0;
155  break;
156 
157  case 16:
158  s_face[i][1] = 5.0 / 12.0;
159  s_face[i][0] = 1.0 / 6.0; // 1.0-2.0*5.0/12.0;
160  break;
161 
162 
163  // Internal midside nodes connecting nodes 1 and 5
164 
165  case 17:
166  s_face[i][0] = 5.0 / 24.0;
167  s_face[i][1] = 7.0 / 12.0; // 1.0-2.0*5.0/24.0;
168  break;
169 
170  case 18:
171  s_face[i][0] = 5.0 / 12.0;
172  s_face[i][1] = 1.0 / 6.0; // 1.0-2.0*5.0/12.0;
173  break;
174  }
175  }
176 
177  // Set number of boundaries
178  unsigned nb = tet_mesh_pt->nboundary();
179  set_nboundary(nb);
180 
181  // Get ready for boundary lookup scheme
182  Boundary_element_pt.resize(nb);
183  Face_index_at_boundary.resize(nb);
184 
185  // Maps to check which nodes have already been done
186 
187  // Map that stores the new brick node corresponding to an existing tet node
188  std::map<Node*, Node*> tet_node_node_pt;
189 
190  // Map that stores node on an edge between two brick nodes
191  std::map<Edge, Node*> brick_edge_node_pt;
192 
193  // Map that stores node on face spanned by three tet nodes
194  std::map<TFace, Node*> tet_face_node_pt;
195 
196  // Create the four Dummy bricks:
197  //------------------------------
198  Vector<DummyBrickElement*> dummy_q_el_pt(4);
199  for (unsigned e = 0; e < 4; e++)
200  {
201  dummy_q_el_pt[e] = new DummyBrickElement;
202  for (unsigned j = 0; j < 8; j++)
203  {
204  dummy_q_el_pt[e]->construct_node(j);
205  }
206  }
207 
208  // Loop over the elements in the tet mesh
209  unsigned n_el_tet = tet_mesh_pt->nelement();
210  for (unsigned e_tet = 0; e_tet < n_el_tet; e_tet++)
211  {
212  // Cast to ten-noded tet
213  TElement<3, 3>* tet_el_pt =
214  dynamic_cast<TElement<3, 3>*>(tet_mesh_pt->element_pt(e_tet));
215 
216 #ifdef PARANOID
217  if (tet_el_pt == 0)
218  {
219  std::ostringstream error_stream;
220  error_stream
221  << "BrickFromTetMesh can only built from tet mesh containing\n"
222  << "ten-noded tets.\n";
223  throw OomphLibError(
224  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
225  }
226 #endif
227 
228  // Storage for the centroid node for this tet
229  Node* centroid_node_pt = 0;
230 
231  // Internal mid brick-face nodes
232  Node* top_mid_face_node0_pt = 0;
233  Node* right_mid_face_node0_pt = 0;
234  Node* back_mid_face_node0_pt = 0;
235 
236  Node* top_mid_face_node1_pt = 0;
237  Node* right_mid_face_node1_pt = 0;
238 
239  Node* top_mid_face_node2_pt = 0;
240 
241  // Newly created brick elements
242  FiniteElement* brick_el0_pt = 0;
243  FiniteElement* brick_el1_pt = 0;
244  FiniteElement* brick_el2_pt = 0;
245  FiniteElement* brick_el3_pt = 0;
246 
247 
248  // First brick element is centred at node 0 of tet:
249  //-------------------------------------------------
250  {
251  // Assign coordinates of dummy element
252  for (unsigned j = 0; j < 8; j++)
253  {
254  Node* nod_pt = dummy_q_el_pt[0]->node_pt(j);
255  Vector<double> s_tet(3);
256  Vector<double> x_tet(3);
257  switch (j)
258  {
259  case 0:
260  tet_el_pt->local_coordinate_of_node(0, s_tet);
261  nod_pt->set_value(0, s_tet[0]);
262  nod_pt->set_value(1, s_tet[1]);
263  nod_pt->set_value(2, s_tet[2]);
264  tet_el_pt->interpolated_x(s_tet, x_tet);
265  nod_pt->x(0) = x_tet[0];
266  nod_pt->x(1) = x_tet[1];
267  nod_pt->x(2) = x_tet[2];
268  break;
269  case 1:
270  tet_el_pt->local_coordinate_of_node(4, s_tet);
271  nod_pt->set_value(0, s_tet[0]);
272  nod_pt->set_value(1, s_tet[1]);
273  nod_pt->set_value(2, s_tet[2]);
274  tet_el_pt->interpolated_x(s_tet, x_tet);
275  nod_pt->x(0) = x_tet[0];
276  nod_pt->x(1) = x_tet[1];
277  nod_pt->x(2) = x_tet[2];
278  break;
279  case 2:
280  tet_el_pt->local_coordinate_of_node(6, s_tet);
281  nod_pt->set_value(0, s_tet[0]);
282  nod_pt->set_value(1, s_tet[1]);
283  nod_pt->set_value(2, s_tet[2]);
284  tet_el_pt->interpolated_x(s_tet, x_tet);
285  nod_pt->x(0) = x_tet[0];
286  nod_pt->x(1) = x_tet[1];
287  nod_pt->x(2) = x_tet[2];
288  break;
289  case 3:
290  // label 13 in initial sketch: Mid face node on face spanned by
291  // tet nodes 0,1,3
292  s_tet[0] = 1.0 / 3.0;
293  s_tet[1] = 1.0 / 3.0;
294  s_tet[2] = 0.0;
295  nod_pt->set_value(0, s_tet[0]);
296  nod_pt->set_value(1, s_tet[1]);
297  nod_pt->set_value(2, s_tet[2]);
298  tet_el_pt->interpolated_x(s_tet, x_tet);
299  nod_pt->x(0) = x_tet[0];
300  nod_pt->x(1) = x_tet[1];
301  nod_pt->x(2) = x_tet[2];
302  break;
303  case 4:
304  tet_el_pt->local_coordinate_of_node(5, s_tet);
305  nod_pt->set_value(0, s_tet[0]);
306  nod_pt->set_value(1, s_tet[1]);
307  nod_pt->set_value(2, s_tet[2]);
308  tet_el_pt->interpolated_x(s_tet, x_tet);
309  nod_pt->x(0) = x_tet[0];
310  nod_pt->x(1) = x_tet[1];
311  nod_pt->x(2) = x_tet[2];
312  break;
313  case 5:
314  // label 11 in initial sketch: Mid face node on face spanned
315  // by tet nodes 0,1,2
316  s_tet[0] = 1.0 / 3.0;
317  s_tet[1] = 1.0 / 3.0;
318  s_tet[2] = 1.0 / 3.0;
319  nod_pt->set_value(0, s_tet[0]);
320  nod_pt->set_value(1, s_tet[1]);
321  nod_pt->set_value(2, s_tet[2]);
322  tet_el_pt->interpolated_x(s_tet, x_tet);
323  nod_pt->x(0) = x_tet[0];
324  nod_pt->x(1) = x_tet[1];
325  nod_pt->x(2) = x_tet[2];
326  break;
327  case 6:
328  // label 12 in initial sketch: Mid face node on face
329  // spanned by tet nodes 0,2,3
330  s_tet[0] = 1.0 / 3.0;
331  s_tet[1] = 0.0;
332  s_tet[2] = 1.0 / 3.0;
333  nod_pt->set_value(0, s_tet[0]);
334  nod_pt->set_value(1, s_tet[1]);
335  nod_pt->set_value(2, s_tet[2]);
336  tet_el_pt->interpolated_x(s_tet, x_tet);
337  nod_pt->x(0) = x_tet[0];
338  nod_pt->x(1) = x_tet[1];
339  nod_pt->x(2) = x_tet[2];
340  break;
341  case 7:
342  // label 14 in initial sketch: Centroid
343  s_tet[0] = 0.25;
344  s_tet[1] = 0.25;
345  s_tet[2] = 0.25;
346  nod_pt->set_value(0, s_tet[0]);
347  nod_pt->set_value(1, s_tet[1]);
348  nod_pt->set_value(2, s_tet[2]);
349  tet_el_pt->interpolated_x(s_tet, x_tet);
350  nod_pt->x(0) = x_tet[0];
351  nod_pt->x(1) = x_tet[1];
352  nod_pt->x(2) = x_tet[2];
353  break;
354  }
355  }
356 
357 
358  // Create actual zeroth brick element
359  FiniteElement* el_pt = new ELEMENT;
360  brick_el0_pt = el_pt;
361  Element_pt.push_back(el_pt);
362 
363  TFace face0(
364  tet_el_pt->node_pt(0), tet_el_pt->node_pt(1), tet_el_pt->node_pt(2));
365 
366  TFace face1(
367  tet_el_pt->node_pt(0), tet_el_pt->node_pt(2), tet_el_pt->node_pt(3));
368 
369  TFace face2(
370  tet_el_pt->node_pt(0), tet_el_pt->node_pt(1), tet_el_pt->node_pt(3));
371 
372 
373  // Tet vertex nodes along edges emanating from node 0 in brick
374  Vector<Vector<unsigned>> tet_edge_node(3);
375  tet_edge_node[0].resize(2);
376  tet_edge_node[0][0] = 4;
377  tet_edge_node[0][1] = 1;
378  tet_edge_node[1].resize(2);
379  tet_edge_node[1][0] = 6;
380  tet_edge_node[1][1] = 3;
381  tet_edge_node[2].resize(2);
382  tet_edge_node[2][0] = 5;
383  tet_edge_node[2][1] = 2;
384 
385  // Node number of tet vertex that node 0 in brick is centred on
386  unsigned central_tet_vertex = 0;
387 
388  Node* tet_node_pt = 0;
389  Node* old_node_pt = 0;
390 
391  // Corner node
392  {
393  unsigned j = 0;
394 
395  // Need new node?
396  tet_node_pt = tet_el_pt->node_pt(central_tet_vertex);
397  old_node_pt = tet_node_node_pt[tet_node_pt];
398  if (old_node_pt == 0)
399  {
400  Node* new_node_pt = 0;
401  if (tet_node_pt->is_on_boundary())
402  {
403  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
404  }
405  else
406  {
407  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
408  }
409  tet_node_node_pt[tet_node_pt] = new_node_pt;
410  Node_pt.push_back(new_node_pt);
411  Vector<double> s(3);
412  Vector<double> s_tet(3);
413  Vector<double> x_tet(3);
414  el_pt->local_coordinate_of_node(j, s);
415  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
416  tet_el_pt->interpolated_x(s_tet, x_tet);
417  new_node_pt->x(0) = x_tet[0];
418  new_node_pt->x(1) = x_tet[1];
419  new_node_pt->x(2) = x_tet[2];
420  }
421  // Node already exists
422  else
423  {
424  el_pt->node_pt(j) = old_node_pt;
425  }
426  }
427 
428 
429  // Brick vertex node coindides with mid-edge node on tet edge 0
430  {
431  unsigned j = 2;
432 
433  // Need new node?
434  tet_node_pt = tet_el_pt->node_pt(tet_edge_node[0][0]);
435  old_node_pt = tet_node_node_pt[tet_node_pt];
436  if (old_node_pt == 0)
437  {
438  Node* new_node_pt = 0;
439  if (tet_node_pt->is_on_boundary())
440  {
441  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
442  }
443  else
444  {
445  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
446  }
447  tet_node_node_pt[tet_node_pt] = new_node_pt;
448  Node_pt.push_back(new_node_pt);
449  Vector<double> s(3);
450  Vector<double> s_tet(3);
451  Vector<double> x_tet(3);
452  el_pt->local_coordinate_of_node(j, s);
453  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
454  tet_el_pt->interpolated_x(s_tet, x_tet);
455  new_node_pt->x(0) = x_tet[0];
456  new_node_pt->x(1) = x_tet[1];
457  new_node_pt->x(2) = x_tet[2];
458  }
459  // Node already exists
460  else
461  {
462  el_pt->node_pt(j) = old_node_pt;
463  }
464  }
465 
466 
467  // Brick vertex node coindides with mid vertex node of tet edge 1
468  {
469  unsigned j = 6;
470 
471  // Need new node?
472  tet_node_pt = tet_el_pt->node_pt(tet_edge_node[1][0]);
473  old_node_pt = tet_node_node_pt[tet_node_pt];
474  if (old_node_pt == 0)
475  {
476  Node* new_node_pt = 0;
477  if (tet_node_pt->is_on_boundary())
478  {
479  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
480  }
481  else
482  {
483  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
484  }
485  tet_node_node_pt[tet_node_pt] = new_node_pt;
486  Node_pt.push_back(new_node_pt);
487  Vector<double> s(3);
488  Vector<double> s_tet(3);
489  Vector<double> x_tet(3);
490  el_pt->local_coordinate_of_node(j, s);
491  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
492  tet_el_pt->interpolated_x(s_tet, x_tet);
493  new_node_pt->x(0) = x_tet[0];
494  new_node_pt->x(1) = x_tet[1];
495  new_node_pt->x(2) = x_tet[2];
496  }
497  // Node already exists
498  else
499  {
500  el_pt->node_pt(j) = old_node_pt;
501  }
502  }
503 
504 
505  // Brick vertex node coindides with mid-vertex node of tet edge 2
506  {
507  unsigned j = 18;
508 
509  // Need new node?
510  tet_node_pt = tet_el_pt->node_pt(tet_edge_node[2][0]);
511  old_node_pt = tet_node_node_pt[tet_node_pt];
512  if (old_node_pt == 0)
513  {
514  Node* new_node_pt = 0;
515  if (tet_node_pt->is_on_boundary())
516  {
517  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
518  }
519  else
520  {
521  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
522  }
523  tet_node_node_pt[tet_node_pt] = new_node_pt;
524  Node_pt.push_back(new_node_pt);
525  Vector<double> s(3);
526  Vector<double> s_tet(3);
527  Vector<double> x_tet(3);
528  el_pt->local_coordinate_of_node(j, s);
529  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
530  tet_el_pt->interpolated_x(s_tet, x_tet);
531  new_node_pt->x(0) = x_tet[0];
532  new_node_pt->x(1) = x_tet[1];
533  new_node_pt->x(2) = x_tet[2];
534  }
535  // Node already exists
536  else
537  {
538  el_pt->node_pt(j) = old_node_pt;
539  }
540  }
541 
542 
543  // Brick vertex node in the middle of tet face0, spanned by
544  // tet vertices 0, 1, 2. Enumerated "11" in initial sketch.
545  {
546  unsigned j = 20;
547 
548  // Need new node?
549  old_node_pt = tet_face_node_pt[face0];
550  if (old_node_pt == 0)
551  {
552  Node* new_node_pt = 0;
553  if (face0.is_boundary_face())
554  {
555  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
556  }
557  else
558  {
559  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
560  }
561  tet_face_node_pt[face0] = new_node_pt;
562  Node_pt.push_back(new_node_pt);
563  Vector<double> s(3);
564  Vector<double> s_tet(3);
565  Vector<double> x_tet(3);
566  el_pt->local_coordinate_of_node(j, s);
567  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
568  tet_el_pt->interpolated_x(s_tet, x_tet);
569  new_node_pt->x(0) = x_tet[0];
570  new_node_pt->x(1) = x_tet[1];
571  new_node_pt->x(2) = x_tet[2];
572  }
573  // Node already exists
574  else
575  {
576  el_pt->node_pt(j) = old_node_pt;
577  }
578  }
579 
580  // Brick vertex node in the middle of tet face1, spanned by
581  // tet vertices 0, 2, 3. Enumerated "12" in initial sketch.
582  {
583  unsigned j = 24;
584 
585  // Need new node?
586  old_node_pt = tet_face_node_pt[face1];
587  if (old_node_pt == 0)
588  {
589  Node* new_node_pt = 0;
590  if (face1.is_boundary_face())
591  {
592  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
593  }
594  else
595  {
596  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
597  }
598  tet_face_node_pt[face1] = new_node_pt;
599  Node_pt.push_back(new_node_pt);
600  Vector<double> s(3);
601  Vector<double> s_tet(3);
602  Vector<double> x_tet(3);
603  el_pt->local_coordinate_of_node(j, s);
604  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
605  tet_el_pt->interpolated_x(s_tet, x_tet);
606  new_node_pt->x(0) = x_tet[0];
607  new_node_pt->x(1) = x_tet[1];
608  new_node_pt->x(2) = x_tet[2];
609  }
610  // Node already exists
611  else
612  {
613  el_pt->node_pt(j) = old_node_pt;
614  }
615  }
616 
617  // Brick vertex node in the middle of tet face2, spanned by
618  // tet vertices 0, 1, 3. Enumerated "13" in initial sketch.
619  {
620  unsigned j = 8;
621 
622  // Need new node?
623  old_node_pt = tet_face_node_pt[face2];
624  if (old_node_pt == 0)
625  {
626  Node* new_node_pt = 0;
627  if (face2.is_boundary_face())
628  {
629  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
630  }
631  else
632  {
633  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
634  }
635  tet_face_node_pt[face2] = new_node_pt;
636  Node_pt.push_back(new_node_pt);
637  Vector<double> s(3);
638  Vector<double> s_tet(3);
639  Vector<double> x_tet(3);
640  el_pt->local_coordinate_of_node(j, s);
641  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
642  tet_el_pt->interpolated_x(s_tet, x_tet);
643  new_node_pt->x(0) = x_tet[0];
644  new_node_pt->x(1) = x_tet[1];
645  new_node_pt->x(2) = x_tet[2];
646  }
647  // Node already exists
648  else
649  {
650  el_pt->node_pt(j) = old_node_pt;
651  }
652  }
653 
654  // Brick vertex node in centroid of tet. Only built for first element.
655  // Enumerated "13" in initial sketch.
656  {
657  unsigned j = 26;
658 
659  // Always new
660  {
661  Node* new_node_pt = el_pt->construct_node(j, time_stepper_pt);
662  centroid_node_pt = new_node_pt;
663  Node_pt.push_back(new_node_pt);
664  Vector<double> s(3);
665  Vector<double> s_tet(3);
666  Vector<double> x_tet(3);
667  el_pt->local_coordinate_of_node(j, s);
668  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
669  tet_el_pt->interpolated_x(s_tet, x_tet);
670  new_node_pt->x(0) = x_tet[0];
671  new_node_pt->x(1) = x_tet[1];
672  new_node_pt->x(2) = x_tet[2];
673  }
674  }
675 
676 
677  // Internal brick node -- always built
678  {
679  unsigned j = 13;
680 
681  // Always new
682  {
683  Node* new_node_pt = el_pt->construct_node(j, time_stepper_pt);
684  Node_pt.push_back(new_node_pt);
685  Vector<double> s(3);
686  Vector<double> s_tet(3);
687  Vector<double> x_tet(3);
688  el_pt->local_coordinate_of_node(j, s);
689  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
690  tet_el_pt->interpolated_x(s_tet, x_tet);
691  new_node_pt->x(0) = x_tet[0];
692  new_node_pt->x(1) = x_tet[1];
693  new_node_pt->x(2) = x_tet[2];
694  }
695  }
696 
697  // Brick edge node between brick nodes 0 and 2
698  {
699  unsigned j = 1;
700 
701  // Need new node?
702  Edge edge(el_pt->node_pt(0), el_pt->node_pt(2));
703  old_node_pt = brick_edge_node_pt[edge];
704  if (old_node_pt == 0)
705  {
706  Node* new_node_pt = 0;
707  if (edge.is_boundary_edge())
708  {
709  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
710  }
711  else
712  {
713  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
714  }
715  brick_edge_node_pt[edge] = new_node_pt;
716  Node_pt.push_back(new_node_pt);
717  Vector<double> s(3);
718  Vector<double> s_tet(3);
719  Vector<double> x_tet(3);
720  el_pt->local_coordinate_of_node(j, s);
721  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
722  tet_el_pt->interpolated_x(s_tet, x_tet);
723  new_node_pt->x(0) = x_tet[0];
724  new_node_pt->x(1) = x_tet[1];
725  new_node_pt->x(2) = x_tet[2];
726  }
727  // Node already exists
728  else
729  {
730  el_pt->node_pt(j) = old_node_pt;
731  }
732  }
733 
734 
735  // Brick edge node between brick nodes 0 and 6
736  {
737  unsigned j = 3;
738 
739  // Need new node?
740  Edge edge(el_pt->node_pt(0), el_pt->node_pt(6));
741  old_node_pt = brick_edge_node_pt[edge];
742  if (old_node_pt == 0)
743  {
744  Node* new_node_pt = 0;
745  if (edge.is_boundary_edge())
746  {
747  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
748  }
749  else
750  {
751  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
752  }
753  brick_edge_node_pt[edge] = new_node_pt;
754  Node_pt.push_back(new_node_pt);
755  Vector<double> s(3);
756  Vector<double> s_tet(3);
757  Vector<double> x_tet(3);
758  el_pt->local_coordinate_of_node(j, s);
759  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
760  tet_el_pt->interpolated_x(s_tet, x_tet);
761  new_node_pt->x(0) = x_tet[0];
762  new_node_pt->x(1) = x_tet[1];
763  new_node_pt->x(2) = x_tet[2];
764  }
765  // Node already exists
766  else
767  {
768  el_pt->node_pt(j) = old_node_pt;
769  }
770  }
771 
772  // Brick edge node between brick nodes 2 and 8
773  {
774  unsigned j = 5;
775 
776  // Need new node?
777  Edge edge(el_pt->node_pt(2), el_pt->node_pt(8));
778  old_node_pt = brick_edge_node_pt[edge];
779  if (old_node_pt == 0)
780  {
781  Node* new_node_pt = 0;
782  if (edge.is_boundary_edge())
783  {
784  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
785  }
786  else
787  {
788  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
789  }
790  brick_edge_node_pt[edge] = new_node_pt;
791  Node_pt.push_back(new_node_pt);
792  Vector<double> s(3);
793  Vector<double> s_tet(3);
794  Vector<double> x_tet(3);
795  el_pt->local_coordinate_of_node(j, s);
796  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
797  tet_el_pt->interpolated_x(s_tet, x_tet);
798  new_node_pt->x(0) = x_tet[0];
799  new_node_pt->x(1) = x_tet[1];
800  new_node_pt->x(2) = x_tet[2];
801  }
802  // Node already exists
803  else
804  {
805  el_pt->node_pt(j) = old_node_pt;
806  }
807  }
808 
809  // Brick edge node between brick nodes 6 and 8
810  {
811  unsigned j = 7;
812 
813  // Need new node?
814  Edge edge(el_pt->node_pt(6), el_pt->node_pt(8));
815  old_node_pt = brick_edge_node_pt[edge];
816  if (old_node_pt == 0)
817  {
818  Node* new_node_pt = 0;
819  if (edge.is_boundary_edge())
820  {
821  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
822  }
823  else
824  {
825  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
826  }
827  brick_edge_node_pt[edge] = new_node_pt;
828  Node_pt.push_back(new_node_pt);
829  Vector<double> s(3);
830  Vector<double> s_tet(3);
831  Vector<double> x_tet(3);
832  el_pt->local_coordinate_of_node(j, s);
833  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
834  tet_el_pt->interpolated_x(s_tet, x_tet);
835  new_node_pt->x(0) = x_tet[0];
836  new_node_pt->x(1) = x_tet[1];
837  new_node_pt->x(2) = x_tet[2];
838  }
839  // Node already exists
840  else
841  {
842  el_pt->node_pt(j) = old_node_pt;
843  }
844  }
845 
846  // Brick edge node between brick nodes 18 and 20
847  {
848  unsigned j = 19;
849 
850  // Need new node?
851  Edge edge(el_pt->node_pt(18), el_pt->node_pt(20));
852  old_node_pt = brick_edge_node_pt[edge];
853  if (old_node_pt == 0)
854  {
855  Node* new_node_pt = 0;
856  if (edge.is_boundary_edge())
857  {
858  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
859  }
860  else
861  {
862  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
863  }
864  brick_edge_node_pt[edge] = new_node_pt;
865  Node_pt.push_back(new_node_pt);
866  Vector<double> s(3);
867  Vector<double> s_tet(3);
868  Vector<double> x_tet(3);
869  el_pt->local_coordinate_of_node(j, s);
870  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
871  tet_el_pt->interpolated_x(s_tet, x_tet);
872  new_node_pt->x(0) = x_tet[0];
873  new_node_pt->x(1) = x_tet[1];
874  new_node_pt->x(2) = x_tet[2];
875  }
876  // Node already exists
877  else
878  {
879  el_pt->node_pt(j) = old_node_pt;
880  }
881  }
882 
883 
884  // Brick edge node between brick nodes 18 and 24
885  {
886  unsigned j = 21;
887 
888  // Need new node?
889  Edge edge(el_pt->node_pt(18), el_pt->node_pt(24));
890  old_node_pt = brick_edge_node_pt[edge];
891  if (old_node_pt == 0)
892  {
893  Node* new_node_pt = 0;
894  if (edge.is_boundary_edge())
895  {
896  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
897  }
898  else
899  {
900  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
901  }
902  brick_edge_node_pt[edge] = new_node_pt;
903  Node_pt.push_back(new_node_pt);
904  Vector<double> s(3);
905  Vector<double> s_tet(3);
906  Vector<double> x_tet(3);
907  el_pt->local_coordinate_of_node(j, s);
908  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
909  tet_el_pt->interpolated_x(s_tet, x_tet);
910  new_node_pt->x(0) = x_tet[0];
911  new_node_pt->x(1) = x_tet[1];
912  new_node_pt->x(2) = x_tet[2];
913  }
914  // Node already exists
915  else
916  {
917  el_pt->node_pt(j) = old_node_pt;
918  }
919  }
920 
921  // Brick edge node between brick nodes 20 and 26
922  {
923  unsigned j = 23;
924 
925  // Need new node?
926  Edge edge(el_pt->node_pt(20), el_pt->node_pt(26));
927  old_node_pt = brick_edge_node_pt[edge];
928  if (old_node_pt == 0)
929  {
930  Node* new_node_pt = 0;
931  if (edge.is_boundary_edge())
932  {
933  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
934  }
935  else
936  {
937  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
938  }
939  brick_edge_node_pt[edge] = new_node_pt;
940  Node_pt.push_back(new_node_pt);
941  Vector<double> s(3);
942  Vector<double> s_tet(3);
943  Vector<double> x_tet(3);
944  el_pt->local_coordinate_of_node(j, s);
945  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
946  tet_el_pt->interpolated_x(s_tet, x_tet);
947  new_node_pt->x(0) = x_tet[0];
948  new_node_pt->x(1) = x_tet[1];
949  new_node_pt->x(2) = x_tet[2];
950  }
951  // Node already exists
952  else
953  {
954  el_pt->node_pt(j) = old_node_pt;
955  }
956  }
957 
958 
959  // Brick edge node between brick nodes 24 and 26
960  {
961  unsigned j = 25;
962 
963  // Need new node?
964  Edge edge(el_pt->node_pt(24), el_pt->node_pt(26));
965  old_node_pt = brick_edge_node_pt[edge];
966  if (old_node_pt == 0)
967  {
968  Node* new_node_pt = 0;
969  if (edge.is_boundary_edge())
970  {
971  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
972  }
973  else
974  {
975  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
976  }
977  brick_edge_node_pt[edge] = new_node_pt;
978  Node_pt.push_back(new_node_pt);
979  Vector<double> s(3);
980  Vector<double> s_tet(3);
981  Vector<double> x_tet(3);
982  el_pt->local_coordinate_of_node(j, s);
983  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
984  tet_el_pt->interpolated_x(s_tet, x_tet);
985  new_node_pt->x(0) = x_tet[0];
986  new_node_pt->x(1) = x_tet[1];
987  new_node_pt->x(2) = x_tet[2];
988  }
989  // Node already exists
990  else
991  {
992  el_pt->node_pt(j) = old_node_pt;
993  }
994  }
995 
996  // Brick edge node between brick nodes 0 and 18
997  {
998  unsigned j = 9;
999 
1000  // Need new node?
1001  Edge edge(el_pt->node_pt(0), el_pt->node_pt(18));
1002  old_node_pt = brick_edge_node_pt[edge];
1003  if (old_node_pt == 0)
1004  {
1005  Node* new_node_pt = 0;
1006  if (edge.is_boundary_edge())
1007  {
1008  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
1009  }
1010  else
1011  {
1012  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
1013  }
1014  brick_edge_node_pt[edge] = new_node_pt;
1015  Node_pt.push_back(new_node_pt);
1016  Vector<double> s(3);
1017  Vector<double> s_tet(3);
1018  Vector<double> x_tet(3);
1019  el_pt->local_coordinate_of_node(j, s);
1020  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
1021  tet_el_pt->interpolated_x(s_tet, x_tet);
1022  new_node_pt->x(0) = x_tet[0];
1023  new_node_pt->x(1) = x_tet[1];
1024  new_node_pt->x(2) = x_tet[2];
1025  }
1026  // Node already exists
1027  else
1028  {
1029  el_pt->node_pt(j) = old_node_pt;
1030  }
1031  }
1032 
1033 
1034  // Brick edge node between brick nodes 2 and 20
1035  {
1036  unsigned j = 11;
1037 
1038  // Need new node?
1039  Edge edge(el_pt->node_pt(2), el_pt->node_pt(20));
1040  old_node_pt = brick_edge_node_pt[edge];
1041  if (old_node_pt == 0)
1042  {
1043  Node* new_node_pt = 0;
1044  if (edge.is_boundary_edge())
1045  {
1046  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
1047  }
1048  else
1049  {
1050  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
1051  }
1052  brick_edge_node_pt[edge] = new_node_pt;
1053  Node_pt.push_back(new_node_pt);
1054  Vector<double> s(3);
1055  Vector<double> s_tet(3);
1056  Vector<double> x_tet(3);
1057  el_pt->local_coordinate_of_node(j, s);
1058  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
1059  tet_el_pt->interpolated_x(s_tet, x_tet);
1060  new_node_pt->x(0) = x_tet[0];
1061  new_node_pt->x(1) = x_tet[1];
1062  new_node_pt->x(2) = x_tet[2];
1063  }
1064  // Node already exists
1065  else
1066  {
1067  el_pt->node_pt(j) = old_node_pt;
1068  }
1069  }
1070 
1071 
1072  // Brick edge node between brick nodes 6 and 24
1073  {
1074  unsigned j = 15;
1075 
1076  // Need new node?
1077  Edge edge(el_pt->node_pt(6), el_pt->node_pt(24));
1078  old_node_pt = brick_edge_node_pt[edge];
1079  if (old_node_pt == 0)
1080  {
1081  Node* new_node_pt = 0;
1082  if (edge.is_boundary_edge())
1083  {
1084  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
1085  }
1086  else
1087  {
1088  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
1089  }
1090  brick_edge_node_pt[edge] = new_node_pt;
1091  Node_pt.push_back(new_node_pt);
1092  Vector<double> s(3);
1093  Vector<double> s_tet(3);
1094  Vector<double> x_tet(3);
1095  el_pt->local_coordinate_of_node(j, s);
1096  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
1097  tet_el_pt->interpolated_x(s_tet, x_tet);
1098  new_node_pt->x(0) = x_tet[0];
1099  new_node_pt->x(1) = x_tet[1];
1100  new_node_pt->x(2) = x_tet[2];
1101  }
1102  // Node already exists
1103  else
1104  {
1105  el_pt->node_pt(j) = old_node_pt;
1106  }
1107  }
1108 
1109 
1110  // Brick edge node between brick nodes 8 and 26
1111  {
1112  unsigned j = 17;
1113 
1114  // Need new node?
1115  Edge edge(el_pt->node_pt(8), el_pt->node_pt(26));
1116  old_node_pt = brick_edge_node_pt[edge];
1117  if (old_node_pt == 0)
1118  {
1119  Node* new_node_pt = 0;
1120  if (edge.is_boundary_edge())
1121  {
1122  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
1123  }
1124  else
1125  {
1126  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
1127  }
1128  brick_edge_node_pt[edge] = new_node_pt;
1129  Node_pt.push_back(new_node_pt);
1130  Vector<double> s(3);
1131  Vector<double> s_tet(3);
1132  Vector<double> x_tet(3);
1133  el_pt->local_coordinate_of_node(j, s);
1134  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
1135  tet_el_pt->interpolated_x(s_tet, x_tet);
1136  new_node_pt->x(0) = x_tet[0];
1137  new_node_pt->x(1) = x_tet[1];
1138  new_node_pt->x(2) = x_tet[2];
1139  }
1140  // Node already exists
1141  else
1142  {
1143  el_pt->node_pt(j) = old_node_pt;
1144  }
1145  }
1146 
1147 
1148  // Mid brick-face node associated with face
1149  // spanned by mid-vertex nodes associated with tet edges 0 and 2
1150  {
1151  unsigned j = 10;
1152 
1153  // Need new node?
1154  TFace face(tet_el_pt->node_pt(central_tet_vertex),
1155  tet_el_pt->node_pt(tet_edge_node[0][0]),
1156  tet_el_pt->node_pt(tet_edge_node[2][0]));
1157 
1158  old_node_pt = tet_face_node_pt[face];
1159  if (old_node_pt == 0)
1160  {
1161  Node* new_node_pt = 0;
1162  if (face.is_boundary_face())
1163  {
1164  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
1165  }
1166  else
1167  {
1168  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
1169  }
1170  tet_face_node_pt[face] = new_node_pt;
1171  Node_pt.push_back(new_node_pt);
1172  Vector<double> s(3);
1173  Vector<double> s_tet(3);
1174  Vector<double> x_tet(3);
1175  el_pt->local_coordinate_of_node(j, s);
1176  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
1177  tet_el_pt->interpolated_x(s_tet, x_tet);
1178  new_node_pt->x(0) = x_tet[0];
1179  new_node_pt->x(1) = x_tet[1];
1180  new_node_pt->x(2) = x_tet[2];
1181  }
1182  // Node already exists
1183  else
1184  {
1185  el_pt->node_pt(j) = old_node_pt;
1186  }
1187  }
1188 
1189 
1190  // Mid brick-face node associated with face
1191  // spanned by mid-vertex nodes associated with tet edges 1 and 2
1192  {
1193  unsigned j = 12;
1194 
1195  // Need new node?
1196  TFace face(tet_el_pt->node_pt(central_tet_vertex),
1197  tet_el_pt->node_pt(tet_edge_node[1][0]),
1198  tet_el_pt->node_pt(tet_edge_node[2][0]));
1199 
1200  old_node_pt = tet_face_node_pt[face];
1201  if (old_node_pt == 0)
1202  {
1203  Node* new_node_pt = 0;
1204  if (face.is_boundary_face())
1205  {
1206  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
1207  }
1208  else
1209  {
1210  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
1211  }
1212  tet_face_node_pt[face] = new_node_pt;
1213  Node_pt.push_back(new_node_pt);
1214  Vector<double> s(3);
1215  Vector<double> s_tet(3);
1216  Vector<double> x_tet(3);
1217  el_pt->local_coordinate_of_node(j, s);
1218  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
1219  tet_el_pt->interpolated_x(s_tet, x_tet);
1220  new_node_pt->x(0) = x_tet[0];
1221  new_node_pt->x(1) = x_tet[1];
1222  new_node_pt->x(2) = x_tet[2];
1223  }
1224  // Node already exists
1225  else
1226  {
1227  el_pt->node_pt(j) = old_node_pt;
1228  }
1229  }
1230 
1231 
1232  // Mid brick-face node associated with face
1233  // spanned by mid-vertex nodes associated with tet edges 0 and 1
1234  {
1235  unsigned j = 4;
1236 
1237  // Need new node?
1238  TFace face(tet_el_pt->node_pt(central_tet_vertex),
1239  tet_el_pt->node_pt(tet_edge_node[0][0]),
1240  tet_el_pt->node_pt(tet_edge_node[1][0]));
1241 
1242  old_node_pt = tet_face_node_pt[face];
1243  if (old_node_pt == 0)
1244  {
1245  Node* new_node_pt = 0;
1246  if (face.is_boundary_face())
1247  {
1248  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
1249  }
1250  else
1251  {
1252  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
1253  }
1254  tet_face_node_pt[face] = new_node_pt;
1255  Node_pt.push_back(new_node_pt);
1256  Vector<double> s(3);
1257  Vector<double> s_tet(3);
1258  Vector<double> x_tet(3);
1259  el_pt->local_coordinate_of_node(j, s);
1260  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
1261  tet_el_pt->interpolated_x(s_tet, x_tet);
1262  new_node_pt->x(0) = x_tet[0];
1263  new_node_pt->x(1) = x_tet[1];
1264  new_node_pt->x(2) = x_tet[2];
1265  }
1266  // Node already exists
1267  else
1268  {
1269  el_pt->node_pt(j) = old_node_pt;
1270  }
1271  }
1272 
1273 
1274  // Top mid brick-face node -- only built by first element
1275  {
1276  unsigned j = 22;
1277  Node* new_node_pt = el_pt->construct_node(j, time_stepper_pt);
1278  Node_pt.push_back(new_node_pt);
1279  Vector<double> s(3);
1280  Vector<double> s_tet(3);
1281  Vector<double> x_tet(3);
1282  el_pt->local_coordinate_of_node(j, s);
1283  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
1284  top_mid_face_node0_pt = new_node_pt;
1285  tet_el_pt->interpolated_x(s_tet, x_tet);
1286  new_node_pt->x(0) = x_tet[0];
1287  new_node_pt->x(1) = x_tet[1];
1288  new_node_pt->x(2) = x_tet[2];
1289  }
1290 
1291 
1292  // Right mid brick-face node -- only built by first element
1293  {
1294  unsigned j = 14;
1295  Node* new_node_pt = el_pt->construct_node(j, time_stepper_pt);
1296  Node_pt.push_back(new_node_pt);
1297  Vector<double> s(3);
1298  Vector<double> s_tet(3);
1299  Vector<double> x_tet(3);
1300  el_pt->local_coordinate_of_node(j, s);
1301  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
1302  right_mid_face_node0_pt = new_node_pt;
1303  tet_el_pt->interpolated_x(s_tet, x_tet);
1304  new_node_pt->x(0) = x_tet[0];
1305  new_node_pt->x(1) = x_tet[1];
1306  new_node_pt->x(2) = x_tet[2];
1307  }
1308 
1309 
1310  // Back mid brick-face node -- only built by first element
1311  {
1312  unsigned j = 16;
1313  Node* new_node_pt = el_pt->construct_node(j, time_stepper_pt);
1314  Node_pt.push_back(new_node_pt);
1315  Vector<double> s(3);
1316  Vector<double> s_tet(3);
1317  Vector<double> x_tet(3);
1318  el_pt->local_coordinate_of_node(j, s);
1319  dummy_q_el_pt[0]->interpolated_s_tet(s, s_tet);
1320  back_mid_face_node0_pt = new_node_pt;
1321  tet_el_pt->interpolated_x(s_tet, x_tet);
1322  new_node_pt->x(0) = x_tet[0];
1323  new_node_pt->x(1) = x_tet[1];
1324  new_node_pt->x(2) = x_tet[2];
1325  }
1326  }
1327 
1328 
1329  // Second brick element is centred at node 1 of tet:
1330  //--------------------------------------------------
1331  {
1332  // Assign coordinates of dummy element
1333  for (unsigned j = 0; j < 8; j++)
1334  {
1335  Node* nod_pt = dummy_q_el_pt[1]->node_pt(j);
1336  Vector<double> s_tet(3);
1337  Vector<double> x_tet(3);
1338  switch (j)
1339  {
1340  case 0:
1341  tet_el_pt->local_coordinate_of_node(1, s_tet);
1342  nod_pt->set_value(0, s_tet[0]);
1343  nod_pt->set_value(1, s_tet[1]);
1344  nod_pt->set_value(2, s_tet[2]);
1345  tet_el_pt->interpolated_x(s_tet, x_tet);
1346  nod_pt->x(0) = x_tet[0];
1347  nod_pt->x(1) = x_tet[1];
1348  nod_pt->x(2) = x_tet[2];
1349  break;
1350  case 1:
1351  tet_el_pt->local_coordinate_of_node(9, s_tet);
1352  nod_pt->set_value(0, s_tet[0]);
1353  nod_pt->set_value(1, s_tet[1]);
1354  nod_pt->set_value(2, s_tet[2]);
1355  tet_el_pt->interpolated_x(s_tet, x_tet);
1356  nod_pt->x(0) = x_tet[0];
1357  nod_pt->x(1) = x_tet[1];
1358  nod_pt->x(2) = x_tet[2];
1359  break;
1360  case 2:
1361  tet_el_pt->local_coordinate_of_node(4, s_tet);
1362  nod_pt->set_value(0, s_tet[0]);
1363  nod_pt->set_value(1, s_tet[1]);
1364  nod_pt->set_value(2, s_tet[2]);
1365  tet_el_pt->interpolated_x(s_tet, x_tet);
1366  nod_pt->x(0) = x_tet[0];
1367  nod_pt->x(1) = x_tet[1];
1368  nod_pt->x(2) = x_tet[2];
1369  break;
1370  case 3:
1371  // label 13 in initial sketch: Mid face node on face
1372  // spanned by tet nodes 0,1,3
1373  s_tet[0] = 1.0 / 3.0;
1374  s_tet[1] = 1.0 / 3.0;
1375  s_tet[2] = 0.0;
1376  nod_pt->set_value(0, s_tet[0]);
1377  nod_pt->set_value(1, s_tet[1]);
1378  nod_pt->set_value(2, s_tet[2]);
1379  tet_el_pt->interpolated_x(s_tet, x_tet);
1380  nod_pt->x(0) = x_tet[0];
1381  nod_pt->x(1) = x_tet[1];
1382  nod_pt->x(2) = x_tet[2];
1383  break;
1384  case 4:
1385  tet_el_pt->local_coordinate_of_node(7, s_tet);
1386  nod_pt->set_value(0, s_tet[0]);
1387  nod_pt->set_value(1, s_tet[1]);
1388  nod_pt->set_value(2, s_tet[2]);
1389  tet_el_pt->interpolated_x(s_tet, x_tet);
1390  nod_pt->x(0) = x_tet[0];
1391  nod_pt->x(1) = x_tet[1];
1392  nod_pt->x(2) = x_tet[2];
1393  break;
1394  case 5:
1395  // label 10 in initial sketch: Mid face node on face
1396  // spanned by tet nodes 1,2,3
1397  s_tet[0] = 0.0;
1398  s_tet[1] = 1.0 / 3.0;
1399  s_tet[2] = 1.0 / 3.0;
1400  nod_pt->set_value(0, s_tet[0]);
1401  nod_pt->set_value(1, s_tet[1]);
1402  nod_pt->set_value(2, s_tet[2]);
1403  tet_el_pt->interpolated_x(s_tet, x_tet);
1404  nod_pt->x(0) = x_tet[0];
1405  nod_pt->x(1) = x_tet[1];
1406  nod_pt->x(2) = x_tet[2];
1407  break;
1408  case 6:
1409  // label 11 in initial sketch: Mid face node on face
1410  // spanned by tet nodes 0,1,2
1411  s_tet[0] = 1.0 / 3.0;
1412  s_tet[1] = 1.0 / 3.0;
1413  s_tet[2] = 1.0 / 3.0;
1414  nod_pt->set_value(0, s_tet[0]);
1415  nod_pt->set_value(1, s_tet[1]);
1416  nod_pt->set_value(2, s_tet[2]);
1417  tet_el_pt->interpolated_x(s_tet, x_tet);
1418  nod_pt->x(0) = x_tet[0];
1419  nod_pt->x(1) = x_tet[1];
1420  nod_pt->x(2) = x_tet[2];
1421  break;
1422  case 7:
1423  // label 14 in initial sketch: Centroid
1424  s_tet[0] = 0.25;
1425  s_tet[1] = 0.25;
1426  s_tet[2] = 0.25;
1427  nod_pt->set_value(0, s_tet[0]);
1428  nod_pt->set_value(1, s_tet[1]);
1429  nod_pt->set_value(2, s_tet[2]);
1430  tet_el_pt->interpolated_x(s_tet, x_tet);
1431  nod_pt->x(0) = x_tet[0];
1432  nod_pt->x(1) = x_tet[1];
1433  nod_pt->x(2) = x_tet[2];
1434  break;
1435  }
1436  }
1437 
1438 
1439  // Create actual first brick element
1440  FiniteElement* el_pt = new ELEMENT;
1441  brick_el1_pt = el_pt;
1442  Element_pt.push_back(el_pt);
1443 
1444  TFace face0(
1445  tet_el_pt->node_pt(1), tet_el_pt->node_pt(3), tet_el_pt->node_pt(2));
1446 
1447  TFace face1(
1448  tet_el_pt->node_pt(1), tet_el_pt->node_pt(0), tet_el_pt->node_pt(2));
1449 
1450  TFace face2(
1451  tet_el_pt->node_pt(1), tet_el_pt->node_pt(0), tet_el_pt->node_pt(3));
1452 
1453  // Tet vertex nodes along edges emanating from node 0 in brick
1454  Vector<Vector<unsigned>> tet_edge_node(3);
1455  tet_edge_node[0].resize(2);
1456  tet_edge_node[0][0] = 9;
1457  tet_edge_node[0][1] = 3;
1458  tet_edge_node[1].resize(2);
1459  tet_edge_node[1][0] = 4;
1460  tet_edge_node[1][1] = 0;
1461  tet_edge_node[2].resize(2);
1462  tet_edge_node[2][0] = 7;
1463  tet_edge_node[2][1] = 2;
1464 
1465  // Node number of tet vertex that node 0 in brick is centred on
1466  unsigned central_tet_vertex = 1;
1467 
1468  Node* tet_node_pt = 0;
1469  Node* old_node_pt = 0;
1470 
1471  // Corner node
1472  {
1473  unsigned j = 0;
1474 
1475  // Need new node?
1476  tet_node_pt = tet_el_pt->node_pt(central_tet_vertex);
1477  old_node_pt = tet_node_node_pt[tet_node_pt];
1478  if (old_node_pt == 0)
1479  {
1480  Node* new_node_pt = 0;
1481  if (tet_node_pt->is_on_boundary())
1482  {
1483  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
1484  }
1485  else
1486  {
1487  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
1488  }
1489  tet_node_node_pt[tet_node_pt] = new_node_pt;
1490  Node_pt.push_back(new_node_pt);
1491  Vector<double> s(3);
1492  Vector<double> s_tet(3);
1493  Vector<double> x_tet(3);
1494  el_pt->local_coordinate_of_node(j, s);
1495  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
1496  tet_el_pt->interpolated_x(s_tet, x_tet);
1497  new_node_pt->x(0) = x_tet[0];
1498  new_node_pt->x(1) = x_tet[1];
1499  new_node_pt->x(2) = x_tet[2];
1500  }
1501  // Node already exists
1502  else
1503  {
1504  el_pt->node_pt(j) = old_node_pt;
1505  }
1506  }
1507 
1508 
1509  // Brick vertex node coindides with mid-edge node on tet edge 0
1510  {
1511  unsigned j = 2;
1512 
1513  // Need new node?
1514  tet_node_pt = tet_el_pt->node_pt(tet_edge_node[0][0]);
1515  old_node_pt = tet_node_node_pt[tet_node_pt];
1516  if (old_node_pt == 0)
1517  {
1518  Node* new_node_pt = 0;
1519  if (tet_node_pt->is_on_boundary())
1520  {
1521  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
1522  }
1523  else
1524  {
1525  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
1526  }
1527  tet_node_node_pt[tet_node_pt] = new_node_pt;
1528  Node_pt.push_back(new_node_pt);
1529  Vector<double> s(3);
1530  Vector<double> s_tet(3);
1531  Vector<double> x_tet(3);
1532  el_pt->local_coordinate_of_node(j, s);
1533  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
1534  tet_el_pt->interpolated_x(s_tet, x_tet);
1535  new_node_pt->x(0) = x_tet[0];
1536  new_node_pt->x(1) = x_tet[1];
1537  new_node_pt->x(2) = x_tet[2];
1538  }
1539  // Node already exists
1540  else
1541  {
1542  el_pt->node_pt(j) = old_node_pt;
1543  }
1544  }
1545 
1546 
1547  // Brick vertex node coindides with mid vertex node of tet edge 1
1548  {
1549  unsigned j = 6;
1550 
1551  // Need new node?
1552  tet_node_pt = tet_el_pt->node_pt(tet_edge_node[1][0]);
1553  old_node_pt = tet_node_node_pt[tet_node_pt];
1554  if (old_node_pt == 0)
1555  {
1556  Node* new_node_pt = 0;
1557  if (tet_node_pt->is_on_boundary())
1558  {
1559  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
1560  }
1561  else
1562  {
1563  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
1564  }
1565  tet_node_node_pt[tet_node_pt] = new_node_pt;
1566  Node_pt.push_back(new_node_pt);
1567  Vector<double> s(3);
1568  Vector<double> s_tet(3);
1569  Vector<double> x_tet(3);
1570  el_pt->local_coordinate_of_node(j, s);
1571  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
1572  tet_el_pt->interpolated_x(s_tet, x_tet);
1573  new_node_pt->x(0) = x_tet[0];
1574  new_node_pt->x(1) = x_tet[1];
1575  new_node_pt->x(2) = x_tet[2];
1576  }
1577  // Node already exists
1578  else
1579  {
1580  el_pt->node_pt(j) = old_node_pt;
1581  }
1582  }
1583 
1584 
1585  // Brick vertex node coindides with mid-vertex node of tet edge 2
1586  {
1587  unsigned j = 18;
1588 
1589  // Need new node?
1590  tet_node_pt = tet_el_pt->node_pt(tet_edge_node[2][0]);
1591  old_node_pt = tet_node_node_pt[tet_node_pt];
1592  if (old_node_pt == 0)
1593  {
1594  Node* new_node_pt = 0;
1595  if (tet_node_pt->is_on_boundary())
1596  {
1597  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
1598  }
1599  else
1600  {
1601  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
1602  }
1603  tet_node_node_pt[tet_node_pt] = new_node_pt;
1604  Node_pt.push_back(new_node_pt);
1605  Vector<double> s(3);
1606  Vector<double> s_tet(3);
1607  Vector<double> x_tet(3);
1608  el_pt->local_coordinate_of_node(j, s);
1609  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
1610  tet_el_pt->interpolated_x(s_tet, x_tet);
1611  new_node_pt->x(0) = x_tet[0];
1612  new_node_pt->x(1) = x_tet[1];
1613  new_node_pt->x(2) = x_tet[2];
1614  }
1615  // Node already exists
1616  else
1617  {
1618  el_pt->node_pt(j) = old_node_pt;
1619  }
1620  }
1621 
1622 
1623  // Brick vertex node in the middle of tet face0
1624  {
1625  unsigned j = 20;
1626 
1627  // Need new node?
1628  old_node_pt = tet_face_node_pt[face0];
1629  if (old_node_pt == 0)
1630  {
1631  Node* new_node_pt = 0;
1632  if (face0.is_boundary_face())
1633  {
1634  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
1635  }
1636  else
1637  {
1638  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
1639  }
1640  tet_face_node_pt[face0] = new_node_pt;
1641  Node_pt.push_back(new_node_pt);
1642  Vector<double> s(3);
1643  Vector<double> s_tet(3);
1644  Vector<double> x_tet(3);
1645  el_pt->local_coordinate_of_node(j, s);
1646  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
1647  tet_el_pt->interpolated_x(s_tet, x_tet);
1648  new_node_pt->x(0) = x_tet[0];
1649  new_node_pt->x(1) = x_tet[1];
1650  new_node_pt->x(2) = x_tet[2];
1651  }
1652  // Node already exists
1653  else
1654  {
1655  el_pt->node_pt(j) = old_node_pt;
1656  }
1657  }
1658 
1659  // Brick vertex node in the middle of tet face1
1660  {
1661  unsigned j = 24;
1662 
1663  // Need new node?
1664  old_node_pt = tet_face_node_pt[face1];
1665  if (old_node_pt == 0)
1666  {
1667  Node* new_node_pt = 0;
1668  if (face1.is_boundary_face())
1669  {
1670  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
1671  }
1672  else
1673  {
1674  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
1675  }
1676  tet_face_node_pt[face1] = new_node_pt;
1677  Node_pt.push_back(new_node_pt);
1678  Vector<double> s(3);
1679  Vector<double> s_tet(3);
1680  Vector<double> x_tet(3);
1681  el_pt->local_coordinate_of_node(j, s);
1682  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
1683  tet_el_pt->interpolated_x(s_tet, x_tet);
1684  new_node_pt->x(0) = x_tet[0];
1685  new_node_pt->x(1) = x_tet[1];
1686  new_node_pt->x(2) = x_tet[2];
1687  }
1688  // Node already exists
1689  else
1690  {
1691  el_pt->node_pt(j) = old_node_pt;
1692  }
1693  }
1694 
1695  // Brick vertex node in the middle of face2
1696  {
1697  unsigned j = 8;
1698 
1699  // Need new node?
1700  old_node_pt = tet_face_node_pt[face2];
1701  if (old_node_pt == 0)
1702  {
1703  Node* new_node_pt = 0;
1704  if (face2.is_boundary_face())
1705  {
1706  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
1707  }
1708  else
1709  {
1710  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
1711  }
1712  tet_face_node_pt[face2] = new_node_pt;
1713  Node_pt.push_back(new_node_pt);
1714  Vector<double> s(3);
1715  Vector<double> s_tet(3);
1716  Vector<double> x_tet(3);
1717  el_pt->local_coordinate_of_node(j, s);
1718  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
1719  tet_el_pt->interpolated_x(s_tet, x_tet);
1720  new_node_pt->x(0) = x_tet[0];
1721  new_node_pt->x(1) = x_tet[1];
1722  new_node_pt->x(2) = x_tet[2];
1723  }
1724  // Node already exists
1725  else
1726  {
1727  el_pt->node_pt(j) = old_node_pt;
1728  }
1729  }
1730 
1731 
1732  // Brick vertex node in centroid of tet. Only built for first element.
1733  // Enumerated "13" in initial sketch.
1734  {
1735  unsigned j = 26;
1736 
1737  // Always copied
1738  el_pt->node_pt(j) = centroid_node_pt;
1739  }
1740 
1741 
1742  // Internal brick node -- always built
1743  {
1744  unsigned j = 13;
1745 
1746  // Always new
1747  {
1748  Node* new_node_pt = el_pt->construct_node(j, time_stepper_pt);
1749  Node_pt.push_back(new_node_pt);
1750  Vector<double> s(3);
1751  Vector<double> s_tet(3);
1752  Vector<double> x_tet(3);
1753  el_pt->local_coordinate_of_node(j, s);
1754  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
1755  tet_el_pt->interpolated_x(s_tet, x_tet);
1756  new_node_pt->x(0) = x_tet[0];
1757  new_node_pt->x(1) = x_tet[1];
1758  new_node_pt->x(2) = x_tet[2];
1759  }
1760  }
1761 
1762 
1763  // Brick edge node between brick nodes 0 and 2
1764  {
1765  unsigned j = 1;
1766 
1767  // Need new node?
1768  Edge edge(el_pt->node_pt(0), el_pt->node_pt(2));
1769  old_node_pt = brick_edge_node_pt[edge];
1770  if (old_node_pt == 0)
1771  {
1772  Node* new_node_pt = 0;
1773  if (edge.is_boundary_edge())
1774  {
1775  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
1776  }
1777  else
1778  {
1779  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
1780  }
1781  brick_edge_node_pt[edge] = new_node_pt;
1782  Node_pt.push_back(new_node_pt);
1783  Vector<double> s(3);
1784  Vector<double> s_tet(3);
1785  Vector<double> x_tet(3);
1786  el_pt->local_coordinate_of_node(j, s);
1787  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
1788  tet_el_pt->interpolated_x(s_tet, x_tet);
1789  new_node_pt->x(0) = x_tet[0];
1790  new_node_pt->x(1) = x_tet[1];
1791  new_node_pt->x(2) = x_tet[2];
1792  }
1793  // Node already exists
1794  else
1795  {
1796  el_pt->node_pt(j) = old_node_pt;
1797  }
1798  }
1799 
1800 
1801  // Brick edge node between brick nodes 0 and 6
1802  {
1803  unsigned j = 3;
1804 
1805  // Need new node?
1806  Edge edge(el_pt->node_pt(0), el_pt->node_pt(6));
1807  old_node_pt = brick_edge_node_pt[edge];
1808  if (old_node_pt == 0)
1809  {
1810  Node* new_node_pt = 0;
1811  if (edge.is_boundary_edge())
1812  {
1813  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
1814  }
1815  else
1816  {
1817  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
1818  }
1819  brick_edge_node_pt[edge] = new_node_pt;
1820  Node_pt.push_back(new_node_pt);
1821  Vector<double> s(3);
1822  Vector<double> s_tet(3);
1823  Vector<double> x_tet(3);
1824  el_pt->local_coordinate_of_node(j, s);
1825  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
1826  tet_el_pt->interpolated_x(s_tet, x_tet);
1827  new_node_pt->x(0) = x_tet[0];
1828  new_node_pt->x(1) = x_tet[1];
1829  new_node_pt->x(2) = x_tet[2];
1830  }
1831  // Node already exists
1832  else
1833  {
1834  el_pt->node_pt(j) = old_node_pt;
1835  }
1836  }
1837 
1838 
1839  // Brick edge node between brick nodes 2 and 8
1840  {
1841  unsigned j = 5;
1842 
1843  // Need new node?
1844  Edge edge(el_pt->node_pt(2), el_pt->node_pt(8));
1845  old_node_pt = brick_edge_node_pt[edge];
1846  if (old_node_pt == 0)
1847  {
1848  Node* new_node_pt = 0;
1849  if (edge.is_boundary_edge())
1850  {
1851  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
1852  }
1853  else
1854  {
1855  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
1856  }
1857  brick_edge_node_pt[edge] = new_node_pt;
1858  Node_pt.push_back(new_node_pt);
1859  Vector<double> s(3);
1860  Vector<double> s_tet(3);
1861  Vector<double> x_tet(3);
1862  el_pt->local_coordinate_of_node(j, s);
1863  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
1864  tet_el_pt->interpolated_x(s_tet, x_tet);
1865  new_node_pt->x(0) = x_tet[0];
1866  new_node_pt->x(1) = x_tet[1];
1867  new_node_pt->x(2) = x_tet[2];
1868  }
1869  // Node already exists
1870  else
1871  {
1872  el_pt->node_pt(j) = old_node_pt;
1873  }
1874  }
1875 
1876  // Brick edge node between brick nodes 6 and 8
1877  {
1878  unsigned j = 7;
1879 
1880  // Need new node?
1881  Edge edge(el_pt->node_pt(6), el_pt->node_pt(8));
1882  old_node_pt = brick_edge_node_pt[edge];
1883  if (old_node_pt == 0)
1884  {
1885  Node* new_node_pt = 0;
1886  if (edge.is_boundary_edge())
1887  {
1888  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
1889  }
1890  else
1891  {
1892  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
1893  }
1894  brick_edge_node_pt[edge] = new_node_pt;
1895  Node_pt.push_back(new_node_pt);
1896  Vector<double> s(3);
1897  Vector<double> s_tet(3);
1898  Vector<double> x_tet(3);
1899  el_pt->local_coordinate_of_node(j, s);
1900  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
1901  tet_el_pt->interpolated_x(s_tet, x_tet);
1902  new_node_pt->x(0) = x_tet[0];
1903  new_node_pt->x(1) = x_tet[1];
1904  new_node_pt->x(2) = x_tet[2];
1905  }
1906  // Node already exists
1907  else
1908  {
1909  el_pt->node_pt(j) = old_node_pt;
1910  }
1911  }
1912 
1913  // Brick edge node between brick nodes 18 and 20
1914  {
1915  unsigned j = 19;
1916 
1917  // Need new node?
1918  Edge edge(el_pt->node_pt(18), el_pt->node_pt(20));
1919  old_node_pt = brick_edge_node_pt[edge];
1920  if (old_node_pt == 0)
1921  {
1922  Node* new_node_pt = 0;
1923  if (edge.is_boundary_edge())
1924  {
1925  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
1926  }
1927  else
1928  {
1929  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
1930  }
1931  brick_edge_node_pt[edge] = new_node_pt;
1932  Node_pt.push_back(new_node_pt);
1933  Vector<double> s(3);
1934  Vector<double> s_tet(3);
1935  Vector<double> x_tet(3);
1936  el_pt->local_coordinate_of_node(j, s);
1937  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
1938  tet_el_pt->interpolated_x(s_tet, x_tet);
1939  new_node_pt->x(0) = x_tet[0];
1940  new_node_pt->x(1) = x_tet[1];
1941  new_node_pt->x(2) = x_tet[2];
1942  }
1943  // Node already exists
1944  else
1945  {
1946  el_pt->node_pt(j) = old_node_pt;
1947  }
1948  }
1949 
1950 
1951  // Brick edge node between brick nodes 18 and 24
1952  {
1953  unsigned j = 21;
1954 
1955  // Need new node?
1956  Edge edge(el_pt->node_pt(18), el_pt->node_pt(24));
1957  old_node_pt = brick_edge_node_pt[edge];
1958  if (old_node_pt == 0)
1959  {
1960  Node* new_node_pt = 0;
1961  if (edge.is_boundary_edge())
1962  {
1963  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
1964  }
1965  else
1966  {
1967  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
1968  }
1969  brick_edge_node_pt[edge] = new_node_pt;
1970  Node_pt.push_back(new_node_pt);
1971  Vector<double> s(3);
1972  Vector<double> s_tet(3);
1973  Vector<double> x_tet(3);
1974  el_pt->local_coordinate_of_node(j, s);
1975  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
1976  tet_el_pt->interpolated_x(s_tet, x_tet);
1977  new_node_pt->x(0) = x_tet[0];
1978  new_node_pt->x(1) = x_tet[1];
1979  new_node_pt->x(2) = x_tet[2];
1980  }
1981  // Node already exists
1982  else
1983  {
1984  el_pt->node_pt(j) = old_node_pt;
1985  }
1986  }
1987 
1988  // Brick edge node between brick nodes 20 and 26
1989  {
1990  unsigned j = 23;
1991 
1992  // Need new node?
1993  Edge edge(el_pt->node_pt(20), el_pt->node_pt(26));
1994  old_node_pt = brick_edge_node_pt[edge];
1995  if (old_node_pt == 0)
1996  {
1997  Node* new_node_pt = 0;
1998  if (edge.is_boundary_edge())
1999  {
2000  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
2001  }
2002  else
2003  {
2004  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
2005  }
2006  brick_edge_node_pt[edge] = new_node_pt;
2007  Node_pt.push_back(new_node_pt);
2008  Vector<double> s(3);
2009  Vector<double> s_tet(3);
2010  Vector<double> x_tet(3);
2011  el_pt->local_coordinate_of_node(j, s);
2012  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
2013  tet_el_pt->interpolated_x(s_tet, x_tet);
2014  new_node_pt->x(0) = x_tet[0];
2015  new_node_pt->x(1) = x_tet[1];
2016  new_node_pt->x(2) = x_tet[2];
2017  }
2018  // Node already exists
2019  else
2020  {
2021  el_pt->node_pt(j) = old_node_pt;
2022  }
2023  }
2024 
2025 
2026  // Brick edge node between brick nodes 24 and 26
2027  {
2028  unsigned j = 25;
2029 
2030  // Need new node?
2031  Edge edge(el_pt->node_pt(24), el_pt->node_pt(26));
2032  old_node_pt = brick_edge_node_pt[edge];
2033  if (old_node_pt == 0)
2034  {
2035  Node* new_node_pt = 0;
2036  if (edge.is_boundary_edge())
2037  {
2038  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
2039  }
2040  else
2041  {
2042  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
2043  }
2044  brick_edge_node_pt[edge] = new_node_pt;
2045  Node_pt.push_back(new_node_pt);
2046  Vector<double> s(3);
2047  Vector<double> s_tet(3);
2048  Vector<double> x_tet(3);
2049  el_pt->local_coordinate_of_node(j, s);
2050  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
2051  tet_el_pt->interpolated_x(s_tet, x_tet);
2052  new_node_pt->x(0) = x_tet[0];
2053  new_node_pt->x(1) = x_tet[1];
2054  new_node_pt->x(2) = x_tet[2];
2055  }
2056  // Node already exists
2057  else
2058  {
2059  el_pt->node_pt(j) = old_node_pt;
2060  }
2061  }
2062 
2063  // Brick edge node between brick nodes 0 and 18
2064  {
2065  unsigned j = 9;
2066 
2067  // Need new node?
2068  Edge edge(el_pt->node_pt(0), el_pt->node_pt(18));
2069  old_node_pt = brick_edge_node_pt[edge];
2070  if (old_node_pt == 0)
2071  {
2072  Node* new_node_pt = 0;
2073  if (edge.is_boundary_edge())
2074  {
2075  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
2076  }
2077  else
2078  {
2079  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
2080  }
2081  brick_edge_node_pt[edge] = new_node_pt;
2082  Node_pt.push_back(new_node_pt);
2083  Vector<double> s(3);
2084  Vector<double> s_tet(3);
2085  Vector<double> x_tet(3);
2086  el_pt->local_coordinate_of_node(j, s);
2087  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
2088  tet_el_pt->interpolated_x(s_tet, x_tet);
2089  new_node_pt->x(0) = x_tet[0];
2090  new_node_pt->x(1) = x_tet[1];
2091  new_node_pt->x(2) = x_tet[2];
2092  }
2093  // Node already exists
2094  else
2095  {
2096  el_pt->node_pt(j) = old_node_pt;
2097  }
2098  }
2099 
2100 
2101  // Brick edge node between brick nodes 2 and 20
2102  {
2103  unsigned j = 11;
2104 
2105  // Need new node?
2106  Edge edge(el_pt->node_pt(2), el_pt->node_pt(20));
2107  old_node_pt = brick_edge_node_pt[edge];
2108  if (old_node_pt == 0)
2109  {
2110  Node* new_node_pt = 0;
2111  if (edge.is_boundary_edge())
2112  {
2113  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
2114  }
2115  else
2116  {
2117  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
2118  }
2119  brick_edge_node_pt[edge] = new_node_pt;
2120  Node_pt.push_back(new_node_pt);
2121  Vector<double> s(3);
2122  Vector<double> s_tet(3);
2123  Vector<double> x_tet(3);
2124  el_pt->local_coordinate_of_node(j, s);
2125  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
2126  tet_el_pt->interpolated_x(s_tet, x_tet);
2127  new_node_pt->x(0) = x_tet[0];
2128  new_node_pt->x(1) = x_tet[1];
2129  new_node_pt->x(2) = x_tet[2];
2130  }
2131  // Node already exists
2132  else
2133  {
2134  el_pt->node_pt(j) = old_node_pt;
2135  }
2136  }
2137 
2138 
2139  // Brick edge node between brick nodes 6 and 24
2140  {
2141  unsigned j = 15;
2142 
2143  // Need new node?
2144  Edge edge(el_pt->node_pt(6), el_pt->node_pt(24));
2145  old_node_pt = brick_edge_node_pt[edge];
2146  if (old_node_pt == 0)
2147  {
2148  Node* new_node_pt = 0;
2149  if (edge.is_boundary_edge())
2150  {
2151  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
2152  }
2153  else
2154  {
2155  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
2156  }
2157  brick_edge_node_pt[edge] = new_node_pt;
2158  Node_pt.push_back(new_node_pt);
2159  Vector<double> s(3);
2160  Vector<double> s_tet(3);
2161  Vector<double> x_tet(3);
2162  el_pt->local_coordinate_of_node(j, s);
2163  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
2164  tet_el_pt->interpolated_x(s_tet, x_tet);
2165  new_node_pt->x(0) = x_tet[0];
2166  new_node_pt->x(1) = x_tet[1];
2167  new_node_pt->x(2) = x_tet[2];
2168  }
2169  // Node already exists
2170  else
2171  {
2172  el_pt->node_pt(j) = old_node_pt;
2173  }
2174  }
2175 
2176 
2177  // Brick edge node between brick nodes 8 and 26
2178  {
2179  unsigned j = 17;
2180 
2181  // Need new node?
2182  Edge edge(el_pt->node_pt(8), el_pt->node_pt(26));
2183  old_node_pt = brick_edge_node_pt[edge];
2184  if (old_node_pt == 0)
2185  {
2186  Node* new_node_pt = 0;
2187  if (edge.is_boundary_edge())
2188  {
2189  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
2190  }
2191  else
2192  {
2193  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
2194  }
2195  brick_edge_node_pt[edge] = new_node_pt;
2196  Node_pt.push_back(new_node_pt);
2197  Vector<double> s(3);
2198  Vector<double> s_tet(3);
2199  Vector<double> x_tet(3);
2200  el_pt->local_coordinate_of_node(j, s);
2201  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
2202  tet_el_pt->interpolated_x(s_tet, x_tet);
2203  new_node_pt->x(0) = x_tet[0];
2204  new_node_pt->x(1) = x_tet[1];
2205  new_node_pt->x(2) = x_tet[2];
2206  }
2207  // Node already exists
2208  else
2209  {
2210  el_pt->node_pt(j) = old_node_pt;
2211  }
2212  }
2213 
2214 
2215  // Mid brick-face node associated with face
2216  // spanned by mid-vertex nodes associated with tet edges 0 and 2
2217  {
2218  unsigned j = 10;
2219 
2220  // Need new node?
2221  TFace face(tet_el_pt->node_pt(central_tet_vertex),
2222  tet_el_pt->node_pt(tet_edge_node[0][0]),
2223  tet_el_pt->node_pt(tet_edge_node[2][0]));
2224 
2225  old_node_pt = tet_face_node_pt[face];
2226  if (old_node_pt == 0)
2227  {
2228  Node* new_node_pt = 0;
2229  if (face.is_boundary_face())
2230  {
2231  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
2232  }
2233  else
2234  {
2235  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
2236  }
2237  tet_face_node_pt[face] = new_node_pt;
2238  Node_pt.push_back(new_node_pt);
2239  Vector<double> s(3);
2240  Vector<double> s_tet(3);
2241  Vector<double> x_tet(3);
2242  el_pt->local_coordinate_of_node(j, s);
2243  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
2244  tet_el_pt->interpolated_x(s_tet, x_tet);
2245  new_node_pt->x(0) = x_tet[0];
2246  new_node_pt->x(1) = x_tet[1];
2247  new_node_pt->x(2) = x_tet[2];
2248  }
2249  // Node already exists
2250  else
2251  {
2252  el_pt->node_pt(j) = old_node_pt;
2253  }
2254  }
2255 
2256 
2257  // Mid brick-face node associated with face
2258  // spanned by mid-vertex nodes associated with tet edges 1 and 2
2259  {
2260  unsigned j = 12;
2261 
2262  // Need new node?
2263  TFace face(tet_el_pt->node_pt(central_tet_vertex),
2264  tet_el_pt->node_pt(tet_edge_node[1][0]),
2265  tet_el_pt->node_pt(tet_edge_node[2][0]));
2266 
2267  old_node_pt = tet_face_node_pt[face];
2268  if (old_node_pt == 0)
2269  {
2270  Node* new_node_pt = 0;
2271  if (face.is_boundary_face())
2272  {
2273  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
2274  }
2275  else
2276  {
2277  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
2278  }
2279  tet_face_node_pt[face] = new_node_pt;
2280  Node_pt.push_back(new_node_pt);
2281  Vector<double> s(3);
2282  Vector<double> s_tet(3);
2283  Vector<double> x_tet(3);
2284  el_pt->local_coordinate_of_node(j, s);
2285  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
2286  tet_el_pt->interpolated_x(s_tet, x_tet);
2287  new_node_pt->x(0) = x_tet[0];
2288  new_node_pt->x(1) = x_tet[1];
2289  new_node_pt->x(2) = x_tet[2];
2290  }
2291  // Node already exists
2292  else
2293  {
2294  el_pt->node_pt(j) = old_node_pt;
2295  }
2296  }
2297 
2298 
2299  // Mid brick-face node associated with face
2300  // spanned by mid-vertex nodes associated with tet edges 0 and 1
2301  {
2302  unsigned j = 4;
2303 
2304  // Need new node?
2305  TFace face(tet_el_pt->node_pt(central_tet_vertex),
2306  tet_el_pt->node_pt(tet_edge_node[0][0]),
2307  tet_el_pt->node_pt(tet_edge_node[1][0]));
2308 
2309  old_node_pt = tet_face_node_pt[face];
2310  if (old_node_pt == 0)
2311  {
2312  Node* new_node_pt = 0;
2313  if (face.is_boundary_face())
2314  {
2315  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
2316  }
2317  else
2318  {
2319  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
2320  }
2321  tet_face_node_pt[face] = new_node_pt;
2322  Node_pt.push_back(new_node_pt);
2323  Vector<double> s(3);
2324  Vector<double> s_tet(3);
2325  Vector<double> x_tet(3);
2326  el_pt->local_coordinate_of_node(j, s);
2327  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
2328  tet_el_pt->interpolated_x(s_tet, x_tet);
2329  new_node_pt->x(0) = x_tet[0];
2330  new_node_pt->x(1) = x_tet[1];
2331  new_node_pt->x(2) = x_tet[2];
2332  }
2333  // Node already exists
2334  else
2335  {
2336  el_pt->node_pt(j) = old_node_pt;
2337  }
2338  }
2339 
2340 
2341  // Top mid brick-face node -- only built by this element
2342  {
2343  unsigned j = 22;
2344  Node* new_node_pt = el_pt->construct_node(j, time_stepper_pt);
2345  Node_pt.push_back(new_node_pt);
2346  Vector<double> s(3);
2347  Vector<double> s_tet(3);
2348  Vector<double> x_tet(3);
2349  el_pt->local_coordinate_of_node(j, s);
2350  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
2351  top_mid_face_node1_pt = new_node_pt;
2352  tet_el_pt->interpolated_x(s_tet, x_tet);
2353  new_node_pt->x(0) = x_tet[0];
2354  new_node_pt->x(1) = x_tet[1];
2355  new_node_pt->x(2) = x_tet[2];
2356  }
2357 
2358 
2359  // Right mid brick-face node -- only built by this element
2360  {
2361  unsigned j = 14;
2362  Node* new_node_pt = el_pt->construct_node(j, time_stepper_pt);
2363  Node_pt.push_back(new_node_pt);
2364  Vector<double> s(3);
2365  Vector<double> s_tet(3);
2366  Vector<double> x_tet(3);
2367  el_pt->local_coordinate_of_node(j, s);
2368  dummy_q_el_pt[1]->interpolated_s_tet(s, s_tet);
2369  right_mid_face_node1_pt = new_node_pt;
2370  tet_el_pt->interpolated_x(s_tet, x_tet);
2371  new_node_pt->x(0) = x_tet[0];
2372  new_node_pt->x(1) = x_tet[1];
2373  new_node_pt->x(2) = x_tet[2];
2374  }
2375 
2376 
2377  // Back mid brick-face node copy from previous element
2378  {
2379  unsigned j = 16;
2380 
2381  // Always copied
2382  el_pt->node_pt(j) = right_mid_face_node0_pt;
2383  }
2384  }
2385 
2386 
2387  // Third brick element is centred at node 3 of tet:
2388  //-------------------------------------------------
2389  {
2390  // Assign coordinates of dummy element
2391  for (unsigned j = 0; j < 8; j++)
2392  {
2393  Node* nod_pt = dummy_q_el_pt[2]->node_pt(j);
2394  Vector<double> s_tet(3);
2395  Vector<double> x_tet(3);
2396  switch (j)
2397  {
2398  case 0:
2399  tet_el_pt->local_coordinate_of_node(3, s_tet);
2400  nod_pt->set_value(0, s_tet[0]);
2401  nod_pt->set_value(1, s_tet[1]);
2402  nod_pt->set_value(2, s_tet[2]);
2403  tet_el_pt->interpolated_x(s_tet, x_tet);
2404  nod_pt->x(0) = x_tet[0];
2405  nod_pt->x(1) = x_tet[1];
2406  nod_pt->x(2) = x_tet[2];
2407  break;
2408  case 1:
2409  tet_el_pt->local_coordinate_of_node(6, s_tet);
2410  nod_pt->set_value(0, s_tet[0]);
2411  nod_pt->set_value(1, s_tet[1]);
2412  nod_pt->set_value(2, s_tet[2]);
2413  tet_el_pt->interpolated_x(s_tet, x_tet);
2414  nod_pt->x(0) = x_tet[0];
2415  nod_pt->x(1) = x_tet[1];
2416  nod_pt->x(2) = x_tet[2];
2417  break;
2418  case 2:
2419  tet_el_pt->local_coordinate_of_node(9, s_tet);
2420  nod_pt->set_value(0, s_tet[0]);
2421  nod_pt->set_value(1, s_tet[1]);
2422  nod_pt->set_value(2, s_tet[2]);
2423  tet_el_pt->interpolated_x(s_tet, x_tet);
2424  nod_pt->x(0) = x_tet[0];
2425  nod_pt->x(1) = x_tet[1];
2426  nod_pt->x(2) = x_tet[2];
2427  break;
2428  case 3:
2429  // label 13 in initial sketch: Mid face node on face
2430  // spanned by tet nodes 0,1,3
2431  s_tet[0] = 1.0 / 3.0;
2432  s_tet[1] = 1.0 / 3.0;
2433  s_tet[2] = 0.0;
2434  nod_pt->set_value(0, s_tet[0]);
2435  nod_pt->set_value(1, s_tet[1]);
2436  nod_pt->set_value(2, s_tet[2]);
2437  tet_el_pt->interpolated_x(s_tet, x_tet);
2438  nod_pt->x(0) = x_tet[0];
2439  nod_pt->x(1) = x_tet[1];
2440  nod_pt->x(2) = x_tet[2];
2441  break;
2442  case 4:
2443  tet_el_pt->local_coordinate_of_node(8, s_tet);
2444  nod_pt->set_value(0, s_tet[0]);
2445  nod_pt->set_value(1, s_tet[1]);
2446  nod_pt->set_value(2, s_tet[2]);
2447  tet_el_pt->interpolated_x(s_tet, x_tet);
2448  nod_pt->x(0) = x_tet[0];
2449  nod_pt->x(1) = x_tet[1];
2450  nod_pt->x(2) = x_tet[2];
2451  break;
2452  case 5:
2453  // label 12 in initial sketch: Mid face node on face
2454  // spanned by tet nodes 0,2,3
2455  s_tet[0] = 1.0 / 3.0;
2456  s_tet[1] = 0.0;
2457  s_tet[2] = 1.0 / 3.0;
2458  nod_pt->set_value(0, s_tet[0]);
2459  nod_pt->set_value(1, s_tet[1]);
2460  nod_pt->set_value(2, s_tet[2]);
2461  tet_el_pt->interpolated_x(s_tet, x_tet);
2462  nod_pt->x(0) = x_tet[0];
2463  nod_pt->x(1) = x_tet[1];
2464  nod_pt->x(2) = x_tet[2];
2465  break;
2466  case 6:
2467  // label 10 in initial sketch: Mid face node on face
2468  // spanned by tet nodes 1,2,3
2469  s_tet[0] = 0.0;
2470  s_tet[1] = 1.0 / 3.0;
2471  s_tet[2] = 1.0 / 3.0;
2472  nod_pt->set_value(0, s_tet[0]);
2473  nod_pt->set_value(1, s_tet[1]);
2474  nod_pt->set_value(2, s_tet[2]);
2475  tet_el_pt->interpolated_x(s_tet, x_tet);
2476  nod_pt->x(0) = x_tet[0];
2477  nod_pt->x(1) = x_tet[1];
2478  nod_pt->x(2) = x_tet[2];
2479  break;
2480  case 7:
2481  // label 14 in initial sketch: Centroid
2482  s_tet[0] = 0.25;
2483  s_tet[1] = 0.25;
2484  s_tet[2] = 0.25;
2485  nod_pt->set_value(0, s_tet[0]);
2486  nod_pt->set_value(1, s_tet[1]);
2487  nod_pt->set_value(2, s_tet[2]);
2488  tet_el_pt->interpolated_x(s_tet, x_tet);
2489  nod_pt->x(0) = x_tet[0];
2490  nod_pt->x(1) = x_tet[1];
2491  nod_pt->x(2) = x_tet[2];
2492  break;
2493  }
2494  }
2495 
2496 
2497  // Create actual second brick element
2498  FiniteElement* el_pt = new ELEMENT;
2499  brick_el2_pt = el_pt;
2500  Element_pt.push_back(el_pt);
2501 
2502  TFace face0(
2503  tet_el_pt->node_pt(3), tet_el_pt->node_pt(0), tet_el_pt->node_pt(2));
2504 
2505  TFace face1(
2506  tet_el_pt->node_pt(3), tet_el_pt->node_pt(1), tet_el_pt->node_pt(2));
2507 
2508  TFace face2(
2509  tet_el_pt->node_pt(3), tet_el_pt->node_pt(1), tet_el_pt->node_pt(0));
2510 
2511  // Tet vertex nodes along edges emanating from node 0 in brick
2512  Vector<Vector<unsigned>> tet_edge_node(3);
2513  tet_edge_node[0].resize(2);
2514  tet_edge_node[0][0] = 6;
2515  tet_edge_node[0][1] = 0;
2516  tet_edge_node[1].resize(2);
2517  tet_edge_node[1][0] = 9;
2518  tet_edge_node[1][1] = 1;
2519  tet_edge_node[2].resize(2);
2520  tet_edge_node[2][0] = 8;
2521  tet_edge_node[2][1] = 2;
2522 
2523  // Node number of tet vertex that node 0 in brick is centred on
2524  unsigned central_tet_vertex = 3;
2525 
2526  Node* tet_node_pt = 0;
2527  Node* old_node_pt = 0;
2528 
2529  // Corner node
2530  {
2531  unsigned j = 0;
2532 
2533  // Need new node?
2534  tet_node_pt = tet_el_pt->node_pt(central_tet_vertex);
2535  old_node_pt = tet_node_node_pt[tet_node_pt];
2536  if (old_node_pt == 0)
2537  {
2538  Node* new_node_pt = 0;
2539  if (tet_node_pt->is_on_boundary())
2540  {
2541  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
2542  }
2543  else
2544  {
2545  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
2546  }
2547  tet_node_node_pt[tet_node_pt] = new_node_pt;
2548  Node_pt.push_back(new_node_pt);
2549  Vector<double> s(3);
2550  Vector<double> s_tet(3);
2551  Vector<double> x_tet(3);
2552  el_pt->local_coordinate_of_node(j, s);
2553  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
2554  tet_el_pt->interpolated_x(s_tet, x_tet);
2555  new_node_pt->x(0) = x_tet[0];
2556  new_node_pt->x(1) = x_tet[1];
2557  new_node_pt->x(2) = x_tet[2];
2558  }
2559  // Node already exists
2560  else
2561  {
2562  el_pt->node_pt(j) = old_node_pt;
2563  }
2564  }
2565 
2566 
2567  // Brick vertex node coindides with mid-edge node on tet edge 0
2568  {
2569  unsigned j = 2;
2570 
2571  // Need new node?
2572  tet_node_pt = tet_el_pt->node_pt(tet_edge_node[0][0]);
2573  old_node_pt = tet_node_node_pt[tet_node_pt];
2574  if (old_node_pt == 0)
2575  {
2576  Node* new_node_pt = 0;
2577  if (tet_node_pt->is_on_boundary())
2578  {
2579  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
2580  }
2581  else
2582  {
2583  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
2584  }
2585  tet_node_node_pt[tet_node_pt] = new_node_pt;
2586  Node_pt.push_back(new_node_pt);
2587  Vector<double> s(3);
2588  Vector<double> s_tet(3);
2589  Vector<double> x_tet(3);
2590  el_pt->local_coordinate_of_node(j, s);
2591  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
2592  tet_el_pt->interpolated_x(s_tet, x_tet);
2593  new_node_pt->x(0) = x_tet[0];
2594  new_node_pt->x(1) = x_tet[1];
2595  new_node_pt->x(2) = x_tet[2];
2596  }
2597  // Node already exists
2598  else
2599  {
2600  el_pt->node_pt(j) = old_node_pt;
2601  }
2602  }
2603 
2604 
2605  // Brick vertex node coindides with mid vertex node of tet edge 1
2606  {
2607  unsigned j = 6;
2608 
2609  // Need new node?
2610  tet_node_pt = tet_el_pt->node_pt(tet_edge_node[1][0]);
2611  old_node_pt = tet_node_node_pt[tet_node_pt];
2612  if (old_node_pt == 0)
2613  {
2614  Node* new_node_pt = 0;
2615  if (tet_node_pt->is_on_boundary())
2616  {
2617  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
2618  }
2619  else
2620  {
2621  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
2622  }
2623  tet_node_node_pt[tet_node_pt] = new_node_pt;
2624  Node_pt.push_back(new_node_pt);
2625  Vector<double> s(3);
2626  Vector<double> s_tet(3);
2627  Vector<double> x_tet(3);
2628  el_pt->local_coordinate_of_node(j, s);
2629  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
2630  tet_el_pt->interpolated_x(s_tet, x_tet);
2631  new_node_pt->x(0) = x_tet[0];
2632  new_node_pt->x(1) = x_tet[1];
2633  new_node_pt->x(2) = x_tet[2];
2634  }
2635  // Node already exists
2636  else
2637  {
2638  el_pt->node_pt(j) = old_node_pt;
2639  }
2640  }
2641 
2642 
2643  // Brick vertex node coindides with mid-vertex node of tet edge 2
2644  {
2645  unsigned j = 18;
2646 
2647  // Need new node?
2648  tet_node_pt = tet_el_pt->node_pt(tet_edge_node[2][0]);
2649  old_node_pt = tet_node_node_pt[tet_node_pt];
2650  if (old_node_pt == 0)
2651  {
2652  Node* new_node_pt = 0;
2653  if (tet_node_pt->is_on_boundary())
2654  {
2655  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
2656  }
2657  else
2658  {
2659  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
2660  }
2661  tet_node_node_pt[tet_node_pt] = new_node_pt;
2662  Node_pt.push_back(new_node_pt);
2663  Vector<double> s(3);
2664  Vector<double> s_tet(3);
2665  Vector<double> x_tet(3);
2666  el_pt->local_coordinate_of_node(j, s);
2667  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
2668  tet_el_pt->interpolated_x(s_tet, x_tet);
2669  new_node_pt->x(0) = x_tet[0];
2670  new_node_pt->x(1) = x_tet[1];
2671  new_node_pt->x(2) = x_tet[2];
2672  }
2673  // Node already exists
2674  else
2675  {
2676  el_pt->node_pt(j) = old_node_pt;
2677  }
2678  }
2679 
2680 
2681  // Brick vertex node in the middle of tet face0
2682  {
2683  unsigned j = 20;
2684 
2685  // Need new node?
2686  old_node_pt = tet_face_node_pt[face0];
2687  if (old_node_pt == 0)
2688  {
2689  Node* new_node_pt = 0;
2690  if (face0.is_boundary_face())
2691  {
2692  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
2693  }
2694  else
2695  {
2696  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
2697  }
2698  tet_face_node_pt[face0] = new_node_pt;
2699  Node_pt.push_back(new_node_pt);
2700  Vector<double> s(3);
2701  Vector<double> s_tet(3);
2702  Vector<double> x_tet(3);
2703  el_pt->local_coordinate_of_node(j, s);
2704  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
2705  tet_el_pt->interpolated_x(s_tet, x_tet);
2706  new_node_pt->x(0) = x_tet[0];
2707  new_node_pt->x(1) = x_tet[1];
2708  new_node_pt->x(2) = x_tet[2];
2709  }
2710  // Node already exists
2711  else
2712  {
2713  el_pt->node_pt(j) = old_node_pt;
2714  }
2715  }
2716 
2717  // Brick vertex node in the middle of tet face1
2718  {
2719  unsigned j = 24;
2720 
2721  // Need new node?
2722  old_node_pt = tet_face_node_pt[face1];
2723  if (old_node_pt == 0)
2724  {
2725  Node* new_node_pt = 0;
2726  if (face1.is_boundary_face())
2727  {
2728  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
2729  }
2730  else
2731  {
2732  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
2733  }
2734  tet_face_node_pt[face1] = new_node_pt;
2735  Node_pt.push_back(new_node_pt);
2736  Vector<double> s(3);
2737  Vector<double> s_tet(3);
2738  Vector<double> x_tet(3);
2739  el_pt->local_coordinate_of_node(j, s);
2740  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
2741  tet_el_pt->interpolated_x(s_tet, x_tet);
2742  new_node_pt->x(0) = x_tet[0];
2743  new_node_pt->x(1) = x_tet[1];
2744  new_node_pt->x(2) = x_tet[2];
2745  }
2746  // Node already exists
2747  else
2748  {
2749  el_pt->node_pt(j) = old_node_pt;
2750  }
2751  }
2752 
2753  // Brick vertex node in the middle of tet face2
2754  {
2755  unsigned j = 8;
2756 
2757  // Need new node?
2758  old_node_pt = tet_face_node_pt[face2];
2759  if (old_node_pt == 0)
2760  {
2761  Node* new_node_pt = 0;
2762  if (face2.is_boundary_face())
2763  {
2764  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
2765  }
2766  else
2767  {
2768  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
2769  }
2770  tet_face_node_pt[face2] = new_node_pt;
2771  Node_pt.push_back(new_node_pt);
2772  Vector<double> s(3);
2773  Vector<double> s_tet(3);
2774  Vector<double> x_tet(3);
2775  el_pt->local_coordinate_of_node(j, s);
2776  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
2777  tet_el_pt->interpolated_x(s_tet, x_tet);
2778  new_node_pt->x(0) = x_tet[0];
2779  new_node_pt->x(1) = x_tet[1];
2780  new_node_pt->x(2) = x_tet[2];
2781  }
2782  // Node already exists
2783  else
2784  {
2785  el_pt->node_pt(j) = old_node_pt;
2786  }
2787  }
2788 
2789 
2790  // Brick vertex node in centroid of tet. Only built for first element.
2791  // Enumerated "13" in initial sketch.
2792  {
2793  unsigned j = 26;
2794 
2795  // Always copied
2796  el_pt->node_pt(j) = centroid_node_pt;
2797  }
2798 
2799 
2800  // Internal brick node -- always built
2801  {
2802  unsigned j = 13;
2803 
2804  // Always new
2805  {
2806  Node* new_node_pt = el_pt->construct_node(j, time_stepper_pt);
2807  Node_pt.push_back(new_node_pt);
2808  Vector<double> s(3);
2809  Vector<double> s_tet(3);
2810  Vector<double> x_tet(3);
2811  el_pt->local_coordinate_of_node(j, s);
2812  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
2813  tet_el_pt->interpolated_x(s_tet, x_tet);
2814  new_node_pt->x(0) = x_tet[0];
2815  new_node_pt->x(1) = x_tet[1];
2816  new_node_pt->x(2) = x_tet[2];
2817  }
2818  }
2819 
2820  // Brick edge node between brick nodes 0 and 2
2821  {
2822  unsigned j = 1;
2823 
2824  // Need new node?
2825  Edge edge(el_pt->node_pt(0), el_pt->node_pt(2));
2826  old_node_pt = brick_edge_node_pt[edge];
2827  if (old_node_pt == 0)
2828  {
2829  Node* new_node_pt = 0;
2830  if (edge.is_boundary_edge())
2831  {
2832  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
2833  }
2834  else
2835  {
2836  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
2837  }
2838  brick_edge_node_pt[edge] = new_node_pt;
2839  Node_pt.push_back(new_node_pt);
2840  Vector<double> s(3);
2841  Vector<double> s_tet(3);
2842  Vector<double> x_tet(3);
2843  el_pt->local_coordinate_of_node(j, s);
2844  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
2845  tet_el_pt->interpolated_x(s_tet, x_tet);
2846  new_node_pt->x(0) = x_tet[0];
2847  new_node_pt->x(1) = x_tet[1];
2848  new_node_pt->x(2) = x_tet[2];
2849  }
2850  // Node already exists
2851  else
2852  {
2853  el_pt->node_pt(j) = old_node_pt;
2854  }
2855  }
2856 
2857 
2858  // Brick edge node between brick nodes 0 and 6
2859  {
2860  unsigned j = 3;
2861 
2862  // Need new node?
2863  Edge edge(el_pt->node_pt(0), el_pt->node_pt(6));
2864  old_node_pt = brick_edge_node_pt[edge];
2865  if (old_node_pt == 0)
2866  {
2867  Node* new_node_pt = 0;
2868  if (edge.is_boundary_edge())
2869  {
2870  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
2871  }
2872  else
2873  {
2874  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
2875  }
2876  brick_edge_node_pt[edge] = new_node_pt;
2877  Node_pt.push_back(new_node_pt);
2878  Vector<double> s(3);
2879  Vector<double> s_tet(3);
2880  Vector<double> x_tet(3);
2881  el_pt->local_coordinate_of_node(j, s);
2882  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
2883  tet_el_pt->interpolated_x(s_tet, x_tet);
2884  new_node_pt->x(0) = x_tet[0];
2885  new_node_pt->x(1) = x_tet[1];
2886  new_node_pt->x(2) = x_tet[2];
2887  }
2888  // Node already exists
2889  else
2890  {
2891  el_pt->node_pt(j) = old_node_pt;
2892  }
2893  }
2894 
2895  // Brick edge node between brick nodes 2 and 8
2896  {
2897  unsigned j = 5;
2898 
2899  // Need new node?
2900  Edge edge(el_pt->node_pt(2), el_pt->node_pt(8));
2901  old_node_pt = brick_edge_node_pt[edge];
2902  if (old_node_pt == 0)
2903  {
2904  Node* new_node_pt = 0;
2905  if (edge.is_boundary_edge())
2906  {
2907  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
2908  }
2909  else
2910  {
2911  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
2912  }
2913  brick_edge_node_pt[edge] = new_node_pt;
2914  Node_pt.push_back(new_node_pt);
2915  Vector<double> s(3);
2916  Vector<double> s_tet(3);
2917  Vector<double> x_tet(3);
2918  el_pt->local_coordinate_of_node(j, s);
2919  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
2920  tet_el_pt->interpolated_x(s_tet, x_tet);
2921  new_node_pt->x(0) = x_tet[0];
2922  new_node_pt->x(1) = x_tet[1];
2923  new_node_pt->x(2) = x_tet[2];
2924  }
2925  // Node already exists
2926  else
2927  {
2928  el_pt->node_pt(j) = old_node_pt;
2929  }
2930  }
2931 
2932  // Brick edge node between brick nodes 6 and 8
2933  {
2934  unsigned j = 7;
2935 
2936  // Need new node?
2937  Edge edge(el_pt->node_pt(6), el_pt->node_pt(8));
2938  old_node_pt = brick_edge_node_pt[edge];
2939  if (old_node_pt == 0)
2940  {
2941  Node* new_node_pt = 0;
2942  if (edge.is_boundary_edge())
2943  {
2944  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
2945  }
2946  else
2947  {
2948  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
2949  }
2950  brick_edge_node_pt[edge] = new_node_pt;
2951  Node_pt.push_back(new_node_pt);
2952  Vector<double> s(3);
2953  Vector<double> s_tet(3);
2954  Vector<double> x_tet(3);
2955  el_pt->local_coordinate_of_node(j, s);
2956  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
2957  tet_el_pt->interpolated_x(s_tet, x_tet);
2958  new_node_pt->x(0) = x_tet[0];
2959  new_node_pt->x(1) = x_tet[1];
2960  new_node_pt->x(2) = x_tet[2];
2961  }
2962  // Node already exists
2963  else
2964  {
2965  el_pt->node_pt(j) = old_node_pt;
2966  }
2967  }
2968 
2969  // Brick edge node between brick nodes 18 and 20
2970  {
2971  unsigned j = 19;
2972 
2973  // Need new node?
2974  Edge edge(el_pt->node_pt(18), el_pt->node_pt(20));
2975  old_node_pt = brick_edge_node_pt[edge];
2976  if (old_node_pt == 0)
2977  {
2978  Node* new_node_pt = 0;
2979  if (edge.is_boundary_edge())
2980  {
2981  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
2982  }
2983  else
2984  {
2985  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
2986  }
2987  brick_edge_node_pt[edge] = new_node_pt;
2988  Node_pt.push_back(new_node_pt);
2989  Vector<double> s(3);
2990  Vector<double> s_tet(3);
2991  Vector<double> x_tet(3);
2992  el_pt->local_coordinate_of_node(j, s);
2993  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
2994  tet_el_pt->interpolated_x(s_tet, x_tet);
2995  new_node_pt->x(0) = x_tet[0];
2996  new_node_pt->x(1) = x_tet[1];
2997  new_node_pt->x(2) = x_tet[2];
2998  }
2999  // Node already exists
3000  else
3001  {
3002  el_pt->node_pt(j) = old_node_pt;
3003  }
3004  }
3005 
3006 
3007  // Brick edge node between brick nodes 18 and 24
3008  {
3009  unsigned j = 21;
3010 
3011  // Need new node?
3012  Edge edge(el_pt->node_pt(18), el_pt->node_pt(24));
3013  old_node_pt = brick_edge_node_pt[edge];
3014  if (old_node_pt == 0)
3015  {
3016  Node* new_node_pt = 0;
3017  if (edge.is_boundary_edge())
3018  {
3019  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
3020  }
3021  else
3022  {
3023  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
3024  }
3025  brick_edge_node_pt[edge] = new_node_pt;
3026  Node_pt.push_back(new_node_pt);
3027  Vector<double> s(3);
3028  Vector<double> s_tet(3);
3029  Vector<double> x_tet(3);
3030  el_pt->local_coordinate_of_node(j, s);
3031  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
3032  tet_el_pt->interpolated_x(s_tet, x_tet);
3033  new_node_pt->x(0) = x_tet[0];
3034  new_node_pt->x(1) = x_tet[1];
3035  new_node_pt->x(2) = x_tet[2];
3036  }
3037  // Node already exists
3038  else
3039  {
3040  el_pt->node_pt(j) = old_node_pt;
3041  }
3042  }
3043 
3044  // Brick edge node between brick nodes 20 and 26
3045  {
3046  unsigned j = 23;
3047 
3048  // Need new node?
3049  Edge edge(el_pt->node_pt(20), el_pt->node_pt(26));
3050  old_node_pt = brick_edge_node_pt[edge];
3051  if (old_node_pt == 0)
3052  {
3053  Node* new_node_pt = 0;
3054  if (edge.is_boundary_edge())
3055  {
3056  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
3057  }
3058  else
3059  {
3060  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
3061  }
3062  brick_edge_node_pt[edge] = new_node_pt;
3063  Node_pt.push_back(new_node_pt);
3064  Vector<double> s(3);
3065  Vector<double> s_tet(3);
3066  Vector<double> x_tet(3);
3067  el_pt->local_coordinate_of_node(j, s);
3068  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
3069  tet_el_pt->interpolated_x(s_tet, x_tet);
3070  new_node_pt->x(0) = x_tet[0];
3071  new_node_pt->x(1) = x_tet[1];
3072  new_node_pt->x(2) = x_tet[2];
3073  }
3074  // Node already exists
3075  else
3076  {
3077  el_pt->node_pt(j) = old_node_pt;
3078  }
3079  }
3080 
3081 
3082  // Brick edge node between brick nodes 24 and 26
3083  {
3084  unsigned j = 25;
3085 
3086  // Need new node?
3087  Edge edge(el_pt->node_pt(24), el_pt->node_pt(26));
3088  old_node_pt = brick_edge_node_pt[edge];
3089  if (old_node_pt == 0)
3090  {
3091  Node* new_node_pt = 0;
3092  if (edge.is_boundary_edge())
3093  {
3094  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
3095  }
3096  else
3097  {
3098  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
3099  }
3100  brick_edge_node_pt[edge] = new_node_pt;
3101  Node_pt.push_back(new_node_pt);
3102  Vector<double> s(3);
3103  Vector<double> s_tet(3);
3104  Vector<double> x_tet(3);
3105  el_pt->local_coordinate_of_node(j, s);
3106  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
3107  tet_el_pt->interpolated_x(s_tet, x_tet);
3108  new_node_pt->x(0) = x_tet[0];
3109  new_node_pt->x(1) = x_tet[1];
3110  new_node_pt->x(2) = x_tet[2];
3111  }
3112  // Node already exists
3113  else
3114  {
3115  el_pt->node_pt(j) = old_node_pt;
3116  }
3117  }
3118 
3119  // Brick edge node between brick nodes 0 and 18
3120  {
3121  unsigned j = 9;
3122 
3123  // Need new node?
3124  Edge edge(el_pt->node_pt(0), el_pt->node_pt(18));
3125  old_node_pt = brick_edge_node_pt[edge];
3126  if (old_node_pt == 0)
3127  {
3128  Node* new_node_pt = 0;
3129  if (edge.is_boundary_edge())
3130  {
3131  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
3132  }
3133  else
3134  {
3135  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
3136  }
3137  brick_edge_node_pt[edge] = new_node_pt;
3138  Node_pt.push_back(new_node_pt);
3139  Vector<double> s(3);
3140  Vector<double> s_tet(3);
3141  Vector<double> x_tet(3);
3142  el_pt->local_coordinate_of_node(j, s);
3143  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
3144  tet_el_pt->interpolated_x(s_tet, x_tet);
3145  new_node_pt->x(0) = x_tet[0];
3146  new_node_pt->x(1) = x_tet[1];
3147  new_node_pt->x(2) = x_tet[2];
3148  }
3149  // Node already exists
3150  else
3151  {
3152  el_pt->node_pt(j) = old_node_pt;
3153  }
3154  }
3155 
3156 
3157  // Brick edge node between brick nodes 2 and 20
3158  {
3159  unsigned j = 11;
3160 
3161  // Need new node?
3162  Edge edge(el_pt->node_pt(2), el_pt->node_pt(20));
3163  old_node_pt = brick_edge_node_pt[edge];
3164  if (old_node_pt == 0)
3165  {
3166  Node* new_node_pt = 0;
3167  if (edge.is_boundary_edge())
3168  {
3169  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
3170  }
3171  else
3172  {
3173  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
3174  }
3175  brick_edge_node_pt[edge] = new_node_pt;
3176  Node_pt.push_back(new_node_pt);
3177  Vector<double> s(3);
3178  Vector<double> s_tet(3);
3179  Vector<double> x_tet(3);
3180  el_pt->local_coordinate_of_node(j, s);
3181  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
3182  tet_el_pt->interpolated_x(s_tet, x_tet);
3183  new_node_pt->x(0) = x_tet[0];
3184  new_node_pt->x(1) = x_tet[1];
3185  new_node_pt->x(2) = x_tet[2];
3186  }
3187  // Node already exists
3188  else
3189  {
3190  el_pt->node_pt(j) = old_node_pt;
3191  }
3192  }
3193 
3194 
3195  // Brick edge node between brick nodes 6 and 24
3196  {
3197  unsigned j = 15;
3198 
3199  // Need new node?
3200  Edge edge(el_pt->node_pt(6), el_pt->node_pt(24));
3201  old_node_pt = brick_edge_node_pt[edge];
3202  if (old_node_pt == 0)
3203  {
3204  Node* new_node_pt = 0;
3205  if (edge.is_boundary_edge())
3206  {
3207  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
3208  }
3209  else
3210  {
3211  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
3212  }
3213  brick_edge_node_pt[edge] = new_node_pt;
3214  Node_pt.push_back(new_node_pt);
3215  Vector<double> s(3);
3216  Vector<double> s_tet(3);
3217  Vector<double> x_tet(3);
3218  el_pt->local_coordinate_of_node(j, s);
3219  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
3220  tet_el_pt->interpolated_x(s_tet, x_tet);
3221  new_node_pt->x(0) = x_tet[0];
3222  new_node_pt->x(1) = x_tet[1];
3223  new_node_pt->x(2) = x_tet[2];
3224  }
3225  // Node already exists
3226  else
3227  {
3228  el_pt->node_pt(j) = old_node_pt;
3229  }
3230  }
3231 
3232 
3233  // Brick edge node between brick nodes 8 and 26
3234  {
3235  unsigned j = 17;
3236 
3237  // Need new node?
3238  Edge edge(el_pt->node_pt(8), el_pt->node_pt(26));
3239  old_node_pt = brick_edge_node_pt[edge];
3240  if (old_node_pt == 0)
3241  {
3242  Node* new_node_pt = 0;
3243  if (edge.is_boundary_edge())
3244  {
3245  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
3246  }
3247  else
3248  {
3249  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
3250  }
3251  brick_edge_node_pt[edge] = new_node_pt;
3252  Node_pt.push_back(new_node_pt);
3253  Vector<double> s(3);
3254  Vector<double> s_tet(3);
3255  Vector<double> x_tet(3);
3256  el_pt->local_coordinate_of_node(j, s);
3257  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
3258  tet_el_pt->interpolated_x(s_tet, x_tet);
3259  new_node_pt->x(0) = x_tet[0];
3260  new_node_pt->x(1) = x_tet[1];
3261  new_node_pt->x(2) = x_tet[2];
3262  }
3263  // Node already exists
3264  else
3265  {
3266  el_pt->node_pt(j) = old_node_pt;
3267  }
3268  }
3269 
3270 
3271  // Mid brick-face node associated with face
3272  // spanned by mid-vertex nodes associated with tet edges 0 and 2
3273  {
3274  unsigned j = 10;
3275 
3276  // Need new node?
3277  TFace face(tet_el_pt->node_pt(central_tet_vertex),
3278  tet_el_pt->node_pt(tet_edge_node[0][0]),
3279  tet_el_pt->node_pt(tet_edge_node[2][0]));
3280 
3281  old_node_pt = tet_face_node_pt[face];
3282  if (old_node_pt == 0)
3283  {
3284  Node* new_node_pt = 0;
3285  if (face.is_boundary_face())
3286  {
3287  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
3288  }
3289  else
3290  {
3291  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
3292  }
3293  tet_face_node_pt[face] = new_node_pt;
3294  Node_pt.push_back(new_node_pt);
3295  Vector<double> s(3);
3296  Vector<double> s_tet(3);
3297  Vector<double> x_tet(3);
3298  el_pt->local_coordinate_of_node(j, s);
3299  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
3300  tet_el_pt->interpolated_x(s_tet, x_tet);
3301  new_node_pt->x(0) = x_tet[0];
3302  new_node_pt->x(1) = x_tet[1];
3303  new_node_pt->x(2) = x_tet[2];
3304  }
3305  // Node already exists
3306  else
3307  {
3308  el_pt->node_pt(j) = old_node_pt;
3309  }
3310  }
3311 
3312 
3313  // Mid brick-face node associated with face
3314  // spanned by mid-vertex nodes associated with tet edges 1 and 2
3315  {
3316  unsigned j = 12;
3317 
3318  // Need new node?
3319  TFace face(tet_el_pt->node_pt(central_tet_vertex),
3320  tet_el_pt->node_pt(tet_edge_node[1][0]),
3321  tet_el_pt->node_pt(tet_edge_node[2][0]));
3322  old_node_pt = tet_face_node_pt[face];
3323  if (old_node_pt == 0)
3324  {
3325  Node* new_node_pt = 0;
3326  if (face.is_boundary_face())
3327  {
3328  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
3329  }
3330  else
3331  {
3332  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
3333  }
3334  tet_face_node_pt[face] = new_node_pt;
3335  Node_pt.push_back(new_node_pt);
3336  Vector<double> s(3);
3337  Vector<double> s_tet(3);
3338  Vector<double> x_tet(3);
3339  el_pt->local_coordinate_of_node(j, s);
3340  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
3341  tet_el_pt->interpolated_x(s_tet, x_tet);
3342  new_node_pt->x(0) = x_tet[0];
3343  new_node_pt->x(1) = x_tet[1];
3344  new_node_pt->x(2) = x_tet[2];
3345  }
3346  // Node already exists
3347  else
3348  {
3349  el_pt->node_pt(j) = old_node_pt;
3350  }
3351  }
3352 
3353 
3354  // Mid brick-face node associated with face
3355  // spanned by mid-vertex nodes associated with tet edges 0 and 1
3356  {
3357  unsigned j = 4;
3358 
3359  // Need new node?
3360  TFace face(tet_el_pt->node_pt(central_tet_vertex),
3361  tet_el_pt->node_pt(tet_edge_node[0][0]),
3362  tet_el_pt->node_pt(tet_edge_node[1][0]));
3363 
3364  old_node_pt = tet_face_node_pt[face];
3365  if (old_node_pt == 0)
3366  {
3367  Node* new_node_pt = 0;
3368  if (face.is_boundary_face())
3369  {
3370  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
3371  }
3372  else
3373  {
3374  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
3375  }
3376  tet_face_node_pt[face] = new_node_pt;
3377  Node_pt.push_back(new_node_pt);
3378  Vector<double> s(3);
3379  Vector<double> s_tet(3);
3380  Vector<double> x_tet(3);
3381  el_pt->local_coordinate_of_node(j, s);
3382  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
3383  tet_el_pt->interpolated_x(s_tet, x_tet);
3384  new_node_pt->x(0) = x_tet[0];
3385  new_node_pt->x(1) = x_tet[1];
3386  new_node_pt->x(2) = x_tet[2];
3387  }
3388  // Node already exists
3389  else
3390  {
3391  el_pt->node_pt(j) = old_node_pt;
3392  }
3393  }
3394 
3395 
3396  // Top mid brick-face node -- only built by this element
3397  {
3398  unsigned j = 22;
3399  Node* new_node_pt = el_pt->construct_node(j, time_stepper_pt);
3400  Node_pt.push_back(new_node_pt);
3401  Vector<double> s(3);
3402  Vector<double> s_tet(3);
3403  Vector<double> x_tet(3);
3404  el_pt->local_coordinate_of_node(j, s);
3405  dummy_q_el_pt[2]->interpolated_s_tet(s, s_tet);
3406  top_mid_face_node2_pt = new_node_pt;
3407  tet_el_pt->interpolated_x(s_tet, x_tet);
3408  new_node_pt->x(0) = x_tet[0];
3409  new_node_pt->x(1) = x_tet[1];
3410  new_node_pt->x(2) = x_tet[2];
3411  }
3412 
3413 
3414  // Right mid brick-face node copy from first element
3415  {
3416  unsigned j = 14;
3417 
3418  // Always copied
3419  el_pt->node_pt(j) = back_mid_face_node0_pt;
3420  }
3421 
3422 
3423  // Back mid brick-face node copy from previous element
3424  {
3425  unsigned j = 16;
3426 
3427  // Always copied
3428  el_pt->node_pt(j) = right_mid_face_node1_pt;
3429  }
3430  }
3431 
3432 
3433  // Fourth brick element is centred at node 2 of tet:
3434  //--------------------------------------------------
3435  {
3436  // Assign coordinates of dummy element
3437  for (unsigned j = 0; j < 8; j++)
3438  {
3439  Node* nod_pt = dummy_q_el_pt[3]->node_pt(j);
3440  Vector<double> s_tet(3);
3441  Vector<double> x_tet(3);
3442  switch (j)
3443  {
3444  case 0:
3445  tet_el_pt->local_coordinate_of_node(2, s_tet);
3446  nod_pt->set_value(0, s_tet[0]);
3447  nod_pt->set_value(1, s_tet[1]);
3448  nod_pt->set_value(2, s_tet[2]);
3449  tet_el_pt->interpolated_x(s_tet, x_tet);
3450  nod_pt->x(0) = x_tet[0];
3451  nod_pt->x(1) = x_tet[1];
3452  nod_pt->x(2) = x_tet[2];
3453  break;
3454  case 1:
3455  tet_el_pt->local_coordinate_of_node(7, s_tet);
3456  nod_pt->set_value(0, s_tet[0]);
3457  nod_pt->set_value(1, s_tet[1]);
3458  nod_pt->set_value(2, s_tet[2]);
3459  tet_el_pt->interpolated_x(s_tet, x_tet);
3460  nod_pt->x(0) = x_tet[0];
3461  nod_pt->x(1) = x_tet[1];
3462  nod_pt->x(2) = x_tet[2];
3463  break;
3464  case 2:
3465  tet_el_pt->local_coordinate_of_node(5, s_tet);
3466  nod_pt->set_value(0, s_tet[0]);
3467  nod_pt->set_value(1, s_tet[1]);
3468  nod_pt->set_value(2, s_tet[2]);
3469  tet_el_pt->interpolated_x(s_tet, x_tet);
3470  nod_pt->x(0) = x_tet[0];
3471  nod_pt->x(1) = x_tet[1];
3472  nod_pt->x(2) = x_tet[2];
3473  break;
3474  case 3:
3475  // label 11 in initial sketch: Mid face node on face
3476  // spanned by tet nodes 0,1,2
3477  s_tet[0] = 1.0 / 3.0;
3478  s_tet[1] = 1.0 / 3.0;
3479  s_tet[2] = 1.0 / 3.0;
3480  nod_pt->set_value(0, s_tet[0]);
3481  nod_pt->set_value(1, s_tet[1]);
3482  nod_pt->set_value(2, s_tet[2]);
3483  tet_el_pt->interpolated_x(s_tet, x_tet);
3484  nod_pt->x(0) = x_tet[0];
3485  nod_pt->x(1) = x_tet[1];
3486  nod_pt->x(2) = x_tet[2];
3487  break;
3488  case 4:
3489  tet_el_pt->local_coordinate_of_node(8, s_tet);
3490  nod_pt->set_value(0, s_tet[0]);
3491  nod_pt->set_value(1, s_tet[1]);
3492  nod_pt->set_value(2, s_tet[2]);
3493  tet_el_pt->interpolated_x(s_tet, x_tet);
3494  nod_pt->x(0) = x_tet[0];
3495  nod_pt->x(1) = x_tet[1];
3496  nod_pt->x(2) = x_tet[2];
3497  break;
3498  case 5:
3499  // label 10 in initial sketch: Mid face node on face
3500  // spanned by tet nodes 0,2,3
3501  s_tet[0] = 0.0;
3502  s_tet[1] = 1.0 / 3.0;
3503  s_tet[2] = 1.0 / 3.0;
3504  nod_pt->set_value(0, s_tet[0]);
3505  nod_pt->set_value(1, s_tet[1]);
3506  nod_pt->set_value(2, s_tet[2]);
3507  tet_el_pt->interpolated_x(s_tet, x_tet);
3508  nod_pt->x(0) = x_tet[0];
3509  nod_pt->x(1) = x_tet[1];
3510  nod_pt->x(2) = x_tet[2];
3511  break;
3512  case 6:
3513  // label 12 in initial sketch: Mid face node on face
3514  // spanned by tet nodes 0,2,3
3515  s_tet[0] = 1.0 / 3.0;
3516  s_tet[1] = 0.0;
3517  s_tet[2] = 1.0 / 3.0;
3518  nod_pt->set_value(0, s_tet[0]);
3519  nod_pt->set_value(1, s_tet[1]);
3520  nod_pt->set_value(2, s_tet[2]);
3521  tet_el_pt->interpolated_x(s_tet, x_tet);
3522  nod_pt->x(0) = x_tet[0];
3523  nod_pt->x(1) = x_tet[1];
3524  nod_pt->x(2) = x_tet[2];
3525  break;
3526  case 7:
3527  // label 14 in initial sketch: Centroid
3528  s_tet[0] = 0.25;
3529  s_tet[1] = 0.25;
3530  s_tet[2] = 0.25;
3531  nod_pt->set_value(0, s_tet[0]);
3532  nod_pt->set_value(1, s_tet[1]);
3533  nod_pt->set_value(2, s_tet[2]);
3534  tet_el_pt->interpolated_x(s_tet, x_tet);
3535  nod_pt->x(0) = x_tet[0];
3536  nod_pt->x(1) = x_tet[1];
3537  nod_pt->x(2) = x_tet[2];
3538  break;
3539  }
3540  }
3541 
3542 
3543  // Create actual third brick element
3544  FiniteElement* el_pt = new ELEMENT;
3545  brick_el3_pt = el_pt;
3546  Element_pt.push_back(el_pt);
3547 
3548  TFace face0(
3549  tet_el_pt->node_pt(1), tet_el_pt->node_pt(2), tet_el_pt->node_pt(3));
3550 
3551  TFace face1(
3552  tet_el_pt->node_pt(0), tet_el_pt->node_pt(2), tet_el_pt->node_pt(3));
3553 
3554  TFace face2(
3555  tet_el_pt->node_pt(0), tet_el_pt->node_pt(1), tet_el_pt->node_pt(2));
3556 
3557  // Tet vertex nodes along edges emanating from node 0 in brick
3558  Vector<Vector<unsigned>> tet_edge_node(3);
3559  tet_edge_node[0].resize(2);
3560  tet_edge_node[0][0] = 7;
3561  tet_edge_node[0][1] = 1;
3562  tet_edge_node[1].resize(2);
3563  tet_edge_node[1][0] = 5;
3564  tet_edge_node[1][1] = 0;
3565  tet_edge_node[2].resize(2);
3566  tet_edge_node[2][0] = 8;
3567  tet_edge_node[2][1] = 3;
3568 
3569  // Node number of tet vertex that node 0 in brick is centred on
3570  unsigned central_tet_vertex = 2;
3571 
3572  Node* tet_node_pt = 0;
3573  Node* old_node_pt = 0;
3574 
3575  // Corner node
3576  {
3577  unsigned j = 0;
3578 
3579  // Need new node?
3580  tet_node_pt = tet_el_pt->node_pt(central_tet_vertex);
3581  old_node_pt = tet_node_node_pt[tet_node_pt];
3582  if (old_node_pt == 0)
3583  {
3584  Node* new_node_pt = 0;
3585  if (tet_node_pt->is_on_boundary())
3586  {
3587  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
3588  }
3589  else
3590  {
3591  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
3592  }
3593  tet_node_node_pt[tet_node_pt] = new_node_pt;
3594  Node_pt.push_back(new_node_pt);
3595  Vector<double> s(3);
3596  Vector<double> s_tet(3);
3597  Vector<double> x_tet(3);
3598  el_pt->local_coordinate_of_node(j, s);
3599  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
3600  tet_el_pt->interpolated_x(s_tet, x_tet);
3601  new_node_pt->x(0) = x_tet[0];
3602  new_node_pt->x(1) = x_tet[1];
3603  new_node_pt->x(2) = x_tet[2];
3604  }
3605  // Node already exists
3606  else
3607  {
3608  el_pt->node_pt(j) = old_node_pt;
3609  }
3610  }
3611 
3612 
3613  // Brick vertex node coindides with mid-edge node on tet edge 0
3614  {
3615  unsigned j = 2;
3616 
3617  // Need new node?
3618  tet_node_pt = tet_el_pt->node_pt(tet_edge_node[0][0]);
3619  old_node_pt = tet_node_node_pt[tet_node_pt];
3620  if (old_node_pt == 0)
3621  {
3622  Node* new_node_pt = 0;
3623  if (tet_node_pt->is_on_boundary())
3624  {
3625  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
3626  }
3627  else
3628  {
3629  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
3630  }
3631  tet_node_node_pt[tet_node_pt] = new_node_pt;
3632  Node_pt.push_back(new_node_pt);
3633  Vector<double> s(3);
3634  Vector<double> s_tet(3);
3635  Vector<double> x_tet(3);
3636  el_pt->local_coordinate_of_node(j, s);
3637  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
3638  tet_el_pt->interpolated_x(s_tet, x_tet);
3639  new_node_pt->x(0) = x_tet[0];
3640  new_node_pt->x(1) = x_tet[1];
3641  new_node_pt->x(2) = x_tet[2];
3642  }
3643  // Node already exists
3644  else
3645  {
3646  el_pt->node_pt(j) = old_node_pt;
3647  }
3648  }
3649 
3650 
3651  // Brick vertex node coindides with mid vertex node of tet edge 1
3652  {
3653  unsigned j = 6;
3654 
3655  // Need new node?
3656  tet_node_pt = tet_el_pt->node_pt(tet_edge_node[1][0]);
3657  old_node_pt = tet_node_node_pt[tet_node_pt];
3658  if (old_node_pt == 0)
3659  {
3660  Node* new_node_pt = 0;
3661  if (tet_node_pt->is_on_boundary())
3662  {
3663  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
3664  }
3665  else
3666  {
3667  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
3668  }
3669  tet_node_node_pt[tet_node_pt] = new_node_pt;
3670  Node_pt.push_back(new_node_pt);
3671  Vector<double> s(3);
3672  Vector<double> s_tet(3);
3673  Vector<double> x_tet(3);
3674  el_pt->local_coordinate_of_node(j, s);
3675  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
3676  tet_el_pt->interpolated_x(s_tet, x_tet);
3677  new_node_pt->x(0) = x_tet[0];
3678  new_node_pt->x(1) = x_tet[1];
3679  new_node_pt->x(2) = x_tet[2];
3680  }
3681  // Node already exists
3682  else
3683  {
3684  el_pt->node_pt(j) = old_node_pt;
3685  }
3686  }
3687 
3688 
3689  // Brick vertex node coindides with mid-vertex node of tet edge 2
3690  {
3691  unsigned j = 18;
3692 
3693  // Need new node?
3694  tet_node_pt = tet_el_pt->node_pt(tet_edge_node[2][0]);
3695  old_node_pt = tet_node_node_pt[tet_node_pt];
3696  if (old_node_pt == 0)
3697  {
3698  Node* new_node_pt = 0;
3699  if (tet_node_pt->is_on_boundary())
3700  {
3701  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
3702  }
3703  else
3704  {
3705  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
3706  }
3707  tet_node_node_pt[tet_node_pt] = new_node_pt;
3708  Node_pt.push_back(new_node_pt);
3709  Vector<double> s(3);
3710  Vector<double> s_tet(3);
3711  Vector<double> x_tet(3);
3712  el_pt->local_coordinate_of_node(j, s);
3713  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
3714  tet_el_pt->interpolated_x(s_tet, x_tet);
3715  new_node_pt->x(0) = x_tet[0];
3716  new_node_pt->x(1) = x_tet[1];
3717  new_node_pt->x(2) = x_tet[2];
3718  }
3719  // Node already exists
3720  else
3721  {
3722  el_pt->node_pt(j) = old_node_pt;
3723  }
3724  }
3725 
3726 
3727  // Brick vertex node in the middle of tet face0
3728  {
3729  unsigned j = 20;
3730 
3731  // Need new node?
3732  old_node_pt = tet_face_node_pt[face0];
3733  if (old_node_pt == 0)
3734  {
3735  Node* new_node_pt = 0;
3736  if (face0.is_boundary_face())
3737  {
3738  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
3739  }
3740  else
3741  {
3742  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
3743  }
3744  tet_face_node_pt[face0] = new_node_pt;
3745  Node_pt.push_back(new_node_pt);
3746  Vector<double> s(3);
3747  Vector<double> s_tet(3);
3748  Vector<double> x_tet(3);
3749  el_pt->local_coordinate_of_node(j, s);
3750  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
3751  tet_el_pt->interpolated_x(s_tet, x_tet);
3752  new_node_pt->x(0) = x_tet[0];
3753  new_node_pt->x(1) = x_tet[1];
3754  new_node_pt->x(2) = x_tet[2];
3755  }
3756  // Node already exists
3757  else
3758  {
3759  el_pt->node_pt(j) = old_node_pt;
3760  }
3761  }
3762 
3763  // Brick vertex node in the middle of tet face1
3764  {
3765  unsigned j = 24;
3766 
3767  // Need new node?
3768  old_node_pt = tet_face_node_pt[face1];
3769  if (old_node_pt == 0)
3770  {
3771  Node* new_node_pt = 0;
3772  if (face1.is_boundary_face())
3773  {
3774  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
3775  }
3776  else
3777  {
3778  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
3779  }
3780  tet_face_node_pt[face1] = new_node_pt;
3781  Node_pt.push_back(new_node_pt);
3782  Vector<double> s(3);
3783  Vector<double> s_tet(3);
3784  Vector<double> x_tet(3);
3785  el_pt->local_coordinate_of_node(j, s);
3786  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
3787  tet_el_pt->interpolated_x(s_tet, x_tet);
3788  new_node_pt->x(0) = x_tet[0];
3789  new_node_pt->x(1) = x_tet[1];
3790  new_node_pt->x(2) = x_tet[2];
3791  }
3792  // Node already exists
3793  else
3794  {
3795  el_pt->node_pt(j) = old_node_pt;
3796  }
3797  }
3798 
3799  // Brick vertex node in the middle of tet face2
3800  {
3801  unsigned j = 8;
3802 
3803  // Need new node?
3804  old_node_pt = tet_face_node_pt[face2];
3805  if (old_node_pt == 0)
3806  {
3807  Node* new_node_pt = 0;
3808  if (face2.is_boundary_face())
3809  {
3810  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
3811  }
3812  else
3813  {
3814  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
3815  }
3816  tet_face_node_pt[face2] = new_node_pt;
3817  Node_pt.push_back(new_node_pt);
3818  Vector<double> s(3);
3819  Vector<double> s_tet(3);
3820  Vector<double> x_tet(3);
3821  el_pt->local_coordinate_of_node(j, s);
3822  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
3823  tet_el_pt->interpolated_x(s_tet, x_tet);
3824  new_node_pt->x(0) = x_tet[0];
3825  new_node_pt->x(1) = x_tet[1];
3826  new_node_pt->x(2) = x_tet[2];
3827  }
3828  // Node already exists
3829  else
3830  {
3831  el_pt->node_pt(j) = old_node_pt;
3832  }
3833  }
3834 
3835 
3836  // Brick vertex node in centroid of tet. Only built for first element.
3837  // Enumerated "13" in initial sketch.
3838  {
3839  unsigned j = 26;
3840 
3841  // Always copied
3842  el_pt->node_pt(j) = centroid_node_pt;
3843  }
3844 
3845 
3846  // Internal brick node -- always built
3847  {
3848  unsigned j = 13;
3849 
3850  // Always new
3851  {
3852  Node* new_node_pt = el_pt->construct_node(j, time_stepper_pt);
3853  Node_pt.push_back(new_node_pt);
3854  Vector<double> s(3);
3855  Vector<double> s_tet(3);
3856  Vector<double> x_tet(3);
3857  el_pt->local_coordinate_of_node(j, s);
3858  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
3859  tet_el_pt->interpolated_x(s_tet, x_tet);
3860  new_node_pt->x(0) = x_tet[0];
3861  new_node_pt->x(1) = x_tet[1];
3862  new_node_pt->x(2) = x_tet[2];
3863  }
3864  }
3865 
3866  // Brick edge node between brick nodes 0 and 2
3867  {
3868  unsigned j = 1;
3869 
3870  // Need new node?
3871  Edge edge(el_pt->node_pt(0), el_pt->node_pt(2));
3872  old_node_pt = brick_edge_node_pt[edge];
3873  if (old_node_pt == 0)
3874  {
3875  Node* new_node_pt = 0;
3876  if (edge.is_boundary_edge())
3877  {
3878  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
3879  }
3880  else
3881  {
3882  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
3883  }
3884  brick_edge_node_pt[edge] = new_node_pt;
3885  Node_pt.push_back(new_node_pt);
3886  Vector<double> s(3);
3887  Vector<double> s_tet(3);
3888  Vector<double> x_tet(3);
3889  el_pt->local_coordinate_of_node(j, s);
3890  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
3891  tet_el_pt->interpolated_x(s_tet, x_tet);
3892  new_node_pt->x(0) = x_tet[0];
3893  new_node_pt->x(1) = x_tet[1];
3894  new_node_pt->x(2) = x_tet[2];
3895  }
3896  // Node already exists
3897  else
3898  {
3899  el_pt->node_pt(j) = old_node_pt;
3900  }
3901  }
3902 
3903 
3904  // Brick edge node between brick nodes 0 and 6
3905  {
3906  unsigned j = 3;
3907 
3908  // Need new node?
3909  Edge edge(el_pt->node_pt(0), el_pt->node_pt(6));
3910  old_node_pt = brick_edge_node_pt[edge];
3911  if (old_node_pt == 0)
3912  {
3913  Node* new_node_pt = 0;
3914  if (edge.is_boundary_edge())
3915  {
3916  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
3917  }
3918  else
3919  {
3920  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
3921  }
3922  brick_edge_node_pt[edge] = new_node_pt;
3923  Node_pt.push_back(new_node_pt);
3924  Vector<double> s(3);
3925  Vector<double> s_tet(3);
3926  Vector<double> x_tet(3);
3927  el_pt->local_coordinate_of_node(j, s);
3928  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
3929  tet_el_pt->interpolated_x(s_tet, x_tet);
3930  new_node_pt->x(0) = x_tet[0];
3931  new_node_pt->x(1) = x_tet[1];
3932  new_node_pt->x(2) = x_tet[2];
3933  }
3934  // Node already exists
3935  else
3936  {
3937  el_pt->node_pt(j) = old_node_pt;
3938  }
3939  }
3940 
3941  // Brick edge node between brick nodes 2 and 8
3942  {
3943  unsigned j = 5;
3944 
3945  // Need new node?
3946  Edge edge(el_pt->node_pt(2), el_pt->node_pt(8));
3947  old_node_pt = brick_edge_node_pt[edge];
3948  if (old_node_pt == 0)
3949  {
3950  Node* new_node_pt = 0;
3951  if (edge.is_boundary_edge())
3952  {
3953  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
3954  }
3955  else
3956  {
3957  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
3958  }
3959  brick_edge_node_pt[edge] = new_node_pt;
3960  Node_pt.push_back(new_node_pt);
3961  Vector<double> s(3);
3962  Vector<double> s_tet(3);
3963  Vector<double> x_tet(3);
3964  el_pt->local_coordinate_of_node(j, s);
3965  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
3966  tet_el_pt->interpolated_x(s_tet, x_tet);
3967  new_node_pt->x(0) = x_tet[0];
3968  new_node_pt->x(1) = x_tet[1];
3969  new_node_pt->x(2) = x_tet[2];
3970  }
3971  // Node already exists
3972  else
3973  {
3974  el_pt->node_pt(j) = old_node_pt;
3975  }
3976  }
3977 
3978  // Brick edge node between brick nodes 6 and 8
3979  {
3980  unsigned j = 7;
3981 
3982  // Need new node?
3983  Edge edge(el_pt->node_pt(6), el_pt->node_pt(8));
3984  old_node_pt = brick_edge_node_pt[edge];
3985  if (old_node_pt == 0)
3986  {
3987  Node* new_node_pt = 0;
3988  if (edge.is_boundary_edge())
3989  {
3990  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
3991  }
3992  else
3993  {
3994  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
3995  }
3996  brick_edge_node_pt[edge] = new_node_pt;
3997  Node_pt.push_back(new_node_pt);
3998  Vector<double> s(3);
3999  Vector<double> s_tet(3);
4000  Vector<double> x_tet(3);
4001  el_pt->local_coordinate_of_node(j, s);
4002  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
4003  tet_el_pt->interpolated_x(s_tet, x_tet);
4004  new_node_pt->x(0) = x_tet[0];
4005  new_node_pt->x(1) = x_tet[1];
4006  new_node_pt->x(2) = x_tet[2];
4007  }
4008  // Node already exists
4009  else
4010  {
4011  el_pt->node_pt(j) = old_node_pt;
4012  }
4013  }
4014 
4015  // Brick edge node between brick nodes 18 and 20
4016  {
4017  unsigned j = 19;
4018 
4019  // Need new node?
4020  Edge edge(el_pt->node_pt(18), el_pt->node_pt(20));
4021  old_node_pt = brick_edge_node_pt[edge];
4022  if (old_node_pt == 0)
4023  {
4024  Node* new_node_pt = 0;
4025  if (edge.is_boundary_edge())
4026  {
4027  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
4028  }
4029  else
4030  {
4031  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
4032  }
4033  brick_edge_node_pt[edge] = new_node_pt;
4034  Node_pt.push_back(new_node_pt);
4035  Vector<double> s(3);
4036  Vector<double> s_tet(3);
4037  Vector<double> x_tet(3);
4038  el_pt->local_coordinate_of_node(j, s);
4039  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
4040  tet_el_pt->interpolated_x(s_tet, x_tet);
4041  new_node_pt->x(0) = x_tet[0];
4042  new_node_pt->x(1) = x_tet[1];
4043  new_node_pt->x(2) = x_tet[2];
4044  }
4045  // Node already exists
4046  else
4047  {
4048  el_pt->node_pt(j) = old_node_pt;
4049  }
4050  }
4051 
4052 
4053  // Brick edge node between brick nodes 18 and 24
4054  {
4055  unsigned j = 21;
4056 
4057  // Need new node?
4058  Edge edge(el_pt->node_pt(18), el_pt->node_pt(24));
4059  old_node_pt = brick_edge_node_pt[edge];
4060  if (old_node_pt == 0)
4061  {
4062  Node* new_node_pt = 0;
4063  if (edge.is_boundary_edge())
4064  {
4065  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
4066  }
4067  else
4068  {
4069  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
4070  }
4071  brick_edge_node_pt[edge] = new_node_pt;
4072  Node_pt.push_back(new_node_pt);
4073  Vector<double> s(3);
4074  Vector<double> s_tet(3);
4075  Vector<double> x_tet(3);
4076  el_pt->local_coordinate_of_node(j, s);
4077  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
4078  tet_el_pt->interpolated_x(s_tet, x_tet);
4079  new_node_pt->x(0) = x_tet[0];
4080  new_node_pt->x(1) = x_tet[1];
4081  new_node_pt->x(2) = x_tet[2];
4082  }
4083  // Node already exists
4084  else
4085  {
4086  el_pt->node_pt(j) = old_node_pt;
4087  }
4088  }
4089 
4090  // Brick edge node between brick nodes 20 and 26
4091  {
4092  unsigned j = 23;
4093 
4094  // Need new node?
4095  Edge edge(el_pt->node_pt(20), el_pt->node_pt(26));
4096  old_node_pt = brick_edge_node_pt[edge];
4097  if (old_node_pt == 0)
4098  {
4099  Node* new_node_pt = 0;
4100  if (edge.is_boundary_edge())
4101  {
4102  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
4103  }
4104  else
4105  {
4106  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
4107  }
4108  brick_edge_node_pt[edge] = new_node_pt;
4109  Node_pt.push_back(new_node_pt);
4110  Vector<double> s(3);
4111  Vector<double> s_tet(3);
4112  Vector<double> x_tet(3);
4113  el_pt->local_coordinate_of_node(j, s);
4114  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
4115  tet_el_pt->interpolated_x(s_tet, x_tet);
4116  new_node_pt->x(0) = x_tet[0];
4117  new_node_pt->x(1) = x_tet[1];
4118  new_node_pt->x(2) = x_tet[2];
4119  }
4120  // Node already exists
4121  else
4122  {
4123  el_pt->node_pt(j) = old_node_pt;
4124  }
4125  }
4126 
4127 
4128  // Brick edge node between brick nodes 24 and 26
4129  {
4130  unsigned j = 25;
4131 
4132  // Need new node?
4133  Edge edge(el_pt->node_pt(24), el_pt->node_pt(26));
4134  old_node_pt = brick_edge_node_pt[edge];
4135  if (old_node_pt == 0)
4136  {
4137  Node* new_node_pt = 0;
4138  if (edge.is_boundary_edge())
4139  {
4140  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
4141  }
4142  else
4143  {
4144  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
4145  }
4146  brick_edge_node_pt[edge] = new_node_pt;
4147  Node_pt.push_back(new_node_pt);
4148  Vector<double> s(3);
4149  Vector<double> s_tet(3);
4150  Vector<double> x_tet(3);
4151  el_pt->local_coordinate_of_node(j, s);
4152  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
4153  tet_el_pt->interpolated_x(s_tet, x_tet);
4154  new_node_pt->x(0) = x_tet[0];
4155  new_node_pt->x(1) = x_tet[1];
4156  new_node_pt->x(2) = x_tet[2];
4157  }
4158  // Node already exists
4159  else
4160  {
4161  el_pt->node_pt(j) = old_node_pt;
4162  }
4163  }
4164 
4165  // Brick edge node between brick nodes 0 and 18
4166  {
4167  unsigned j = 9;
4168 
4169  // Need new node?
4170  Edge edge(el_pt->node_pt(0), el_pt->node_pt(18));
4171  old_node_pt = brick_edge_node_pt[edge];
4172  if (old_node_pt == 0)
4173  {
4174  Node* new_node_pt = 0;
4175  if (edge.is_boundary_edge())
4176  {
4177  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
4178  }
4179  else
4180  {
4181  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
4182  }
4183  brick_edge_node_pt[edge] = new_node_pt;
4184  Node_pt.push_back(new_node_pt);
4185  Vector<double> s(3);
4186  Vector<double> s_tet(3);
4187  Vector<double> x_tet(3);
4188  el_pt->local_coordinate_of_node(j, s);
4189  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
4190  tet_el_pt->interpolated_x(s_tet, x_tet);
4191  new_node_pt->x(0) = x_tet[0];
4192  new_node_pt->x(1) = x_tet[1];
4193  new_node_pt->x(2) = x_tet[2];
4194  }
4195  // Node already exists
4196  else
4197  {
4198  el_pt->node_pt(j) = old_node_pt;
4199  }
4200  }
4201 
4202 
4203  // Brick edge node between brick nodes 2 and 20
4204  {
4205  unsigned j = 11;
4206 
4207  // Need new node?
4208  Edge edge(el_pt->node_pt(2), el_pt->node_pt(20));
4209  old_node_pt = brick_edge_node_pt[edge];
4210  if (old_node_pt == 0)
4211  {
4212  Node* new_node_pt = 0;
4213  if (edge.is_boundary_edge())
4214  {
4215  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
4216  }
4217  else
4218  {
4219  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
4220  }
4221  brick_edge_node_pt[edge] = new_node_pt;
4222  Node_pt.push_back(new_node_pt);
4223  Vector<double> s(3);
4224  Vector<double> s_tet(3);
4225  Vector<double> x_tet(3);
4226  el_pt->local_coordinate_of_node(j, s);
4227  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
4228  tet_el_pt->interpolated_x(s_tet, x_tet);
4229  new_node_pt->x(0) = x_tet[0];
4230  new_node_pt->x(1) = x_tet[1];
4231  new_node_pt->x(2) = x_tet[2];
4232  }
4233  // Node already exists
4234  else
4235  {
4236  el_pt->node_pt(j) = old_node_pt;
4237  }
4238  }
4239 
4240 
4241  // Brick edge node between brick nodes 6 and 24
4242  {
4243  unsigned j = 15;
4244 
4245  // Need new node?
4246  Edge edge(el_pt->node_pt(6), el_pt->node_pt(24));
4247  old_node_pt = brick_edge_node_pt[edge];
4248  if (old_node_pt == 0)
4249  {
4250  Node* new_node_pt = 0;
4251  if (edge.is_boundary_edge())
4252  {
4253  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
4254  }
4255  else
4256  {
4257  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
4258  }
4259  brick_edge_node_pt[edge] = new_node_pt;
4260  Node_pt.push_back(new_node_pt);
4261  Vector<double> s(3);
4262  Vector<double> s_tet(3);
4263  Vector<double> x_tet(3);
4264  el_pt->local_coordinate_of_node(j, s);
4265  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
4266  tet_el_pt->interpolated_x(s_tet, x_tet);
4267  new_node_pt->x(0) = x_tet[0];
4268  new_node_pt->x(1) = x_tet[1];
4269  new_node_pt->x(2) = x_tet[2];
4270  }
4271  // Node already exists
4272  else
4273  {
4274  el_pt->node_pt(j) = old_node_pt;
4275  }
4276  }
4277 
4278 
4279  // Brick edge node between brick nodes 8 and 26
4280  {
4281  unsigned j = 17;
4282 
4283  // Need new node?
4284  Edge edge(el_pt->node_pt(8), el_pt->node_pt(26));
4285  old_node_pt = brick_edge_node_pt[edge];
4286  if (old_node_pt == 0)
4287  {
4288  Node* new_node_pt = 0;
4289  if (edge.is_boundary_edge())
4290  {
4291  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
4292  }
4293  else
4294  {
4295  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
4296  }
4297  brick_edge_node_pt[edge] = new_node_pt;
4298  Node_pt.push_back(new_node_pt);
4299  Vector<double> s(3);
4300  Vector<double> s_tet(3);
4301  Vector<double> x_tet(3);
4302  el_pt->local_coordinate_of_node(j, s);
4303  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
4304  tet_el_pt->interpolated_x(s_tet, x_tet);
4305  new_node_pt->x(0) = x_tet[0];
4306  new_node_pt->x(1) = x_tet[1];
4307  new_node_pt->x(2) = x_tet[2];
4308  }
4309  // Node already exists
4310  else
4311  {
4312  el_pt->node_pt(j) = old_node_pt;
4313  }
4314  }
4315 
4316 
4317  // Mid brick-face node associated with face
4318  // spanned by mid-vertex nodes associated with tet edges 0 and 2
4319  {
4320  unsigned j = 10;
4321 
4322  // Need new node?
4323  TFace face(tet_el_pt->node_pt(central_tet_vertex),
4324  tet_el_pt->node_pt(tet_edge_node[0][0]),
4325  tet_el_pt->node_pt(tet_edge_node[2][0]));
4326 
4327  old_node_pt = tet_face_node_pt[face];
4328  if (old_node_pt == 0)
4329  {
4330  Node* new_node_pt = 0;
4331  if (face.is_boundary_face())
4332  {
4333  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
4334  }
4335  else
4336  {
4337  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
4338  }
4339  tet_face_node_pt[face] = new_node_pt;
4340  Node_pt.push_back(new_node_pt);
4341  Vector<double> s(3);
4342  Vector<double> s_tet(3);
4343  Vector<double> x_tet(3);
4344  el_pt->local_coordinate_of_node(j, s);
4345  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
4346  tet_el_pt->interpolated_x(s_tet, x_tet);
4347  new_node_pt->x(0) = x_tet[0];
4348  new_node_pt->x(1) = x_tet[1];
4349  new_node_pt->x(2) = x_tet[2];
4350  }
4351  // Node already exists
4352  else
4353  {
4354  el_pt->node_pt(j) = old_node_pt;
4355  }
4356  }
4357 
4358 
4359  // Mid brick-face node associated with face
4360  // spanned by mid-vertex nodes associated with tet edges 1 and 2
4361  {
4362  unsigned j = 12;
4363 
4364  // Need new node?
4365  TFace face(tet_el_pt->node_pt(central_tet_vertex),
4366  tet_el_pt->node_pt(tet_edge_node[1][0]),
4367  tet_el_pt->node_pt(tet_edge_node[2][0]));
4368 
4369  old_node_pt = tet_face_node_pt[face];
4370  if (old_node_pt == 0)
4371  {
4372  Node* new_node_pt = 0;
4373  if (face.is_boundary_face())
4374  {
4375  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
4376  }
4377  else
4378  {
4379  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
4380  }
4381  tet_face_node_pt[face] = new_node_pt;
4382  Node_pt.push_back(new_node_pt);
4383  Vector<double> s(3);
4384  Vector<double> s_tet(3);
4385  Vector<double> x_tet(3);
4386  el_pt->local_coordinate_of_node(j, s);
4387  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
4388  tet_el_pt->interpolated_x(s_tet, x_tet);
4389  new_node_pt->x(0) = x_tet[0];
4390  new_node_pt->x(1) = x_tet[1];
4391  new_node_pt->x(2) = x_tet[2];
4392  }
4393  // Node already exists
4394  else
4395  {
4396  el_pt->node_pt(j) = old_node_pt;
4397  }
4398  }
4399 
4400 
4401  // Mid brick-face node associated with face
4402  // spanned by mid-vertex nodes associated with tet edges 0 and 1
4403  {
4404  unsigned j = 4;
4405 
4406  // Need new node?
4407  TFace face(tet_el_pt->node_pt(central_tet_vertex),
4408  tet_el_pt->node_pt(tet_edge_node[0][0]),
4409  tet_el_pt->node_pt(tet_edge_node[1][0]));
4410 
4411  old_node_pt = tet_face_node_pt[face];
4412  if (old_node_pt == 0)
4413  {
4414  Node* new_node_pt = 0;
4415  if (face.is_boundary_face())
4416  {
4417  new_node_pt = el_pt->construct_boundary_node(j, time_stepper_pt);
4418  }
4419  else
4420  {
4421  new_node_pt = el_pt->construct_node(j, time_stepper_pt);
4422  }
4423  tet_face_node_pt[face] = new_node_pt;
4424  Node_pt.push_back(new_node_pt);
4425  Vector<double> s(3);
4426  Vector<double> s_tet(3);
4427  Vector<double> x_tet(3);
4428  el_pt->local_coordinate_of_node(j, s);
4429  dummy_q_el_pt[3]->interpolated_s_tet(s, s_tet);
4430  tet_el_pt->interpolated_x(s_tet, x_tet);
4431  new_node_pt->x(0) = x_tet[0];
4432  new_node_pt->x(1) = x_tet[1];
4433  new_node_pt->x(2) = x_tet[2];
4434  }
4435  // Node already exists
4436  else
4437  {
4438  el_pt->node_pt(j) = old_node_pt;
4439  }
4440  }
4441 
4442 
4443  // Top mid brick-face node copy from top of second element
4444  {
4445  unsigned j = 22;
4446 
4447  // Always copied
4448  el_pt->node_pt(j) = top_mid_face_node2_pt;
4449  }
4450 
4451 
4452  // Right mid brick-face node copy from top of first element
4453  {
4454  unsigned j = 14;
4455 
4456  // Always copied
4457  el_pt->node_pt(j) = top_mid_face_node1_pt;
4458  }
4459 
4460 
4461  // Back mid brick-face node copy from top of zeroth element
4462  {
4463  unsigned j = 16;
4464 
4465  // Always copied
4466  el_pt->node_pt(j) = top_mid_face_node0_pt;
4467  }
4468  }
4469 
4470 
4471  // Check if the four faces of the tet are on a boundary.
4472  // If they are, add the nodes in the brick mesh to those
4473  // boundaries.
4474 
4475  // Loop over faces of tet (in its own face index enumeration)
4476  for (int face_index = 0; face_index < 4; face_index++)
4477  {
4478  // Identify face and coordinates in it
4479  TFace* face_pt = 0;
4480  switch (face_index)
4481  {
4482  case 0:
4483  // Face 0: s[0]=0; opposite node 0
4484  face_pt = new TFace(tet_el_pt->node_pt(1),
4485  tet_el_pt->node_pt(2),
4486  tet_el_pt->node_pt(3));
4487  break;
4488 
4489  case 1:
4490  // Face 1: s[1]=0; opposite node 1
4491  face_pt = new TFace(tet_el_pt->node_pt(0),
4492  tet_el_pt->node_pt(2),
4493  tet_el_pt->node_pt(3));
4494 
4495  break;
4496 
4497 
4498  case 2:
4499  // Face 2: s[2]=0; opposite node 2
4500  face_pt = new TFace(tet_el_pt->node_pt(0),
4501  tet_el_pt->node_pt(1),
4502  tet_el_pt->node_pt(3));
4503 
4504  break;
4505 
4506  case 3:
4507  // Face 3: s[0]+s[1]+s[2]=1; opposite node 3
4508  face_pt = new TFace(tet_el_pt->node_pt(0),
4509  tet_el_pt->node_pt(1),
4510  tet_el_pt->node_pt(2));
4511  break;
4512  }
4513 
4514 
4515  if (face_pt->is_boundary_face())
4516  {
4517  std::set<unsigned> bnd;
4518  std::set<unsigned>* bnd_pt = &bnd;
4519  face_pt->get_boundaries_pt(bnd_pt);
4520 
4521 #ifdef PARANOID
4522  if ((*bnd_pt).size() > 1)
4523  {
4524  std::ostringstream error_stream;
4525  error_stream << "TFace should only be on one boundary.\n";
4526  throw OomphLibError(error_stream.str(),
4529  }
4530 #endif
4531 
4532  if ((*bnd_pt).size() == 1)
4533  {
4534  // Create new face element
4535  FaceElement* face_el_pt = 0;
4536  if (tet_mesh_is_solid_mesh)
4537  {
4538 #ifdef PARANOID
4539  if (dynamic_cast<SolidTElement<3, 3>*>(tet_el_pt) == 0)
4540  {
4541  std::ostringstream error_stream;
4542  error_stream
4543  << "Tet-element cannot be cast to SolidTElement<3,3>.\n"
4544  << "BrickFromTetMesh can only be built from\n"
4545  << "mesh containing quadratic tets.\n"
4546  << std::endl;
4547  throw OomphLibError(error_stream.str(),
4550  }
4551 #endif
4552  // Build the face element
4553  face_el_pt = new DummyFaceElement<SolidTElement<3, 3>>(
4554  tet_el_pt, face_index);
4555  }
4556  else
4557  {
4558 #ifdef PARANOID
4559  if (dynamic_cast<TElement<3, 3>*>(tet_el_pt) == 0)
4560  {
4561  std::ostringstream error_stream;
4562  error_stream << "Tet-element cannot be cast to TElement<3,3>.\n"
4563  << "BrickFromTetMesh can only be built from\n"
4564  << "mesh containing quadratic tets.\n"
4565  << std::endl;
4566  throw OomphLibError(error_stream.str(),
4569  }
4570 #endif
4571 
4572  // Build the face element
4573  face_el_pt =
4574  new DummyFaceElement<TElement<3, 3>>(tet_el_pt, face_index);
4575  }
4576 
4577 
4578  // Specify boundary id in bulk mesh (needed to extract
4579  // boundary coordinate)
4580  unsigned b = (*(*bnd_pt).begin());
4581  Boundary_coordinate_exists[b] = true;
4582  face_el_pt->set_boundary_number_in_bulk_mesh(b);
4583 
4584  // Now set up the brick nodes on this face, enumerated as
4585  // in s_face
4586  Vector<Node*> brick_face_node_pt(19);
4587 
4588  switch (face_index)
4589  {
4590  case 0:
4591  brick_face_node_pt[0] = brick_el1_pt->node_pt(0);
4592  brick_face_node_pt[1] = brick_el3_pt->node_pt(0);
4593  brick_face_node_pt[2] = brick_el2_pt->node_pt(0);
4594 
4595  brick_face_node_pt[3] = brick_el1_pt->node_pt(18);
4596  brick_face_node_pt[4] = brick_el2_pt->node_pt(18);
4597  brick_face_node_pt[5] = brick_el1_pt->node_pt(2);
4598 
4599  brick_face_node_pt[6] = brick_el1_pt->node_pt(9);
4600  brick_face_node_pt[7] = brick_el3_pt->node_pt(1);
4601  brick_face_node_pt[8] = brick_el3_pt->node_pt(9);
4602 
4603  brick_face_node_pt[9] = brick_el2_pt->node_pt(9);
4604  brick_face_node_pt[10] = brick_el2_pt->node_pt(3);
4605  brick_face_node_pt[11] = brick_el1_pt->node_pt(1);
4606 
4607  brick_face_node_pt[12] = brick_el1_pt->node_pt(20);
4608 
4609  brick_face_node_pt[13] = brick_el2_pt->node_pt(12);
4610  brick_face_node_pt[14] = brick_el1_pt->node_pt(19);
4611 
4612  brick_face_node_pt[15] = brick_el1_pt->node_pt(10);
4613  brick_face_node_pt[16] = brick_el2_pt->node_pt(21);
4614 
4615  brick_face_node_pt[17] = brick_el3_pt->node_pt(10);
4616  brick_face_node_pt[18] = brick_el1_pt->node_pt(11);
4617  break;
4618 
4619  case 1:
4620  brick_face_node_pt[0] = brick_el0_pt->node_pt(0);
4621  brick_face_node_pt[1] = brick_el3_pt->node_pt(0);
4622  brick_face_node_pt[2] = brick_el2_pt->node_pt(0);
4623 
4624  brick_face_node_pt[3] = brick_el0_pt->node_pt(18);
4625  brick_face_node_pt[4] = brick_el2_pt->node_pt(18);
4626  brick_face_node_pt[5] = brick_el0_pt->node_pt(6);
4627 
4628  brick_face_node_pt[6] = brick_el0_pt->node_pt(9);
4629  brick_face_node_pt[7] = brick_el3_pt->node_pt(3);
4630  brick_face_node_pt[8] = brick_el3_pt->node_pt(9);
4631 
4632  brick_face_node_pt[9] = brick_el2_pt->node_pt(9);
4633  brick_face_node_pt[10] = brick_el2_pt->node_pt(1);
4634  brick_face_node_pt[11] = brick_el0_pt->node_pt(3);
4635 
4636  brick_face_node_pt[12] = brick_el0_pt->node_pt(24);
4637 
4638  brick_face_node_pt[13] = brick_el2_pt->node_pt(10);
4639  brick_face_node_pt[14] = brick_el0_pt->node_pt(21);
4640 
4641  brick_face_node_pt[15] = brick_el0_pt->node_pt(12);
4642  brick_face_node_pt[16] = brick_el3_pt->node_pt(21);
4643 
4644  brick_face_node_pt[17] = brick_el3_pt->node_pt(12);
4645  brick_face_node_pt[18] = brick_el0_pt->node_pt(15);
4646  break;
4647 
4648  case 2:
4649  brick_face_node_pt[0] = brick_el0_pt->node_pt(0);
4650  brick_face_node_pt[1] = brick_el1_pt->node_pt(0);
4651  brick_face_node_pt[2] = brick_el2_pt->node_pt(0);
4652 
4653  brick_face_node_pt[3] = brick_el0_pt->node_pt(2);
4654  brick_face_node_pt[4] = brick_el1_pt->node_pt(2);
4655  brick_face_node_pt[5] = brick_el0_pt->node_pt(6);
4656 
4657  brick_face_node_pt[6] = brick_el0_pt->node_pt(1);
4658  brick_face_node_pt[7] = brick_el1_pt->node_pt(3);
4659  brick_face_node_pt[8] = brick_el1_pt->node_pt(1);
4660 
4661  brick_face_node_pt[9] = brick_el2_pt->node_pt(3);
4662  brick_face_node_pt[10] = brick_el2_pt->node_pt(1);
4663  brick_face_node_pt[11] = brick_el0_pt->node_pt(3);
4664 
4665  brick_face_node_pt[12] = brick_el0_pt->node_pt(8);
4666 
4667  brick_face_node_pt[13] = brick_el2_pt->node_pt(4);
4668  brick_face_node_pt[14] = brick_el0_pt->node_pt(5);
4669 
4670  brick_face_node_pt[15] = brick_el0_pt->node_pt(4);
4671  brick_face_node_pt[16] = brick_el1_pt->node_pt(5);
4672 
4673  brick_face_node_pt[17] = brick_el1_pt->node_pt(4);
4674  brick_face_node_pt[18] = brick_el0_pt->node_pt(7);
4675  break;
4676 
4677  case 3:
4678  brick_face_node_pt[0] = brick_el1_pt->node_pt(0);
4679  brick_face_node_pt[1] = brick_el3_pt->node_pt(0);
4680  brick_face_node_pt[2] = brick_el0_pt->node_pt(0);
4681 
4682  brick_face_node_pt[3] = brick_el1_pt->node_pt(18);
4683  brick_face_node_pt[4] = brick_el3_pt->node_pt(6);
4684  brick_face_node_pt[5] = brick_el1_pt->node_pt(6);
4685 
4686  brick_face_node_pt[6] = brick_el1_pt->node_pt(9);
4687  brick_face_node_pt[7] = brick_el3_pt->node_pt(1);
4688  brick_face_node_pt[8] = brick_el3_pt->node_pt(3);
4689 
4690  brick_face_node_pt[9] = brick_el0_pt->node_pt(9);
4691  brick_face_node_pt[10] = brick_el0_pt->node_pt(1);
4692  brick_face_node_pt[11] = brick_el1_pt->node_pt(3);
4693 
4694  brick_face_node_pt[12] = brick_el1_pt->node_pt(24);
4695 
4696  brick_face_node_pt[13] = brick_el0_pt->node_pt(10);
4697  brick_face_node_pt[14] = brick_el1_pt->node_pt(21);
4698 
4699  brick_face_node_pt[15] = brick_el1_pt->node_pt(12);
4700  brick_face_node_pt[16] = brick_el3_pt->node_pt(7);
4701 
4702  brick_face_node_pt[17] = brick_el3_pt->node_pt(4);
4703  brick_face_node_pt[18] = brick_el1_pt->node_pt(15);
4704  break;
4705  }
4706 
4707  // Provide possibility for translation -- may need to add
4708  // face index to this; see ThinLayerBrickOnTetMesh.
4709  Vector<unsigned> translate(19);
4710 
4711  // Initialise with identity mapping
4712  for (unsigned i = 0; i < 19; i++)
4713  {
4714  translate[i] = i;
4715  }
4716 
4717  // Visit all the nodes on that face
4718  for (unsigned j = 0; j < 19; j++)
4719  {
4720  // Which node is it?
4721  Node* brick_node_pt = brick_face_node_pt[translate[j]];
4722 
4723  // Get coordinates etc of point from face
4724  Vector<double> s = s_face[j];
4725  Vector<double> zeta(2);
4726  Vector<double> x(3);
4727  face_el_pt->interpolated_zeta(s, zeta);
4728  face_el_pt->interpolated_x(s, x);
4729 
4730 #ifdef PARANOID
4731  // Check that the coordinates match (within tolerance)
4732  double dist = sqrt(pow(brick_node_pt->x(0) - x[0], 2) +
4733  pow(brick_node_pt->x(1) - x[1], 2) +
4734  pow(brick_node_pt->x(2) - x[2], 2));
4736  {
4737  std::ofstream brick0;
4738  std::ofstream brick1;
4739  std::ofstream brick2;
4740  std::ofstream brick3;
4741  brick0.open("full_brick0.dat");
4742  brick1.open("full_brick1.dat");
4743  brick2.open("full_brick2.dat");
4744  brick3.open("full_brick3.dat");
4745  for (unsigned j = 0; j < 27; j++)
4746  {
4747  brick0 << brick_el0_pt->node_pt(j)->x(0) << " "
4748  << brick_el0_pt->node_pt(j)->x(1) << " "
4749  << brick_el0_pt->node_pt(j)->x(2) << "\n";
4750 
4751  brick1 << brick_el1_pt->node_pt(j)->x(0) << " "
4752  << brick_el1_pt->node_pt(j)->x(1) << " "
4753  << brick_el1_pt->node_pt(j)->x(2) << "\n";
4754 
4755  brick2 << brick_el2_pt->node_pt(j)->x(0) << " "
4756  << brick_el2_pt->node_pt(j)->x(1) << " "
4757  << brick_el2_pt->node_pt(j)->x(2) << "\n";
4758 
4759  brick3 << brick_el3_pt->node_pt(j)->x(0) << " "
4760  << brick_el3_pt->node_pt(j)->x(1) << " "
4761  << brick_el3_pt->node_pt(j)->x(2) << "\n";
4762  }
4763  brick0.close();
4764  brick1.close();
4765  brick2.close();
4766  brick3.close();
4767 
4768  std::ofstream full_face;
4769  full_face.open("full_face.dat");
4770  for (unsigned j = 0; j < 6; j++)
4771  {
4772  full_face << face_el_pt->node_pt(j)->x(0) << " "
4773  << face_el_pt->node_pt(j)->x(1) << " "
4774  << face_el_pt->node_pt(j)->x(2) << "\n";
4775  }
4776  full_face.close();
4777 
4778  // Get normal sign
4779  int normal_sign = face_el_pt->normal_sign();
4780 
4781  std::ostringstream error_stream;
4782  error_stream
4783  << "During assignment of boundary cordinates, the distance\n"
4784  << "between brick node and reference point in \n"
4785  << "triangular FaceElement is " << dist << " which \n"
4786  << "is bigger than the tolerance defined in \n"
4787  << "BrickFromTetMeshHelper::Face_position_tolerance="
4789  << "If this is tolerable, increase the tolerance \n"
4790  << "(it's defined in a namespace and therefore publically\n"
4791  << "accessible). If not, the Face may be inverted in which \n"
4792  << "case you should re-implement the translation scheme,\n"
4793  << "following the pattern used in the "
4794  "ThinLayerBrickOnTetMesh."
4795  << "\nThe required code fragements are already here but \n"
4796  << "the translation is the unit map.\n"
4797  << "To aid the diagnostics, the files full_brick[0-3].dat\n"
4798  << "contain the coordinates of the 27 nodes in the four\n"
4799  << "bricks associated with the current tet and "
4800  "full_face.dat\n"
4801  << "contains the coordinates of the 6 nodes in the "
4802  "FaceElement"
4803  << "\nfrom which the boundary coordinates are extracted.\n"
4804  << "FYI: The normal_sign of the face is: " << normal_sign
4805  << std::endl;
4806  throw OomphLibError(error_stream.str(),
4809  }
4810 #endif
4811 
4812  // Set boundary stuff
4813  add_boundary_node(b, brick_node_pt);
4814  brick_node_pt->set_coordinates_on_boundary(b, zeta);
4815  }
4816 
4817  // Add appropriate brick elements to boundary lookup scheme
4818  switch (face_index)
4819  {
4820  case 0:
4821  Boundary_element_pt[b].push_back(brick_el1_pt);
4822  Face_index_at_boundary[b].push_back(-2);
4823  Boundary_element_pt[b].push_back(brick_el2_pt);
4824  Face_index_at_boundary[b].push_back(-1);
4825  Boundary_element_pt[b].push_back(brick_el3_pt);
4826  Face_index_at_boundary[b].push_back(-2);
4827  break;
4828 
4829  case 1:
4830  Boundary_element_pt[b].push_back(brick_el0_pt);
4831  Face_index_at_boundary[b].push_back(-1);
4832  Boundary_element_pt[b].push_back(brick_el2_pt);
4833  Face_index_at_boundary[b].push_back(-2);
4834  Boundary_element_pt[b].push_back(brick_el3_pt);
4835  Face_index_at_boundary[b].push_back(-1);
4836  break;
4837 
4838  case 2:
4839  Boundary_element_pt[b].push_back(brick_el0_pt);
4840  Face_index_at_boundary[b].push_back(-3);
4841  Boundary_element_pt[b].push_back(brick_el1_pt);
4842  Face_index_at_boundary[b].push_back(-3);
4843  Boundary_element_pt[b].push_back(brick_el2_pt);
4844  Face_index_at_boundary[b].push_back(-3);
4845  break;
4846 
4847  case 3:
4848  Boundary_element_pt[b].push_back(brick_el0_pt);
4849  Face_index_at_boundary[b].push_back(-2);
4850  Boundary_element_pt[b].push_back(brick_el1_pt);
4851  Face_index_at_boundary[b].push_back(-1);
4852  Boundary_element_pt[b].push_back(brick_el3_pt);
4853  Face_index_at_boundary[b].push_back(-3);
4854  break;
4855  }
4856  // Cleanup
4857  delete face_el_pt;
4858  }
4859  }
4860  // Cleanup
4861  delete face_pt;
4862  }
4863  }
4864 
4865  // Lookup scheme has now been setup
4867 
4868  // Get number of distinct boundaries specified
4869  // in the original xda enumeration.
4870  unsigned n_xda_boundaries = tet_mesh_pt->nxda_boundary();
4871 
4872  // Copy collective IDs across
4873  Boundary_id.resize(n_xda_boundaries);
4874  for (unsigned xda_b = 0; xda_b < n_xda_boundaries; xda_b++)
4875  {
4876  Boundary_id[xda_b] = tet_mesh_pt->oomph_lib_boundary_ids(xda_b);
4877  }
4878 
4879 
4880  // Cleanup
4881  for (unsigned e = 0; e < 4; e++)
4882  {
4883  for (unsigned j = 0; j < 8; j++)
4884  {
4885  delete dummy_q_el_pt[e]->node_pt(j);
4886  }
4887  delete dummy_q_el_pt[e];
4888  }
4889  }
Vector< Vector< unsigned > > Boundary_id
Definition: brick_from_tet_mesh.template.h:151

References b, oomph::FiniteElement::construct_boundary_node(), oomph::FiniteElement::construct_node(), e(), oomph::QElement1FaceToBulkCoordinates::face0(), oomph::QElement1FaceToBulkCoordinates::face1(), oomph::QElement2FaceToBulkCoordinates::face2(), oomph::BrickFromTetMeshHelper::Face_position_tolerance, oomph::TFace::get_boundaries_pt(), i, oomph::FaceElement::interpolated_x(), oomph::FiniteElement::interpolated_zeta(), oomph::Edge::is_boundary_edge(), oomph::TFace::is_boundary_face(), oomph::Node::is_on_boundary(), j, oomph::FiniteElement::local_coordinate_of_node(), nb, oomph::FiniteElement::node_pt(), oomph::FaceElement::normal_sign(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, Eigen::bfloat16_impl::pow(), s, oomph::FaceElement::set_boundary_number_in_bulk_mesh(), oomph::Node::set_coordinates_on_boundary(), oomph::Data::set_value(), sqrt(), plotDoE::x, oomph::Node::x(), and Eigen::zeta().

Referenced by oomph::BrickFromTetMesh< ELEMENT >::BrickFromTetMesh().

◆ oomph_lib_boundary_ids()

template<class ELEMENT >
Vector<unsigned> oomph::BrickFromTetMesh< ELEMENT >::oomph_lib_boundary_ids ( const unsigned xda_boundary_id)
inline

Access functions to the Vector of oomph-lib boundary ids that make up boundary b in the original xda enumeration

135  {
136  return Boundary_id[xda_boundary_id];
137  }

References oomph::BrickFromTetMesh< ELEMENT >::Boundary_id.

Member Data Documentation

◆ Boundary_id

template<class ELEMENT >
Vector<Vector<unsigned> > oomph::BrickFromTetMesh< ELEMENT >::Boundary_id
private

Vector of vectors containing the boundary IDs of the overall boundary specified in the xda file.

Referenced by oomph::BrickFromTetMesh< ELEMENT >::oomph_lib_boundary_ids().


The documentation for this class was generated from the following files: