Subparametric_Telements.h
Go to the documentation of this file.
1 //LIC// ====================================================================
2 //LIC// This file forms part of oomph-lib, the object-oriented,
3 //LIC// multi-physics finite-element library, available
4 //LIC// at http://www.oomph-lib.org.
5 //LIC//
6 //LIC// Version 1.0; svn revision $LastChangedRevision$
7 //LIC//
8 //LIC// $LastChangedDate$
9 //LIC//
10 //LIC// Copyright (C) 2006-2016 Matthias Heil and Andrew Hazel
11 //LIC//
12 //LIC// This library is free software; you can redistribute it and/or
13 //LIC// modify it under the terms of the GNU Lesser General Public
14 //LIC// License as published by the Free Software Foundation; either
15 //LIC// version 2.1 of the License, or (at your option) any later version.
16 //LIC//
17 //LIC// This library is distributed in the hope that it will be useful,
18 //LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
19 //LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 //LIC// Lesser General Public License for more details.
21 //LIC//
22 //LIC// You should have received a copy of the GNU Lesser General Public
23 //LIC// License along with this library; if not, write to the Free Software
24 //LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 //LIC// 02110-1301 USA.
26 //LIC//
27 //LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
28 //LIC//
29 //LIC//====================================================================
30 //Header functions for classes that define Subparametric_Telements
31 #ifndef OOMPH_SUBPARAMETRIC_TELEMENT_HEADER
32 #define OOMPH_SUBPARAMETRIC_TELEMENT_HEADER
33 
34 // Config header generated by autoconfig
35 #ifdef HAVE_CONFIG_H
36  #include <oomph-lib-config.h>
37 #endif
38 
39 #ifdef OOMPH_HAS_MPI
40 #include "mpi.h"
41 #endif
42 
43 //oomph-lib headers
44 #include "Vector.h"
45 #include "shape.h"
46 #include "integral.h"
47 #include "elements.h"
48 #include "Telements.h"
49 
50 namespace oomph
51 {
52 
53 ///////////////////////////////////////////////////////////////////////////
54 ///////////////////////////////////////////////////////////////////////////
55 ///////////////////////////////////////////////////////////////////////////
56 /// BellElementShape
57 ///////////////////////////////////////////////////////////////////////////
58 ///////////////////////////////////////////////////////////////////////////
59 
60 //========================================================================
61 /// A class for Bell triangular shape function with 3 vertex nodes and
62 /// WITHOUT 3 middle-side node
63 //========================================================================
64 template<unsigned DIM>
65  class BellElementShape { };
66 
67 template<>
69  {
70  public:
71 //=======================================================================
72 /// Return local coordinates of node j
73 //=======================================================================
74  void local_coordinate_of_node(const unsigned& j,
75  Vector<double>& s) const
76  {
77  switch (j)
78  {
79  case 0:
80  s[0]=1.0;
81  s[1]=0.0;
82  break;
83 
84  case 1:
85  s[0]=0.0;
86  s[1]=1.0;
87  break;
88 
89  case 2:
90  s[0]=0.0;
91  s[1]=0.0;
92  break;
93 
94  default:
95  std::ostringstream error_message;
96  error_message << "Element only has three nodes; called with node number "
97  << j << std::endl;
98 
99  throw OomphLibError(error_message.str(),
100  "BellElement::local_coordinate_of_node()",
101  OOMPH_EXCEPTION_LOCATION);
102  }
103  }
104 
105  void Bshape(const Vector<double> &s, Shape &psi, DenseMatrix<double> &position) const
106  {
107  //---------------------------------------------
108  // the mapping to physical coordinates
109  //----------------------------------------------
110  Vector<double> phi(2);
111  phi[0] = position(2,0) + (position(0,0) - position(2,0))*s[0] + (position(1,0) - position(2,0))*s[1];
112  phi[1] = position(2,1) + (position(0,1) - position(2,1))*s[0] + (position(1,1) - position(2,1))*s[1];
113 
114  double A = ( (position(1,0)*position(2,1)-position(2,0)*position(1,1)) - (position(0,0)*position(2,1)-position(2,0)*position(0,1)) + (position(0,0)*position(1,1)-position(1,0)*position(0,1)))/2.0;
115  double A0 = ( (position(1,0)*position(2,1)-position(2,0)*position(1,1)) - (phi[0]*position(2,1)-position(2,0)*phi[1]) + (phi[0]*position(1,1)-position(1,0)*phi[1]))/2.0;
116  double A1 = ( (phi[0]*position(2,1)-position(2,0)*phi[1]) - (position(0,0)*position(2,1)-position(2,0)*position(0,1)) + (position(0,0)*phi[1]-phi[0]*position(0,1)))/2.0;
117  double A2 = ( (position(1,0)*phi[1]-phi[0]*position(1,1)) - (position(0,0)*phi[1]-phi[0]*position(0,1)) + (position(0,0)*position(1,1)-position(1,0)*position(0,1)))/2.0;
118  // assigned area coordinates
119  Vector<double> xi(3);
120  xi[0] = A0/A;
121  xi[1] = A1/A;
122  xi[2] = A2/A;
123 
124  Vector<double> b(3);
125  Vector<double> c(3);
126  Vector<double> lamb(3);
127  Vector<double> lamb_p(3);
128  Vector<double> pp(2);
129  Vector<double> a(2),cc(2);
130 
131  //compute for b and c
132  b[1] = position(0,0)-position(2,0);
133  b[2] = position(1,0)-position(0,0);
134  b[0] = position(2,0)-position(1,0);
135 
136  c[1] = position(2,1)-position(0,1);
137  c[2] = position(0,1)-position(1,1);
138  c[0] = position(1,1)-position(2,1);
139 
140  //compute for a point of perpendicular
141  // on the edge opposite to node0 (top vertex)
142  Vector<double> v(2);
143  v[0] = (position(2,0)-position(1,0));
144  v[1] = (position(2,1)-position(1,1));
145  double m = v[1]/v[0];
146  a[0] = position(1,0);
147  a[1] = position(1,1);
148  cc[0] = position(0,0);
149  cc[1] = position(0,1);
150  if(v[0]==0)
151  {
152  m = v[0]/v[1];
153  pp[1] = ( v[0]*m*a[1] + v[1]*cc[1] - v[0]*a[0] + v[0]*cc[0] )/((v[0]*m)+v[1]);
154  pp[0] = (pp[1]-a[1])*m + a[0];
155  }
156  else
157  {
158  pp[0] = (v[1]*m*a[0] + v[1]*cc[1] - v[1]*a[1] + v[0]*cc[0])/(v[1]*m+v[0]);
159  pp[1] = m*(pp[0]-a[0]) + a[1];
160  }
161  double l = sqrt(v[0]*v[0] + v[1]*v[1]);
162  double l1 = sqrt( (pp[0]-a[0])*(pp[0]-a[0]) + (pp[1]-a[1])*(pp[1]-a[1]));
163  lamb_p[0] = l1/l;
164  lamb[0] = 1-lamb_p[0];
165 
166  // on the edge opposite to node1
167  v[0] = (position(0,0)-position(2,0));
168  v[1] = (position(0,1)-position(2,1));
169  m = v[1]/v[0];
170  a[0] = position(2,0);
171  a[1] = position(2,1);
172  cc[0] = position(1,0);
173  cc[1] = position(1,1);
174  if(v[0]==0)
175  {
176  m = v[0]/v[1];
177  pp[1] = ( v[0]*m*a[1] + v[1]*cc[1] - v[0]*a[0] + v[0]*cc[0] )/((v[0]*m)+v[1]);
178  pp[0] = (pp[1]-a[1])*m + a[0];
179  }
180  else
181  {
182  pp[0] = (v[1]*m*a[0] + v[1]*cc[1] - v[1]*a[1] + v[0]*cc[0])/(v[1]*m+v[0]);
183  pp[1] = m*(pp[0]-a[0]) + a[1];
184  }
185  l = sqrt(v[0]*v[0] + v[1]*v[1]);
186  l1 = sqrt( (pp[0]-a[0])*(pp[0]-a[0]) + (pp[1]-a[1])*(pp[1]-a[1]));
187  lamb_p[1] = l1/l;
188  lamb[1] = 1-lamb_p[1];
189 
190  // on the edge opposite to node2 (right bottom)
191  v[0] = (position(1,0)-position(0,0));
192  v[1] = (position(1,1)-position(0,1));
193  m = v[1]/v[0];
194  a[0] = position(0,0);
195  a[1] = position(0,1);
196  cc[0] = position(2,0);
197  cc[1] = position(2,1);
198  if(v[0]==0)
199  {
200  m = v[0]/v[1];
201  pp[1] = ( v[0]*m*a[1] + v[1]*cc[1] - v[0]*a[0] + v[0]*cc[0] )/((v[0]*m)+v[1]);
202  pp[0] = (pp[1]-a[1])*m + a[0];
203  }
204  else
205  {
206  pp[0] = (v[1]*m*a[0] + v[1]*cc[1] - v[1]*a[1] + v[0]*cc[0])/(v[1]*m+v[0]);
207  pp[1] = m*(pp[0]-a[0]) + a[1];
208  }
209  l = sqrt(v[0]*v[0] + v[1]*v[1]);
210  l1 = sqrt( (pp[0]-a[0])*(pp[0]-a[0]) + (pp[1]-a[1])*(pp[1]-a[1]));
211  lamb_p[2] = l1/l;
212  lamb[2] = 1-lamb_p[2];
213 
214  // define shape functions that associated to dofs at node 0
215  psi(0,0) = xi[0]*xi[0]*xi[0]*xi[0]*xi[0] +5.0*xi[0]*xi[0]*xi[0]*xi[0]*(xi[1]+xi[2]) + 10.0*xi[0]*xi[0]*xi[0]*(xi[1]+xi[2])*(xi[1]+xi[2])
216  +30.0*xi[0]*xi[0]*xi[1]*xi[2]*(lamb[2]*xi[1] + lamb_p[1]*xi[2]);
217  psi(0,1) = 3.0*b[0]*xi[0]*xi[0]*xi[1]*xi[2]*(xi[1]-xi[2]) + xi[0]*xi[0]*xi[0]*(b[2]*xi[1] -b[1]*xi[2])*(xi[0] + 4.0*xi[1] + 4*xi[2])
218  + 15*xi[0]*xi[0]*xi[1]*xi[2]*(b[2]*lamb[2]*xi[1] - b[1]*lamb_p[1]*xi[2]);
219  psi(0,2) = -3.0*c[0]*xi[0]*xi[0]*xi[1]*xi[2]*(xi[1]-xi[2]) - xi[0]*xi[0]*xi[0]*(c[2]*xi[1] - c[1]*xi[2])*(xi[0] + 4.0*xi[1] + 4.0*xi[2])
220  -15.0*xi[0]*xi[0]*xi[1]*xi[2]*(c[2]*lamb[2]*xi[1] -c[1]*lamb_p[1]*xi[2]);
221  psi(0,3) = 1.0/2.0*xi[0]*xi[0]*xi[0]*(b[2]*b[2]*xi[1]*xi[1] + b[1]*b[1]*xi[2]*xi[2]) + xi[0]*xi[0]*xi[1]*xi[2]*(-b[1]*b[2]*xi[0] + b[2]*b[0]*xi[1] + b[0]*b[1]*xi[2])
222  + 5.0/2.0*xi[0]*xi[0]*xi[1]*xi[2]*(b[2]*b[2]*lamb[2]*xi[1] + b[1]*b[1]*lamb_p[1]*xi[2]);
223  psi(0,4) = 1.0/2.0*xi[0]*xi[0]*xi[0]*(c[2]*c[2]*xi[1]*xi[1] + c[1]*c[1]*xi[2]*xi[2]) + xi[0]*xi[0]*xi[1]*xi[2]*(-c[1]*c[2]*xi[0] + c[2]*c[0]*xi[1] + c[0]*c[1]*xi[2])
224  + 5.0/2.0*xi[0]*xi[0]*xi[1]*xi[2]*(c[2]*c[2]*lamb[2]*xi[1] + c[1]*c[1]*lamb_p[1]*xi[2]);
225  psi(0,5) = b[0]*c[0]*xi[0]*xi[0]*xi[1]*xi[2]*(xi[0] + xi[1] + xi[2]) + b[1]*c[1]*xi[0]*xi[0]*xi[2]*(xi[1]*xi[2] - xi[2]*xi[0] - xi[0]*xi[1] - xi[1]*xi[1])
226  + b[2]*c[2]*xi[0]*xi[0]*xi[1]*(xi[1]*xi[2] - xi[2]*xi[0] -xi[0]*xi[1] - xi[2]*xi[2]) - 5.0*xi[0]*xi[0]*xi[1]*xi[2]*(b[1]*c[1]*lamb_p[1]*xi[2] + b[2]*c[2]*lamb[2]*xi[1]);
227 
228  // define shape functions that associated to dofs at node 1
229  psi(1,0) = xi[1]*xi[1]*xi[1]*xi[1]*xi[1] +5.0*xi[1]*xi[1]*xi[1]*xi[1]*(xi[2]+xi[0]) + 10.0*xi[1]*xi[1]*xi[1]*(xi[2]+xi[0])*(xi[2]+xi[0])
230  +30.0*xi[1]*xi[1]*xi[2]*xi[0]*(lamb[0]*xi[2] + lamb_p[2]*xi[0]);
231  psi(1,1) = 3.0*b[1]*xi[1]*xi[1]*xi[2]*xi[0]*(xi[2]-xi[0]) + xi[1]*xi[1]*xi[1]*(b[0]*xi[2] -b[2]*xi[0])*(xi[1] + 4.0*xi[2] + 4*xi[0])
232  + 15*xi[1]*xi[1]*xi[2]*xi[0]*(b[0]*lamb[0]*xi[2] - b[2]*lamb_p[2]*xi[0]);
233  psi(1,2) = -3.0*c[1]*xi[1]*xi[1]*xi[2]*xi[0]*(xi[2]-xi[0]) - xi[1]*xi[1]*xi[1]*(c[0]*xi[2] - c[2]*xi[0])*(xi[1] + 4.0*xi[2] + 4.0*xi[0])
234  -15.0*xi[1]*xi[1]*xi[2]*xi[0]*(c[0]*lamb[0]*xi[2] -c[2]*lamb_p[2]*xi[0]);
235  psi(1,3) = 1.0/2.0*xi[1]*xi[1]*xi[1]*(b[0]*b[0]*xi[2]*xi[2] + b[2]*b[2]*xi[0]*xi[0]) + xi[1]*xi[1]*xi[2]*xi[0]*(-b[2]*b[0]*xi[1] + b[0]*b[1]*xi[2] + b[1]*b[2]*xi[0])
236  + 5.0/2.0*xi[1]*xi[1]*xi[2]*xi[0]*(b[0]*b[0]*lamb[0]*xi[2] + b[2]*b[2]*lamb_p[2]*xi[0]);
237  psi(1,4) = 1.0/2.0*xi[1]*xi[1]*xi[1]*(c[0]*c[0]*xi[2]*xi[2] + c[2]*c[2]*xi[0]*xi[0]) + xi[1]*xi[1]*xi[2]*xi[0]*(-c[2]*c[0]*xi[1] + c[0]*c[1]*xi[2] + c[1]*c[2]*xi[0])
238  + 5.0/2.0*xi[1]*xi[1]*xi[2]*xi[0]*(c[0]*c[0]*lamb[0]*xi[2] + c[2]*c[2]*lamb_p[2]*xi[0]);
239  psi(1,5) = b[1]*c[1]*xi[1]*xi[1]*xi[2]*xi[0]*(xi[1] + xi[2] + xi[0]) + b[2]*c[2]*xi[1]*xi[1]*xi[0]*(xi[2]*xi[0] - xi[0]*xi[1] - xi[1]*xi[2] - xi[2]*xi[2])
240  + b[0]*c[0]*xi[1]*xi[1]*xi[2]*(xi[2]*xi[0] - xi[0]*xi[1] -xi[1]*xi[2] - xi[0]*xi[0]) - 5.0*xi[1]*xi[1]*xi[2]*xi[0]*(b[2]*c[2]*lamb_p[2]*xi[0] + b[0]*c[0]*lamb[0]*xi[2]);
241 
242  // define shape functions that associated to dofs at node 2
243  psi(2,0) = xi[2]*xi[2]*xi[2]*xi[2]*xi[2] +5.0*xi[2]*xi[2]*xi[2]*xi[2]*(xi[0]+xi[1]) + 10.0*xi[2]*xi[2]*xi[2]*(xi[0]+xi[1])*(xi[0]+xi[1])
244  +30.0*xi[2]*xi[2]*xi[0]*xi[1]*(lamb[1]*xi[0] + lamb_p[0]*xi[1]);
245  psi(2,1) = 3.0*b[2]*xi[2]*xi[2]*xi[0]*xi[1]*(xi[0]-xi[1]) + xi[2]*xi[2]*xi[2]*(b[1]*xi[0] -b[0]*xi[1])*(xi[2] + 4.0*xi[0] + 4*xi[1])
246  + 15*xi[2]*xi[2]*xi[0]*xi[1]*(b[1]*lamb[1]*xi[0] - b[0]*lamb_p[0]*xi[1]);
247  psi(2,2) = -3.0*c[2]*xi[2]*xi[2]*xi[0]*xi[1]*(xi[0]-xi[1]) - xi[2]*xi[2]*xi[2]*(c[1]*xi[0] - c[0]*xi[1])*(xi[2] + 4.0*xi[0] + 4.0*xi[1])
248  -15.0*xi[2]*xi[2]*xi[0]*xi[1]*(c[1]*lamb[1]*xi[0] -c[0]*lamb_p[0]*xi[1]);
249  psi(2,3) = 1.0/2.0*xi[2]*xi[2]*xi[2]*(b[1]*b[1]*xi[0]*xi[0] + b[0]*b[0]*xi[1]*xi[1]) + xi[2]*xi[2]*xi[0]*xi[1]*(-b[0]*b[1]*xi[2] + b[1]*b[2]*xi[0] + b[2]*b[0]*xi[1])
250  + 5.0/2.0*xi[2]*xi[2]*xi[0]*xi[1]*(b[1]*b[1]*lamb[1]*xi[0] + b[0]*b[0]*lamb_p[0]*xi[1]);
251  psi(2,4) = 1.0/2.0*xi[2]*xi[2]*xi[2]*(c[1]*c[1]*xi[0]*xi[0] + c[0]*c[0]*xi[1]*xi[1]) + xi[2]*xi[2]*xi[0]*xi[1]*(-c[0]*c[1]*xi[2] + c[1]*c[2]*xi[0] + c[2]*c[0]*xi[1])
252  + 5.0/2.0*xi[2]*xi[2]*xi[0]*xi[1]*(c[1]*c[1]*lamb[1]*xi[0] + c[0]*c[0]*lamb_p[0]*xi[1]);
253  psi(2,5) = b[2]*c[2]*xi[2]*xi[2]*xi[0]*xi[1]*(xi[2] + xi[0] + xi[1]) + b[0]*c[0]*xi[2]*xi[2]*xi[1]*(xi[0]*xi[1] - xi[1]*xi[2] - xi[2]*xi[0] - xi[0]*xi[0])
254  + b[1]*c[1]*xi[2]*xi[2]*xi[0]*(xi[0]*xi[1] - xi[1]*xi[2] -xi[2]*xi[0] - xi[1]*xi[1]) - 5.0*xi[2]*xi[2]*xi[0]*xi[1]*(b[0]*c[0]*lamb_p[0]*xi[1] + b[1]*c[1]*lamb[1]*xi[0]);
255 
256  }
257 
258  void dBshape_local(const Vector<double> &s, Shape &psi, DShape &dpsids, DenseMatrix<double> &position) const
259  {
260  // assign for shape functions
261  Bshape(s,psi,position);
262  //---------------------------------------------
263  // the mapping to physical coordinates
264  //----------------------------------------------
265  Vector<double> phi(2);
266  phi[0] = position(2,0) + (position(0,0) - position(2,0))*s[0] + (position(1,0) - position(2,0))*s[1];
267  phi[1] = position(2,1) + (position(0,1) - position(2,1))*s[0] + (position(1,1) - position(2,1))*s[1];
268 
269  double A = ( (position(1,0)*position(2,1)-position(2,0)*position(1,1)) - (position(0,0)*position(2,1)-position(2,0)*position(0,1)) + (position(0,0)*position(1,1)-position(1,0)*position(0,1)))/2.0;
270  double A0, A1, A2;
271  A0 = ( (position(1,0)*position(2,1)-position(2,0)*position(1,1)) - (phi[0]*position(2,1)-position(2,0)*phi[1]) + (phi[0]*position(1,1)-position(1,0)*phi[1]))/2.0;
272  A1 = ( (phi[0]*position(2,1)-position(2,0)*phi[1]) - (position(0,0)*position(2,1)-position(2,0)*position(0,1)) + (position(0,0)*phi[1]-phi[0]*position(0,1)))/2.0;
273  A2 = ( (position(1,0)*phi[1]-phi[0]*position(1,1)) - (position(0,0)*phi[1]-phi[0]*position(0,1)) + (position(0,0)*position(1,1)-position(1,0)*position(0,1)))/2.0;
274 
275  // assigned area coordinates
276  Vector<double> xi(3);
277  xi[0] = A0/A;
278  xi[1] = A1/A;
279  xi[2] = A2/A;
280 
281  Vector<double> b(3);
282  Vector<double> c(3);
283  Vector<double> lamb(3);
284  Vector<double> lamb_p(3);
285  Vector<double> pp(2);
286  Vector<double> a(2),cc(2);
287 
288  //compute for b and c
289  b[1] = position(0,0)-position(2,0);
290  b[2] = position(1,0)-position(0,0);
291  b[0] = position(2,0)-position(1,0);
292 
293  c[1] = position(2,1)-position(0,1);
294  c[2] = position(0,1)-position(1,1);
295  c[0] = position(1,1)-position(2,1);
296 
297  //compute for a point of perpendicular
298  // on the edge opposite to node0 (top vertex)
299  Vector<double> v(2);
300  v[0] = (position(2,0)-position(1,0));
301  v[1] = (position(2,1)-position(1,1));
302  double m = v[1]/v[0];
303  a[0] = position(1,0);
304  a[1] = position(1,1);
305  cc[0] = position(0,0);
306  cc[1] = position(0,1);
307  if(v[0]==0)
308  {
309  m = v[0]/v[1];
310  pp[1] = ( v[0]*m*a[1] + v[1]*cc[1] - v[0]*a[0] + v[0]*cc[0] )/((v[0]*m)+v[1]);
311  pp[0] = (pp[1]-a[1])*m + a[0];
312  }
313  else
314  {
315  pp[0] = (v[1]*m*a[0] + v[1]*cc[1] - v[1]*a[1] + v[0]*cc[0])/(v[1]*m+v[0]);
316  pp[1] = m*(pp[0]-a[0]) + a[1];
317  }
318  double l = sqrt(v[0]*v[0] + v[1]*v[1]);
319  double l1 = sqrt( (pp[0]-a[0])*(pp[0]-a[0]) + (pp[1]-a[1])*(pp[1]-a[1]));
320  lamb_p[0] = l1/l;
321  lamb[0] = 1-lamb_p[0];
322 
323  // on the edge opposite to node1
324  v[0] = (position(0,0)-position(2,0));
325  v[1] = (position(0,1)-position(2,1));
326  m = v[1]/v[0];
327  a[0] = position(2,0);
328  a[1] = position(2,1);
329  cc[0] = position(1,0);
330  cc[1] = position(1,1);
331  if(v[0]==0)
332  {
333  m = v[0]/v[1];
334  pp[1] = ( v[0]*m*a[1] + v[1]*cc[1] - v[0]*a[0] + v[0]*cc[0] )/((v[0]*m)+v[1]);
335  pp[0] = (pp[1]-a[1])*m + a[0];
336  }
337  else
338  {
339  pp[0] = (v[1]*m*a[0] + v[1]*cc[1] - v[1]*a[1] + v[0]*cc[0])/(v[1]*m+v[0]);
340  pp[1] = m*(pp[0]-a[0]) + a[1];
341  }
342  l = sqrt(v[0]*v[0] + v[1]*v[1]);
343  l1 = sqrt( (pp[0]-a[0])*(pp[0]-a[0]) + (pp[1]-a[1])*(pp[1]-a[1]));
344  lamb_p[1] = l1/l;
345  lamb[1] = 1-lamb_p[1];
346 
347  // on the edge opposite to node2 (right bottom)
348  v[0] = (position(1,0)-position(0,0));
349  v[1] = (position(1,1)-position(0,1));
350  m = v[1]/v[0];
351  a[0] = position(0,0);
352  a[1] = position(0,1);
353  cc[0] = position(2,0);
354  cc[1] = position(2,1);
355  if(v[0]==0)
356  {
357  m = v[0]/v[1];
358  pp[1] = ( v[0]*m*a[1] + v[1]*cc[1] - v[0]*a[0] + v[0]*cc[0] )/((v[0]*m)+v[1]);
359  pp[0] = (pp[1]-a[1])*m + a[0];
360  }
361  else
362  {
363  pp[0] = (v[1]*m*a[0] + v[1]*cc[1] - v[1]*a[1] + v[0]*cc[0])/(v[1]*m+v[0]);
364  pp[1] = m*(pp[0]-a[0]) + a[1];
365  }
366  l = sqrt(v[0]*v[0] + v[1]*v[1]);
367  l1 = sqrt( (pp[0]-a[0])*(pp[0]-a[0]) + (pp[1]-a[1])*(pp[1]-a[1]));
368  lamb_p[2] = l1/l;
369  lamb[2] = 1-lamb_p[2];
370 
371 
372  Vector<double> dxids0(3,0.0);
373  Vector<double> dxids1(3,0.0);
374 
375  dxids0[0] = c[0]/A/2.0;
376  dxids0[1] = c[1]/A/2.0;
377  dxids0[2] = c[2]/A/2.0;
378 
379  dxids1[0] = b[0]/A/2.0;
380  dxids1[1] = b[1]/A/2.0;
381  dxids1[2] = b[2]/A/2.0;
382 
383  DShape psi1(3,6,3);
384  // define dshape functions that associated to dofs at node 0
385  psi1(0,0,0) = 5.0*xi[0]*xi[0]*xi[0]*xi[0] + 5.0*4.0*xi[0]*xi[0]*xi[0]*(xi[1]+xi[2]) + 10.0*3.0*xi[0]*xi[0]*(xi[1]+xi[2])*(xi[1]+xi[2])
386  +30.0*2.0*xi[0]*xi[1]*xi[2]*(lamb[2]*xi[1] + lamb_p[1]*xi[2]);
387  psi1(0,1,0) = 3.0*b[0]*2.0*xi[0]*xi[1]*xi[2]*(xi[1]-xi[2]) + 3.0*xi[0]*xi[0]*(b[2]*xi[1] -b[1]*xi[2])*(xi[0] + 4.0*xi[1] + 4.0*xi[2])
388  + xi[0]*xi[0]*xi[0]*(b[2]*xi[1] -b[1]*xi[2]) + 15*2.0*xi[0]*xi[1]*xi[2]*(b[2]*lamb[2]*xi[1] - b[1]*lamb_p[1]*xi[2]);
389  psi1(0,2,0) = -3.0*c[0]*2.0*xi[0]*xi[1]*xi[2]*(xi[1]-xi[2]) - 3.0*xi[0]*xi[0]*(c[2]*xi[1] - c[1]*xi[2])*(xi[0] + 4.0*xi[1] + 4.0*xi[2]) - xi[0]*xi[0]*xi[0]*(c[2]*xi[1] - c[1]*xi[2])
390  -15.0*2.0*xi[0]*xi[1]*xi[2]*(c[2]*lamb[2]*xi[1] -c[1]*lamb_p[1]*xi[2]);
391  psi1(0,3,0) = 1.0/2.0*3.0*xi[0]*xi[0]*(b[2]*b[2]*xi[1]*xi[1] + b[1]*b[1]*xi[2]*xi[2]) + 2.0*xi[0]*xi[1]*xi[2]*(-b[1]*b[2]*xi[0] + b[2]*b[0]*xi[1] + b[0]*b[1]*xi[2])
392  + 5.0/2.0*2.0*xi[0]*xi[1]*xi[2]*(b[2]*b[2]*lamb[2]*xi[1] + b[1]*b[1]*lamb_p[1]*xi[2]) + xi[0]*xi[0]*xi[1]*xi[2]*(-b[1]*b[2]);
393  psi1(0,4,0) = 1.0/2.0*3.0*xi[0]*xi[0]*(c[2]*c[2]*xi[1]*xi[1] + c[1]*c[1]*xi[2]*xi[2]) + 2.0*xi[0]*xi[1]*xi[2]*(-c[1]*c[2]*xi[0] + c[2]*c[0]*xi[1] + c[0]*c[1]*xi[2])
394  + 5.0/2.0*2.0*xi[0]*xi[1]*xi[2]*(c[2]*c[2]*lamb[2]*xi[1] + c[1]*c[1]*lamb_p[1]*xi[2])+ xi[0]*xi[0]*xi[1]*xi[2]*(-c[1]*c[2]);
395  psi1(0,5,0) = b[0]*c[0]*2.0*xi[0]*xi[1]*xi[2]*(xi[0] + xi[1] + xi[2]) + b[0]*c[0]*xi[0]*xi[0]*xi[1]*xi[2] + b[1]*c[1]*2.0*xi[0]*xi[2]*(xi[1]*xi[2] - xi[2]*xi[0] - xi[0]*xi[1] - xi[1]*xi[1])
396  + b[1]*c[1]*xi[0]*xi[0]*xi[2]*(-xi[1] - xi[2]) + b[2]*c[2]*2.0*xi[0]*xi[1]*(xi[1]*xi[2] - xi[2]*xi[0] -xi[0]*xi[1] - xi[2]*xi[2])
397  + b[2]*c[2]*xi[0]*xi[0]*xi[1]*(-xi[2]-xi[1]) - 5.0*2.0*xi[0]*xi[1]*xi[2]*(b[1]*c[1]*lamb_p[1]*xi[2] + b[2]*c[2]*lamb[2]*xi[1]);
398 
399  psi1(0,0,1) = 5.0*xi[0]*xi[0]*xi[0]*xi[0] + 10.0*xi[0]*xi[0]*xi[0]*2.0*(xi[1]+xi[2])
400  +30.0*xi[0]*xi[0]*xi[2]*(lamb[2]*xi[1] + lamb_p[1]*xi[2])+30.0*xi[0]*xi[0]*xi[1]*xi[2]*(lamb[2]);
401  psi1(0,1,1) = 3.0*b[0]*xi[0]*xi[0]*xi[2]*(xi[1]-xi[2])+ 3.0*b[0]*xi[0]*xi[0]*xi[1]*xi[2] + xi[0]*xi[0]*xi[0]*(b[2])*(xi[0] + 4.0*xi[1] + 4*xi[2])
402  + xi[0]*xi[0]*xi[0]*(b[2]*xi[1] -b[1]*xi[2])*(4.0) + 15*xi[0]*xi[0]*xi[2]*(b[2]*lamb[2]*xi[1] - b[1]*lamb_p[1]*xi[2]) +15*xi[0]*xi[0]*xi[1]*xi[2]*(b[2]*lamb[2]);
403  psi1(0,2,1) = -3.0*c[0]*xi[0]*xi[0]*xi[2]*(xi[1]-xi[2]) - 3.0*c[0]*xi[0]*xi[0]*xi[1]*xi[2] - xi[0]*xi[0]*xi[0]*(c[2]*xi[1] - c[1]*xi[2])*(4.0) - xi[0]*xi[0]*xi[0]*(c[2])*(xi[0] + 4.0*xi[1] + 4.0*xi[2]) -15.0*xi[0]*xi[0]*xi[1]*xi[2]*(c[2]*lamb[2])
404  -15.0*xi[0]*xi[0]*xi[2]*(c[2]*lamb[2]*xi[1] -c[1]*lamb_p[1]*xi[2]);
405  psi1(0,3,1) = 1.0/2.0*xi[0]*xi[0]*xi[0]*(b[2]*b[2]*2.0*xi[1]) + xi[0]*xi[0]*xi[1]*xi[2]*(b[2]*b[0]) + xi[0]*xi[0]*xi[2]*(-b[1]*b[2]*xi[0] + b[2]*b[0]*xi[1] + b[0]*b[1]*xi[2]) + 5.0/2.0*xi[0]*xi[0]*xi[1]*xi[2]*(b[2]*b[2]*lamb[2]) + 5.0/2.0*xi[0]*xi[0]*xi[2]*(b[2]*b[2]*lamb[2]*xi[1] + b[1]*b[1]*lamb_p[1]*xi[2]);
406  psi1(0,4,1) = 1.0/2.0*xi[0]*xi[0]*xi[0]*(c[2]*c[2]*2.0*xi[1]) + xi[0]*xi[0]*xi[1]*xi[2]*(c[2]*c[0]) + xi[0]*xi[0]*xi[2]*(-c[1]*c[2]*xi[0] + c[2]*c[0]*xi[1] + c[0]*c[1]*xi[2])+ 5.0/2.0*xi[0]*xi[0]*xi[1]*xi[2]*(c[2]*c[2]*lamb[2]) + 5.0/2.0*xi[0]*xi[0]*xi[2]*(c[2]*c[2]*lamb[2]*xi[1] + c[1]*c[1]*lamb_p[1]*xi[2]);
407  psi1(0,5,1) = b[0]*c[0]*xi[0]*xi[0]*xi[1]*xi[2] + b[0]*c[0]*xi[0]*xi[0]*xi[2]*(xi[0] + xi[1] + xi[2]) + b[1]*c[1]*xi[0]*xi[0]*xi[2]*(xi[2] - xi[0] - 2.0*xi[1])
408  + b[2]*c[2]*xi[0]*xi[0]*(xi[1]*xi[2] - xi[2]*xi[0] -xi[0]*xi[1] - xi[2]*xi[2]) + b[2]*c[2]*xi[0]*xi[0]*xi[1]*(xi[2]-xi[0]) - 5.0*xi[0]*xi[0]*xi[2]*(b[1]*c[1]*lamb_p[1]*xi[2] + b[2]*c[2]*lamb[2]*xi[1])
409  - 5.0*xi[0]*xi[0]*xi[1]*xi[2]*(b[2]*c[2]*lamb[2]);
410 
411  psi1(0,0,2) = 5.0*xi[0]*xi[0]*xi[0]*xi[0] + 10.0*xi[0]*xi[0]*xi[0]*2.0*(xi[1]+xi[2])
412  +30.0*xi[0]*xi[0]*xi[1]*xi[2]*(lamb_p[1]) +30.0*xi[0]*xi[0]*xi[1]*(lamb[2]*xi[1] + lamb_p[1]*xi[2]);
413  psi1(0,1,2) = 3.0*b[0]*xi[0]*xi[0]*xi[1]*xi[2]*(-1.0) + 3.0*b[0]*xi[0]*xi[0]*xi[1]*(xi[1]-xi[2]) + xi[0]*xi[0]*xi[0]*(b[2]*xi[1] -b[1]*xi[2])*( 4.0)+ xi[0]*xi[0]*xi[0]*(-b[1])*(xi[0] + 4.0*xi[1] + 4*xi[2]) + 15*xi[0]*xi[0]*xi[1]*xi[2]*(- b[1]*lamb_p[1])
414  + 15*xi[0]*xi[0]*xi[1]*(b[2]*lamb[2]*xi[1] - b[1]*lamb_p[1]*xi[2]);
415  psi1(0,2,2) = -3.0*c[0]*xi[0]*xi[0]*xi[1]*xi[2]*(-1.0) + -3.0*c[0]*xi[0]*xi[0]*xi[1]*(xi[1]-xi[2]) - xi[0]*xi[0]*xi[0]*(c[2]*xi[1] - c[1]*xi[2])*( 4.0) - xi[0]*xi[0]*xi[0]*(-1.0*c[1])*(xi[0] + 4.0*xi[1] + 4.0*xi[2]) -15.0*xi[0]*xi[0]*xi[1]*xi[2]*( -1.0*c[1]*lamb_p[1]) -15.0*xi[0]*xi[0]*xi[1]*(c[2]*lamb[2]*xi[1] -c[1]*lamb_p[1]*xi[2]);
416  psi1(0,3,2) = 1.0/2.0*xi[0]*xi[0]*xi[0]*(b[1]*b[1]*2.0*xi[2]) + xi[0]*xi[0]*xi[1]*xi[2]*( b[0]*b[1]) + xi[0]*xi[0]*xi[1]*(-b[1]*b[2]*xi[0] + b[2]*b[0]*xi[1] + b[0]*b[1]*xi[2]) + 5.0/2.0*xi[0]*xi[0]*xi[1]*xi[2]*( b[1]*b[1]*lamb_p[1])+ 5.0/2.0*xi[0]*xi[0]*xi[1]*(b[2]*b[2]*lamb[2]*xi[1] + b[1]*b[1]*lamb_p[1]*xi[2]);
417  psi1(0,4,2) = 1.0/2.0*xi[0]*xi[0]*xi[0]*(c[1]*c[1]*2.0*xi[2]) + xi[0]*xi[0]*xi[1]*xi[2]*(c[0]*c[1]) + xi[0]*xi[0]*xi[1]*(-c[1]*c[2]*xi[0] + c[2]*c[0]*xi[1] + c[0]*c[1]*xi[2]) + 5.0/2.0*xi[0]*xi[0]*xi[1]*xi[2]*(c[1]*c[1]*lamb_p[1]) + 5.0/2.0*xi[0]*xi[0]*xi[1]*(c[2]*c[2]*lamb[2]*xi[1] + c[1]*c[1]*lamb_p[1]*xi[2]);
418  psi1(0,5,2) = b[0]*c[0]*xi[0]*xi[0]*xi[1]*xi[2] + b[0]*c[0]*xi[0]*xi[0]*xi[1]*(xi[0] + xi[1] + xi[2]) + b[1]*c[1]*xi[0]*xi[0]*xi[2]*(xi[1] - xi[0]) + b[1]*c[1]*xi[0]*xi[0]*(xi[1]*xi[2] - xi[2]*xi[0] - xi[0]*xi[1] - xi[1]*xi[1]) + b[2]*c[2]*xi[0]*xi[0]*xi[1]*(xi[1] - xi[0] - 2.0*xi[2]) - 5.0*xi[0]*xi[0]*xi[1]*xi[2]*(b[1]*c[1]*lamb_p[1])
419  - 5.0*xi[0]*xi[0]*xi[1]*(b[1]*c[1]*lamb_p[1]*xi[2] + b[2]*c[2]*lamb[2]*xi[1]);
420 
421  // by chain rule, we can obtain dshape wrt s0 at node0
422  dpsids(0,0,0) = psi1(0,0,0)*dxids0[0] + psi1(0,0,1)*dxids0[1] + psi1(0,0,2)*dxids0[2];
423  dpsids(0,1,0) = psi1(0,1,0)*dxids0[0] + psi1(0,1,1)*dxids0[1] + psi1(0,1,2)*dxids0[2];
424  dpsids(0,2,0) = psi1(0,2,0)*dxids0[0] + psi1(0,2,1)*dxids0[1] + psi1(0,2,2)*dxids0[2];
425  dpsids(0,3,0) = psi1(0,3,0)*dxids0[0] + psi1(0,3,1)*dxids0[1] + psi1(0,3,2)*dxids0[2];
426  dpsids(0,4,0) = psi1(0,4,0)*dxids0[0] + psi1(0,4,1)*dxids0[1] + psi1(0,4,2)*dxids0[2];
427  dpsids(0,5,0) = psi1(0,5,0)*dxids0[0] + psi1(0,5,1)*dxids0[1] + psi1(0,5,2)*dxids0[2];
428 
429  // by chain rule, we can obtain dshape wrt s1 at node0
430  dpsids(0,0,1) = psi1(0,0,0)*dxids1[0] + psi1(0,0,1)*dxids1[1] + psi1(0,0,2)*dxids1[2];
431  dpsids(0,1,1) = psi1(0,1,0)*dxids1[0] + psi1(0,1,1)*dxids1[1] + psi1(0,1,2)*dxids1[2];
432  dpsids(0,2,1) = psi1(0,2,0)*dxids1[0] + psi1(0,2,1)*dxids1[1] + psi1(0,2,2)*dxids1[2];
433  dpsids(0,3,1) = psi1(0,3,0)*dxids1[0] + psi1(0,3,1)*dxids1[1] + psi1(0,3,2)*dxids1[2];
434  dpsids(0,4,1) = psi1(0,4,0)*dxids1[0] + psi1(0,4,1)*dxids1[1] + psi1(0,4,2)*dxids1[2];
435  dpsids(0,5,1) = psi1(0,5,0)*dxids1[0] + psi1(0,5,1)*dxids1[1] + psi1(0,5,2)*dxids1[2];
436  //-------------------------------------------------------------------------------------
437  // define shape functions that associated to dofs at node 1
438  // wrt area coordinate 1
439  psi1(1,0,1) = 5.0*xi[1]*xi[1]*xi[1]*xi[1] +5.0*4.0*xi[1]*xi[1]*xi[1]*(xi[2]+xi[0]) + 10.0*3.0*xi[1]*xi[1]*(xi[2]+xi[0])*(xi[2]+xi[0]) +30.0*2.0*xi[1]*xi[2]*xi[0]*(lamb[0]*xi[2] + lamb_p[2]*xi[0]);
440  psi1(1,1,1) = 3.0*b[1]*2.0*xi[1]*xi[2]*xi[0]*(xi[2]-xi[0]) + 3.0*xi[1]*xi[1]*(b[0]*xi[2] -b[2]*xi[0])*(xi[1] + 4.0*xi[2] + 4.0*xi[0]) +xi[1]*xi[1]*xi[1]*(b[0]*xi[2] -b[2]*xi[0]) + 15*2.0*xi[1]*xi[2]*xi[0]*(b[0]*lamb[0]*xi[2] - b[2]*lamb_p[2]*xi[0]);
441  psi1(1,2,1) = -3.0*c[1]*2.0*xi[1]*xi[2]*xi[0]*(xi[2]-xi[0]) - 3.0*xi[1]*xi[1]*(c[0]*xi[2] -c[2]*xi[0])*(xi[1] + 4.0*xi[2] + 4.0*xi[0]) - xi[1]*xi[1]*xi[1]*(c[0]*xi[2] -c[2]*xi[0]) -15.0*2.0*xi[1]*xi[2]*xi[0]*(c[0]*lamb[0]*xi[2] -c[2]*lamb_p[2]*xi[0]);
442  psi1(1,3,1) = 1.0/2.0*3.0*xi[1]*xi[1]*(b[0]*b[0]*xi[2]*xi[2] + b[2]*b[2]*xi[0]*xi[0]) + 2.0*xi[1]*xi[2]*xi[0]*(-b[2]*b[0]*xi[1] + b[0]*b[1]*xi[2] + b[1]*b[2]*xi[0]) + 5.0/2.0*2.0*xi[1]*xi[2]*xi[0]*(b[0]*b[0]*lamb[0]*xi[2] + b[2]*b[2]*lamb_p[2]*xi[0]) + xi[1]*xi[1]*xi[2]*xi[0]*(-b[2])*b[0];
443  psi1(1,4,1) = 1.0/2.0*3.0*xi[1]*xi[1]*(c[0]*c[0]*xi[2]*xi[2] + c[2]*c[2]*xi[0]*xi[0]) + 2.0*xi[1]*xi[2]*xi[0]*(-c[2]*c[0]*xi[1] + c[0]*c[1]*xi[2] + c[1]*c[2]*xi[0])
444  + 5.0/2.0*2.0*xi[1]*xi[2]*xi[0]*(c[0]*c[0]*lamb[0]*xi[2] + c[2]*c[2]*lamb_p[2]*xi[0])+ xi[1]*xi[1]*xi[2]*xi[0]*(-c[2])*c[0];
445  psi1(1,5,1) = b[1]*c[1]*2.0*xi[1]*xi[2]*xi[0]*(xi[1] + xi[2] + xi[0]) + b[1]*c[1]*xi[1]*xi[1]*xi[2]*xi[0] + b[2]*c[2]*2.0*xi[1]*xi[0]*(xi[2]*xi[0] - xi[0]*xi[1] - xi[1]*xi[2] - xi[2]*xi[2]) + b[2]*c[2]*xi[1]*xi[1]*xi[0]*(-xi[2] - xi[0]) + b[0]*c[0]*2.0*xi[1]*xi[2]*(xi[2]*xi[0] - xi[0]*xi[1] -xi[1]*xi[2] - xi[0]*xi[0]) + b[0]*c[0]*xi[1]*xi[1]*xi[2]*(- xi[0]-xi[2]) - 5.0*2.0*xi[1]*xi[2]*xi[0]*(b[2]*c[2]*lamb_p[2]*xi[0] + b[0]*c[0]*lamb[0]*xi[2]);
446 
447  // wrt area coordinate2
448  psi1(1,0,2) = 5.0*xi[1]*xi[1]*xi[1]*xi[1] + 10.0*xi[1]*xi[1]*xi[1]*2.0*(xi[2]+xi[0])+30.0*xi[1]*xi[1]*xi[0]*(lamb[0]*xi[2] + lamb_p[2]*xi[0]) +30.0*xi[1]*xi[1]*xi[2]*xi[0]*(lamb[0]);
449  psi1(1,1,2) = 3.0*b[1]*xi[1]*xi[1]*xi[0]*(xi[2]-xi[0])+ 3.0*b[1]*xi[1]*xi[1]*xi[2]*xi[0] + xi[1]*xi[1]*xi[1]*(b[0])*(xi[1] + 4.0*xi[2] + 4.0*xi[0])+ xi[1]*xi[1]*xi[1]*(b[0]*xi[2] -b[2]*xi[0])*(4.0) + 15.0*xi[1]*xi[1]*xi[0]*(b[0]*lamb[0]*xi[2] - b[2]*lamb_p[2]*xi[0]) + 15*xi[1]*xi[1]*xi[2]*xi[0]*(b[0]*lamb[0]);
450  psi1(1,2,2) = -3.0*c[1]*xi[1]*xi[1]*xi[2]*xi[0] + -3.0*c[1]*xi[1]*xi[1]*xi[0]*(xi[2]-xi[0]) - xi[1]*xi[1]*xi[1]*(c[0]*xi[2] - c[2]*xi[0])*(4.0) - xi[1]*xi[1]*xi[1]*(c[0])*(xi[1] + 4.0*xi[2] + 4.0*xi[0]) -15.0*xi[1]*xi[1]*xi[2]*xi[0]*(c[0]*lamb[0]) - 15.0*xi[1]*xi[1]*xi[0]*(c[0]*lamb[0]*xi[2] -c[2]*lamb_p[2]*xi[0]);
451  psi1(1,3,2) = 1.0/2.0*xi[1]*xi[1]*xi[1]*(b[0]*b[0]*2.0*xi[2]) + xi[1]*xi[1]*xi[2]*xi[0]*(b[0]*b[1]) + xi[1]*xi[1]*xi[0]*(-b[2]*b[0]*xi[1] + b[0]*b[1]*xi[2] + b[1]*b[2]*xi[0]) + 5.0/2.0*xi[1]*xi[1]*xi[2]*xi[0]*(b[0]*b[0]*lamb[0]) + 5.0/2.0*xi[1]*xi[1]*xi[0]*(b[0]*b[0]*lamb[0]*xi[2] + b[2]*b[2]*lamb_p[2]*xi[0]);
452  psi1(1,4,2) = 1.0/2.0*xi[1]*xi[1]*xi[1]*(c[0]*c[0]*2.0*xi[2]) + xi[1]*xi[1]*xi[2]*xi[0]*(c[0]*c[1]) + xi[1]*xi[1]*xi[0]*(-c[2]*c[0]*xi[1] + c[0]*c[1]*xi[2] + c[1]*c[2]*xi[0])+ 5.0/2.0*xi[1]*xi[1]*xi[2]*xi[0]*(c[0]*c[0]*lamb[0]) + 5.0/2.0*xi[1]*xi[1]*xi[0]*(c[0]*c[0]*lamb[0]*xi[2] + c[2]*c[2]*lamb_p[2]*xi[0]);
453  psi1(1,5,2) = b[1]*c[1]*xi[1]*xi[1]*xi[2]*xi[0] + b[1]*c[1]*xi[1]*xi[1]*xi[0]*(xi[1] + xi[2] + xi[0]) + b[2]*c[2]*xi[1]*xi[1]*xi[0]*(xi[0] - xi[1] - 2.0*xi[2])
454  + b[0]*c[0]*xi[1]*xi[1]*xi[2]*(xi[0] -xi[1]) + b[0]*c[0]*xi[1]*xi[1]*(xi[2]*xi[0] - xi[0]*xi[1] -xi[1]*xi[2] - xi[0]*xi[0]) - 5.0*xi[1]*xi[1]*xi[2]*xi[0]*( b[0]*c[0]*lamb[0]) - 5.0*xi[1]*xi[1]*xi[0]*(b[2]*c[2]*lamb_p[2]*xi[0] + b[0]*c[0]*lamb[0]*xi[2]);
455 
456  // wrt area coordinate0
457  psi1(1,0,0) = 5.0*xi[1]*xi[1]*xi[1]*xi[1] + 10.0*xi[1]*xi[1]*xi[1]*2.0*(xi[2]+xi[0]) + 30.0*xi[1]*xi[1]*xi[2]*xi[0]*(lamb_p[2])+ 30.0*xi[1]*xi[1]*xi[2]*(lamb[0]*xi[2] + lamb_p[2]*xi[0]);
458  psi1(1,1,0) = -3.0*b[1]*xi[1]*xi[1]*xi[2]*xi[0] + 3.0*b[1]*xi[1]*xi[1]*xi[2]*(xi[2]-xi[0]) + xi[1]*xi[1]*xi[1]*(b[0]*xi[2] -b[2]*xi[0])*(4.0) + xi[1]*xi[1]*xi[1]*(-b[2])*(xi[1] + 4.0*xi[2] + 4.0*xi[0]) - 15*xi[1]*xi[1]*xi[2]*xi[0]*(b[2]*lamb_p[2]) + 15*xi[1]*xi[1]*xi[2]*(b[0]*lamb[0]*xi[2] - b[2]*lamb_p[2]*xi[0]);
459  psi1(1,2,0) = 3.0*c[1]*xi[1]*xi[1]*xi[2]*xi[0] - 3.0*c[1]*xi[1]*xi[1]*xi[2]*(xi[2]-xi[0]) - xi[1]*xi[1]*xi[1]*(c[0]*xi[2] -c[2]*xi[0])*(4.0) - xi[1]*xi[1]*xi[1]*(-c[2])*(xi[1] + 4.0*xi[2] + 4.0*xi[0]) + 15.0*xi[1]*xi[1]*xi[2]*xi[0]*(c[2]*lamb_p[2]) -15.0*xi[1]*xi[1]*xi[2]*(c[0]*lamb[0]*xi[2] -c[2]*lamb_p[2]*xi[0]);
460  psi1(1,3,0) = 1.0/2.0*xi[1]*xi[1]*xi[1]*(b[2]*b[2]*2.0*xi[0]) + xi[1]*xi[1]*xi[2]*xi[0]*(b[1]*b[2]) + xi[1]*xi[1]*xi[2]*(-b[2]*b[0]*xi[1] + b[0]*b[1]*xi[2] + b[1]*b[2]*xi[0]) + 5.0/2.0*xi[1]*xi[1]*xi[2]*xi[0]*( b[2]*b[2]*lamb_p[2])+ 5.0/2.0*xi[1]*xi[1]*xi[2]*(b[0]*b[0]*lamb[0]*xi[2] + b[2]*b[2]*lamb_p[2]*xi[0]);
461  psi1(1,4,0) = 1.0/2.0*xi[1]*xi[1]*xi[1]*(c[2]*c[2]*2.0*xi[0]) + xi[1]*xi[1]*xi[2]*xi[0]*(c[1]*c[2]) + xi[1]*xi[1]*xi[2]*(-c[2]*c[0]*xi[1] + c[0]*c[1]*xi[2] + c[1]*c[2]*xi[0]) + 5.0/2.0*xi[1]*xi[1]*xi[2]*xi[0]*(c[2]*c[2]*lamb_p[2]) + 5.0/2.0*xi[1]*xi[1]*xi[2]*(c[0]*c[0]*lamb[0]*xi[2] + c[2]*c[2]*lamb_p[2]*xi[0]);
462  psi1(1,5,0) = b[1]*c[1]*xi[1]*xi[1]*xi[2]*xi[0] + b[1]*c[1]*xi[1]*xi[1]*xi[2]*(xi[1] + xi[2] + xi[0]) + b[2]*c[2]*xi[1]*xi[1]*xi[0]*(xi[2] - xi[1]) + b[2]*c[2]*xi[1]*xi[1]*(xi[2]*xi[0] - xi[0]*xi[1] - xi[1]*xi[2] - xi[2]*xi[2]) + b[0]*c[0]*xi[1]*xi[1]*xi[2]*(xi[2] - xi[1] - 2.0*xi[0]) - 5.0*xi[1]*xi[1]*xi[2]*xi[0]*(b[2]*c[2]*lamb_p[2]) - 5.0*xi[1]*xi[1]*xi[2]*(b[2]*c[2]*lamb_p[2]*xi[0] + b[0]*c[0]*lamb[0]*xi[2]);
463  //--------------------------------------------------------------------------------------
464  // by chain rule, we can obtain dshape wrt s0 at node1
465  dpsids(1,0,0) = psi1(1,0,0)*dxids0[0] + psi1(1,0,1)*dxids0[1] + psi1(1,0,2)*dxids0[2];
466  dpsids(1,1,0) = psi1(1,1,0)*dxids0[0] + psi1(1,1,1)*dxids0[1] + psi1(1,1,2)*dxids0[2];
467  dpsids(1,2,0) = psi1(1,2,0)*dxids0[0] + psi1(1,2,1)*dxids0[1] + psi1(1,2,2)*dxids0[2];
468  dpsids(1,3,0) = psi1(1,3,0)*dxids0[0] + psi1(1,3,1)*dxids0[1] + psi1(1,3,2)*dxids0[2];
469  dpsids(1,4,0) = psi1(1,4,0)*dxids0[0] + psi1(1,4,1)*dxids0[1] + psi1(1,4,2)*dxids0[2];
470  dpsids(1,5,0) = psi1(1,5,0)*dxids0[0] + psi1(1,5,1)*dxids0[1] + psi1(1,5,2)*dxids0[2];
471 
472  // by chain rule, we can obtain dshape wrt s1 at node1
473  dpsids(1,0,1) = psi1(1,0,0)*dxids1[0] + psi1(1,0,1)*dxids1[1] + psi1(1,0,2)*dxids1[2];
474  dpsids(1,1,1) = psi1(1,1,0)*dxids1[0] + psi1(1,1,1)*dxids1[1] + psi1(1,1,2)*dxids1[2];
475  dpsids(1,2,1) = psi1(1,2,0)*dxids1[0] + psi1(1,2,1)*dxids1[1] + psi1(1,2,2)*dxids1[2];
476  dpsids(1,3,1) = psi1(1,3,0)*dxids1[0] + psi1(1,3,1)*dxids1[1] + psi1(1,3,2)*dxids1[2];
477  dpsids(1,4,1) = psi1(1,4,0)*dxids1[0] + psi1(1,4,1)*dxids1[1] + psi1(1,4,2)*dxids1[2];
478  dpsids(1,5,1) = psi1(1,5,0)*dxids1[0] + psi1(1,5,1)*dxids1[1] + psi1(1,5,2)*dxids1[2];
479  //-------------------------------------------------------------------------------------
480  // define shape functions that associated to dofs at node 2
481  // wrt area coordinate0
482  psi1(2,0,0) = 5.0*xi[2]*xi[2]*xi[2]*xi[2] + 10.0*xi[2]*xi[2]*xi[2]*2.0*(xi[0]+xi[1]) + 30.0*xi[2]*xi[2]*xi[1]*(lamb[1]*xi[0] + lamb_p[0]*xi[1])
483  +30.0*xi[2]*xi[2]*xi[0]*xi[1]*(lamb[1]);
484  psi1(2,1,0)= 3.0*b[2]*xi[2]*xi[2]*xi[1]*(xi[0]-xi[1]) + 3.0*b[2]*xi[2]*xi[2]*xi[0]*xi[1] + xi[2]*xi[2]*xi[2]*(b[1])*(xi[2] + 4.0*xi[0] + 4.0*xi[1])+ xi[2]*xi[2]*xi[2]*(b[1]*xi[0] -b[0]*xi[1])*(4.0) + 15.0*xi[2]*xi[2]*xi[1]*(b[1]*lamb[1]*xi[0] - b[0]*lamb_p[0]*xi[1]) + 15.0*xi[2]*xi[2]*xi[0]*xi[1]*(b[1]*lamb[1]);
485  psi1(2,2,0) = -3.0*c[2]*xi[2]*xi[2]*xi[0]*xi[1] + -3.0*c[2]*xi[2]*xi[2]*xi[1]*(xi[0]-xi[1]) - xi[2]*xi[2]*xi[2]*(c[1]*xi[0] - c[0]*xi[1])*(4.0) - xi[2]*xi[2]*xi[2]*(c[1])*(xi[2] + 4.0*xi[0] + 4.0*xi[1]) -15.0*xi[2]*xi[2]*xi[0]*xi[1]*(c[1]*lamb[1])
486  -15.0*xi[2]*xi[2]*xi[1]*(c[1]*lamb[1]*xi[0] -c[0]*lamb_p[0]*xi[1]);
487  psi1(2,3,0) = 1.0/2.0*xi[2]*xi[2]*xi[2]*(b[1]*b[1]*2.0*xi[0]) + xi[2]*xi[2]*xi[0]*xi[1]*(b[1]*b[2]) + xi[2]*xi[2]*xi[1]*(-b[0]*b[1]*xi[2] + b[1]*b[2]*xi[0] + b[2]*b[0]*xi[1]) + 5.0/2.0*xi[2]*xi[2]*xi[0]*xi[1]*(b[1]*b[1]*lamb[1]) + 5.0/2.0*xi[2]*xi[2]*xi[1]*(b[1]*b[1]*lamb[1]*xi[0] + b[0]*b[0]*lamb_p[0]*xi[1]);
488  psi1(2,4,0) = 1.0/2.0*xi[2]*xi[2]*xi[2]*(c[1]*c[1]*2.0*xi[0]) + xi[2]*xi[2]*xi[0]*xi[1]*( c[1]*c[2]) + xi[2]*xi[2]*xi[1]*(-c[0]*c[1]*xi[2] + c[1]*c[2]*xi[0] + c[2]*c[0]*xi[1])+ 5.0/2.0*xi[2]*xi[2]*xi[0]*xi[1]*(c[1]*c[1]*lamb[1]) + 5.0/2.0*xi[2]*xi[2]*xi[1]*(c[1]*c[1]*lamb[1]*xi[0] + c[0]*c[0]*lamb_p[0]*xi[1]);
489  psi1(2,5,0) = b[2]*c[2]*xi[2]*xi[2]*xi[0]*xi[1] + b[2]*c[2]*xi[2]*xi[2]*xi[1]*(xi[2] + xi[0] + xi[1]) + b[0]*c[0]*xi[2]*xi[2]*xi[1]*(xi[1] - xi[2] - 2.0*xi[0])
490  + b[1]*c[1]*xi[2]*xi[2]*xi[0]*(xi[1] -xi[2]) + b[1]*c[1]*xi[2]*xi[2]*(xi[0]*xi[1] - xi[1]*xi[2] -xi[2]*xi[0] - xi[1]*xi[1]) - 5.0*xi[2]*xi[2]*xi[0]*xi[1]*( b[1]*c[1]*lamb[1]) - 5.0*xi[2]*xi[2]*xi[1]*(b[0]*c[0]*lamb_p[0]*xi[1] + b[1]*c[1]*lamb[1]*xi[0]);
491 
492  // wrt area coordinate1
493  psi1(2,0,1) = 5.0*xi[2]*xi[2]*xi[2]*xi[2] + 10.0*xi[2]*xi[2]*xi[2]*2.0*(xi[0]+xi[1]) +30.0*xi[2]*xi[2]*xi[0]*xi[1]*(lamb_p[0]) +30.0*xi[2]*xi[2]*xi[0]*(lamb[1]*xi[0] + lamb_p[0]*xi[1]);
494  psi1(2,1,1) = 3.0*b[2]*xi[2]*xi[2]*xi[0]*xi[1]*(-1.0) + 3.0*b[2]*xi[2]*xi[2]*xi[0]*(xi[0]-xi[1])+ xi[2]*xi[2]*xi[2]*(-b[0])*(xi[2] + 4.0*xi[0] + 4.0*xi[1])+ xi[2]*xi[2]*xi[2]*(b[1]*xi[0] -b[0]*xi[1])*(4.0)+ 15*xi[2]*xi[2]*xi[0]*(b[1]*lamb[1]*xi[0] - b[0]*lamb_p[0]*xi[1]) + 15.0*xi[2]*xi[2]*xi[0]*xi[1]*(-b[0]*lamb_p[0]);
495  psi1(2,2,1) = -3.0*c[2]*xi[2]*xi[2]*xi[0]*xi[1]*(-1.0) + -3.0*c[2]*xi[2]*xi[2]*xi[0]*(xi[0]-xi[1]) - xi[2]*xi[2]*xi[2]*(c[1]*xi[0] - c[0]*xi[1])*(4.0) - xi[2]*xi[2]*xi[2]*(-1.0*c[0])*(xi[2] + 4.0*xi[0] + 4.0*xi[1]) -15.0*xi[2]*xi[2]*xi[0]*xi[1]*( -1.0*c[0]*lamb_p[0]) -15.0*xi[2]*xi[2]*xi[0]*(c[1]*lamb[1]*xi[0] -c[0]*lamb_p[0]*xi[1]);
496  psi1(2,3,1) = 1.0/2.0*xi[2]*xi[2]*xi[2]*(b[0]*b[0]*2.0*xi[1]) + xi[2]*xi[2]*xi[0]*xi[1]*( b[2]*b[0]) + xi[2]*xi[2]*xi[0]*(-b[0]*b[1]*xi[2] + b[1]*b[2]*xi[0] + b[2]*b[0]*xi[1]) + 5.0/2.0*xi[2]*xi[2]*xi[0]*xi[1]*( b[0]*b[0]*lamb_p[0])+ 5.0/2.0*xi[2]*xi[2]*xi[0]*(b[1]*b[1]*lamb[1]*xi[0] + b[0]*b[0]*lamb_p[0]*xi[1]);
497  psi1(2,4,1) = 1.0/2.0*xi[2]*xi[2]*xi[2]*(c[0]*c[0]*2.0*xi[1]) + xi[2]*xi[2]*xi[0]*xi[1]*(c[2]*c[0]) + xi[2]*xi[2]*xi[0]*(-c[0]*c[1]*xi[2] + c[1]*c[2]*xi[0] + c[2]*c[0]*xi[1]) + 5.0/2.0*xi[2]*xi[2]*xi[0]*xi[1]*(c[0]*c[0]*lamb_p[0]) + 5.0/2.0*xi[2]*xi[2]*xi[0]*(c[1]*c[1]*lamb[1]*xi[0] + c[0]*c[0]*lamb_p[0]*xi[1]);
498  psi1(2,5,1) = b[2]*c[2]*xi[2]*xi[2]*xi[0]*xi[1] + b[2]*c[2]*xi[2]*xi[2]*xi[0]*(xi[2] + xi[0] + xi[1]) + b[0]*c[0]*xi[2]*xi[2]*xi[1]*(xi[0] - xi[2]) + b[0]*c[0]*xi[2]*xi[2]*(xi[0]*xi[1] - xi[1]*xi[2] - xi[2]*xi[0] - xi[0]*xi[0]) + b[1]*c[1]*xi[2]*xi[2]*xi[0]*(xi[0] - xi[2] - 2.0*xi[1]) - 5.0*xi[2]*xi[2]*xi[0]*xi[1]*(b[0]*c[0]*lamb_p[0]) - 5.0*xi[2]*xi[2]*xi[0]*(b[0]*c[0]*lamb_p[0]*xi[1] + b[1]*c[1]*lamb[1]*xi[0]);
499 
500  // wrt area coordinate2
501  psi1(2,0,2) = 5.0*xi[2]*xi[2]*xi[2]*xi[2] +5.0*4.0*xi[2]*xi[2]*xi[2]*(xi[0]+xi[1]) + 10.0*3.0*xi[2]*xi[2]*(xi[0]+xi[1])*(xi[0]+xi[1])
502  +30.0*2.0*xi[2]*xi[0]*xi[1]*(lamb[1]*xi[0] + lamb_p[0]*xi[1]);
503  psi1(2,1,2) = 3.0*b[2]*2.0*xi[2]*xi[0]*xi[1]*(xi[0]-xi[1]) + 3.0*xi[2]*xi[2]*(b[1]*xi[0] -b[0]*xi[1])*(xi[2] + 4.0*xi[0] + 4.0*xi[1]) + xi[2]*xi[2]*xi[2]*(b[1]*xi[0] -b[0]*xi[1]) + 15*2.0*xi[2]*xi[0]*xi[1]*(b[1]*lamb[1]*xi[0] - b[0]*lamb_p[0]*xi[1]);
504  psi1(2,2,2) = -3.0*c[2]*2.0*xi[2]*xi[0]*xi[1]*(xi[0]-xi[1]) - 3.0*xi[2]*xi[2]*(c[1]*xi[0] -c[0]*xi[1])*(xi[2] + 4.0*xi[0] + 4.0*xi[1]) - xi[2]*xi[2]*xi[2]*(c[1]*xi[0] -c[0]*xi[1]) -15.0*2.0*xi[2]*xi[0]*xi[1]*(c[1]*lamb[1]*xi[0] -c[0]*lamb_p[0]*xi[1]);
505  psi1(2,3,2) = 1.0/2.0*3.0*xi[2]*xi[2]*(b[1]*b[1]*xi[0]*xi[0] + b[0]*b[0]*xi[1]*xi[1]) + 2.0*xi[2]*xi[0]*xi[1]*(-b[0]*b[1]*xi[2] + b[1]*b[2]*xi[0] + b[2]*b[0]*xi[1])
506  + 5.0/2.0*2.0*xi[2]*xi[0]*xi[1]*(b[1]*b[1]*lamb[1]*xi[0] + b[0]*b[0]*lamb_p[0]*xi[1]) + xi[2]*xi[2]*xi[0]*xi[1]*(-b[0])*b[1];
507  psi1(2,4,2) = 1.0/2.0*3.0*xi[2]*xi[2]*(c[1]*c[1]*xi[0]*xi[0] + c[0]*c[0]*xi[1]*xi[1]) + 2.0*xi[2]*xi[0]*xi[1]*(-c[0]*c[1]*xi[2] + c[1]*c[2]*xi[0] + c[2]*c[0]*xi[1])
508  + 5.0/2.0*2.0*xi[2]*xi[0]*xi[1]*(c[1]*c[1]*lamb[1]*xi[0] + c[0]*c[0]*lamb_p[0]*xi[1])+ xi[2]*xi[2]*xi[0]*xi[1]*(-c[0]*c[1]);
509  psi1(2,5,2) = b[2]*c[2]*2.0*xi[2]*xi[0]*xi[1]*(xi[2] + xi[0] + xi[1]) + b[2]*c[2]*xi[2]*xi[2]*xi[0]*xi[1] + b[0]*c[0]*2.0*xi[2]*xi[1]*(xi[0]*xi[1] - xi[1]*xi[2] - xi[2]*xi[0] - xi[0]*xi[0]) + b[0]*c[0]*xi[2]*xi[2]*xi[1]*(-xi[0] - xi[1]) + b[1]*c[1]*2.0*xi[2]*xi[0]*(xi[0]*xi[1] - xi[1]*xi[2] -xi[2]*xi[0] - xi[1]*xi[1]) + b[1]*c[1]*xi[2]*xi[2]*xi[0]*(- xi[1]-xi[0]) - 5.0*2.0*xi[2]*xi[0]*xi[1]*(b[0]*c[0]*lamb_p[0]*xi[1] + b[1]*c[1]*lamb[1]*xi[0]);
510 
511  // by chain rule, we can obtain dshape wrt s0 at node2
512  dpsids(2,0,0) = psi1(2,0,0)*dxids0[0] + psi1(2,0,1)*dxids0[1] + psi1(2,0,2)*dxids0[2];
513  dpsids(2,1,0) = psi1(2,1,0)*dxids0[0] + psi1(2,1,1)*dxids0[1] + psi1(2,1,2)*dxids0[2];
514  dpsids(2,2,0) = psi1(2,2,0)*dxids0[0] + psi1(2,2,1)*dxids0[1] + psi1(2,2,2)*dxids0[2];
515  dpsids(2,3,0) = psi1(2,3,0)*dxids0[0] + psi1(2,3,1)*dxids0[1] + psi1(2,3,2)*dxids0[2];
516  dpsids(2,4,0) = psi1(2,4,0)*dxids0[0] + psi1(2,4,1)*dxids0[1] + psi1(2,4,2)*dxids0[2];
517  dpsids(2,5,0) = psi1(2,5,0)*dxids0[0] + psi1(2,5,1)*dxids0[1] + psi1(2,5,2)*dxids0[2];
518 
519  // by chain rule, we can obtain dshape wrt s1 at node2
520  dpsids(2,0,1) = psi1(2,0,0)*dxids1[0] + psi1(2,0,1)*dxids1[1] + psi1(2,0,2)*dxids1[2];
521  dpsids(2,1,1) = psi1(2,1,0)*dxids1[0] + psi1(2,1,1)*dxids1[1] + psi1(2,1,2)*dxids1[2];
522  dpsids(2,2,1) = psi1(2,2,0)*dxids1[0] + psi1(2,2,1)*dxids1[1] + psi1(2,2,2)*dxids1[2];
523  dpsids(2,3,1) = psi1(2,3,0)*dxids1[0] + psi1(2,3,1)*dxids1[1] + psi1(2,3,2)*dxids1[2];
524  dpsids(2,4,1) = psi1(2,4,0)*dxids1[0] + psi1(2,4,1)*dxids1[1] + psi1(2,4,2)*dxids1[2];
525  dpsids(2,5,1) = psi1(2,5,0)*dxids1[0] + psi1(2,5,1)*dxids1[1] + psi1(2,5,2)*dxids1[2];
526  }
527 
528  void d2Bshape_local(const Vector<double> &s, Shape &psi, DShape &dpsids, DShape &d2psids, DenseMatrix<double> &position) const
529  {
530  // assign for dshape functions
531  dBshape_local(s,psi,dpsids,position);
532  //---------------------------------------------
533  // the mapping to physical coordinates
534  //----------------------------------------------
535  Vector<double> phi(2);
536  phi[0] = position(2,0) + (position(0,0) - position(2,0))*s[0] + (position(1,0) - position(2,0))*s[1];
537  phi[1] = position(2,1) + (position(0,1) - position(2,1))*s[0] + (position(1,1) - position(2,1))*s[1];
538 
539  double A = ( (position(1,0)*position(2,1)-position(2,0)*position(1,1)) - (position(0,0)*position(2,1)-position(2,0)*position(0,1)) + (position(0,0)*position(1,1)-position(1,0)*position(0,1)))/2.0;
540  double A0, A1, A2;
541  A0 = ( (position(1,0)*position(2,1)-position(2,0)*position(1,1)) - (phi[0]*position(2,1)-position(2,0)*phi[1]) + (phi[0]*position(1,1)-position(1,0)*phi[1]))/2.0;
542  A1 = ( (phi[0]*position(2,1)-position(2,0)*phi[1]) - (position(0,0)*position(2,1)-position(2,0)*position(0,1)) + (position(0,0)*phi[1]-phi[0]*position(0,1)))/2.0;
543  A2 = ( (position(1,0)*phi[1]-phi[0]*position(1,1)) - (position(0,0)*phi[1]-phi[0]*position(0,1)) + (position(0,0)*position(1,1)-position(1,0)*position(0,1)))/2.0;
544 
545  // assigned area coordinates
546  Vector<double> xi(3);
547  xi[0] = A0/A;
548  xi[1] = A1/A;
549  xi[2] = A2/A;
550 
551  Vector<double> b(3);
552  Vector<double> c(3);
553  Vector<double> lamb(3);
554  Vector<double> lamb_p(3);
555  Vector<double> pp(2);
556  Vector<double> a(2),cc(2);
557 
558  //compute for b and c
559  b[1] = position(0,0)-position(2,0);
560  b[2] = position(1,0)-position(0,0);
561  b[0] = position(2,0)-position(1,0);
562 
563  c[1] = position(2,1)-position(0,1);
564  c[2] = position(0,1)-position(1,1);
565  c[0] = position(1,1)-position(2,1);
566 
567  //compute for a point of perpendicular
568  // on the edge opposite to node0 (top vertex)
569  Vector<double> v(2);
570  v[0] = (position(2,0)-position(1,0));
571  v[1] = (position(2,1)-position(1,1));
572  double m = v[1]/v[0];
573  a[0] = position(1,0);
574  a[1] = position(1,1);
575  cc[0] = position(0,0);
576  cc[1] = position(0,1);
577  if(v[0]==0)
578  {
579  m = v[0]/v[1];
580  pp[1] = ( v[0]*m*a[1] + v[1]*cc[1] - v[0]*a[0] + v[0]*cc[0] )/((v[0]*m)+v[1]);
581  pp[0] = (pp[1]-a[1])*m + a[0];
582  }
583  else
584  {
585  pp[0] = (v[1]*m*a[0] + v[1]*cc[1] - v[1]*a[1] + v[0]*cc[0])/(v[1]*m+v[0]);
586  pp[1] = m*(pp[0]-a[0]) + a[1];
587  }
588  double l = sqrt(v[0]*v[0] + v[1]*v[1]);
589  double l1 = sqrt( (pp[0]-a[0])*(pp[0]-a[0]) + (pp[1]-a[1])*(pp[1]-a[1]));
590  lamb_p[0] = l1/l;
591  lamb[0] = 1-lamb_p[0];
592 
593  // on the edge opposite to node1
594  v[0] = (position(0,0)-position(2,0));
595  v[1] = (position(0,1)-position(2,1));
596  m = v[1]/v[0];
597  a[0] = position(2,0);
598  a[1] = position(2,1);
599  cc[0] = position(1,0);
600  cc[1] = position(1,1);
601  if(v[0]==0)
602  {
603  m = v[0]/v[1];
604  pp[1] = ( v[0]*m*a[1] + v[1]*cc[1] - v[0]*a[0] + v[0]*cc[0] )/((v[0]*m)+v[1]);
605  pp[0] = (pp[1]-a[1])*m + a[0];
606  }
607  else
608  {
609  pp[0] = (v[1]*m*a[0] + v[1]*cc[1] - v[1]*a[1] + v[0]*cc[0])/(v[1]*m+v[0]);
610  pp[1] = m*(pp[0]-a[0]) + a[1];
611  }
612  l = sqrt(v[0]*v[0] + v[1]*v[1]);
613  l1 = sqrt( (pp[0]-a[0])*(pp[0]-a[0]) + (pp[1]-a[1])*(pp[1]-a[1]));
614  lamb_p[1] = l1/l;
615  lamb[1] = 1-lamb_p[1];
616 
617  // on the edge opposite to node2 (right bottom)
618  v[0] = (position(1,0)-position(0,0));
619  v[1] = (position(1,1)-position(0,1));
620  m = v[1]/v[0];
621  a[0] = position(0,0);
622  a[1] = position(0,1);
623  cc[0] = position(2,0);
624  cc[1] = position(2,1);
625  if(v[0]==0)
626  {
627  m = v[0]/v[1];
628  pp[1] = ( v[0]*m*a[1] + v[1]*cc[1] - v[0]*a[0] + v[0]*cc[0] )/((v[0]*m)+v[1]);
629  pp[0] = (pp[1]-a[1])*m + a[0];
630  }
631  else
632  {
633  pp[0] = (v[1]*m*a[0] + v[1]*cc[1] - v[1]*a[1] + v[0]*cc[0])/(v[1]*m+v[0]);
634  pp[1] = m*(pp[0]-a[0]) + a[1];
635  }
636  l = sqrt(v[0]*v[0] + v[1]*v[1]);
637  l1 = sqrt( (pp[0]-a[0])*(pp[0]-a[0]) + (pp[1]-a[1])*(pp[1]-a[1]));
638  lamb_p[2] = l1/l;
639  lamb[2] = 1-lamb_p[2];
640 
641  Vector<double> dxids0(3,0.0);
642  Vector<double> dxids1(3,0.0);
643 
644  dxids0[0] = c[0]/A/2.0;
645  dxids0[1] = c[1]/A/2.0;
646  dxids0[2] = c[2]/A/2.0;
647 
648  dxids1[0] = b[0]/A/2.0;
649  dxids1[1] = b[1]/A/2.0;
650  dxids1[2] = b[2]/A/2.0;
651 
652  //------------------------------------------------------------------
653  DShape psi2(3,6,6);
654 
655  //------------------------------------------------------------------------------------
656  // compute for all second derivatives at node 0
657  //------------------------------------------------------------------------------------
658  // compute for the second derivatives wrt area coordinate0
659  psi2(0,0,0) = 5.0*4.0*xi[0]*xi[0]*xi[0] +5.0*4.0*3.0*xi[0]*xi[0]*(xi[1]+xi[2]) + 10.0*3.0*2.0*xi[0]*(xi[1]+xi[2])*(xi[1]+xi[2]) +30.0*2.0*xi[1]*xi[2]*(lamb[2]*xi[1] + lamb_p[1]*xi[2]);
660  psi2(0,1,0) = 3.0*b[0]*2.0*xi[1]*xi[2]*(xi[1]-xi[2]) + 3.0*2.0*xi[0]*(b[2]*xi[1] -b[1]*xi[2])*(xi[0] + 4.0*xi[1] + 4.0*xi[2]) + 6.0*xi[0]*xi[0]*(b[2]*xi[1] -b[1]*xi[2]) + 15*2.0*xi[1]*xi[2]*(b[2]*lamb[2]*xi[1] - b[1]*lamb_p[1]*xi[2]);
661  psi2(0,2,0) = -6.0*c[0]*xi[1]*xi[2]*(xi[1]-xi[2]) - 3.0*2.0*xi[0]*(c[2]*xi[1] -c[1]*xi[2])*(xi[0] + 4.0*xi[1] + 4.0*xi[2]) - 6.0*xi[0]*xi[0]*(c[2]*xi[1] -c[1]*xi[2]) -15.0*2.0*xi[1]*xi[2]*(c[2]*lamb[2]*xi[1] -c[1]*lamb_p[1]*xi[2]);
662  psi2(0,3,0) = 3.0*xi[0]*(b[2]*b[2]*xi[1]*xi[1] + b[1]*b[1]*xi[2]*xi[2]) + 2.0*xi[1]*xi[2]*(-b[1]*b[2]*xi[0] + b[2]*b[0]*xi[1] + b[0]*b[1]*xi[2]) - 4.0*xi[0]*xi[1]*xi[2]*(b[1]*b[2])
663  + 5.0*xi[1]*xi[2]*(b[2]*b[2]*lamb[2]*xi[1] + b[1]*b[1]*lamb_p[1]*xi[2]);
664  psi2(0,4,0) = 3.0*xi[0]*(c[2]*c[2]*xi[1]*xi[1] + c[1]*c[1]*xi[2]*xi[2]) + 2.0*xi[1]*xi[2]*(-c[1]*c[2]*xi[0] + c[2]*c[0]*xi[1] + c[0]*c[1]*xi[2]) - 4.0*xi[0]*xi[1]*xi[2]*(c[1]*c[2]) + 5.0*xi[1]*xi[2]*(c[2]*c[2]*lamb[2]*xi[1] + c[1]*c[1]*lamb_p[1]*xi[2]);
665  psi2(0,5,0) = b[0]*c[0]*2.0*xi[1]*xi[2]*(xi[0] + xi[1] + xi[2]) + b[0]*c[0]*2.0*xi[0]*xi[1]*xi[2] + b[0]*c[0]*2.0*xi[0]*xi[1]*xi[2] + b[1]*c[1]*2.0*xi[2]*(xi[1]*xi[2] - xi[2]*xi[0] - xi[0]*xi[1] - xi[1]*xi[1]) - b[1]*c[1]*4.0*xi[0]*xi[2]*(xi[2] +xi[1]) + b[2]*c[2]*2.0*xi[1]*(xi[1]*xi[2] - xi[2]*xi[0] -xi[0]*xi[1] - xi[2]*xi[2]) - b[2]*c[2]*4.0*xi[0]*xi[1]*(xi[2]+xi[1]) - 5.0*2.0*xi[1]*xi[2]*(b[1]*c[1]*lamb_p[1]*xi[2] + b[2]*c[2]*lamb[2]*xi[1]);
666 
667  // compute for the second derivative wrt area coordinate1
668  psi2(0,0,1) = 10.0*xi[0]*xi[0]*xi[0]*2.0 + 30.0*xi[0]*xi[0]*xi[2]*(lamb[2]) + 30.0*xi[0]*xi[0]*xi[2]*(lamb[2]);
669  psi2(0,1,1) = 3.0*b[0]*xi[0]*xi[0]*xi[2] + 3.0*b[0]*xi[0]*xi[0]*xi[2] + xi[0]*xi[0]*xi[0]*(b[2])*(4.0) + xi[0]*xi[0]*xi[0]*(b[2])*(4.0) + 15*xi[0]*xi[0]*xi[2]*(b[2]*lamb[2]) + 15*xi[0]*xi[0]*xi[2]*(b[2]*lamb[2]);
670  psi2(0,2,1) = -6.0*c[0]*xi[0]*xi[0]*xi[2] - 8.0*xi[0]*xi[0]*xi[0]*(c[2]) - 30.0*xi[0]*xi[0]*xi[2]*(c[2]*lamb[2]);
671  psi2(0,3,1) = xi[0]*xi[0]*xi[0]*(b[2]*b[2]) + 2.0*xi[0]*xi[0]*xi[2]*(b[2]*b[0]) + 5.0*xi[0]*xi[0]*xi[2]*(b[2]*b[2]*lamb[2]);
672  psi2(0,4,1) = xi[0]*xi[0]*xi[0]*(c[2]*c[2]) + 2.0*xi[0]*xi[0]*xi[2]*(c[2]*c[0]) + 5.0*xi[0]*xi[0]*xi[2]*(c[2]*c[2]*lamb[2]);
673  psi2(0,5,1) = b[0]*c[0]*xi[0]*xi[0]*xi[2] + b[0]*c[0]*xi[0]*xi[0]*xi[2] - 2.0*b[1]*c[1]*xi[0]*xi[0]*xi[2] - 2.0*b[2]*c[2]*xi[0]*xi[0]*(xi[0]-xi[2])- 10.0*xi[0]*xi[0]*xi[2]*(b[2]*c[2]*lamb[2]);
674 
675  // compute for the second derivative wrt area coordinate2
676  psi2(0,0,2) = 10.0*xi[0]*xi[0]*xi[0]*2.0 + 30.0*xi[0]*xi[0]*xi[1]*(lamb_p[1]) +30.0*xi[0]*xi[0]*xi[1]*(lamb_p[1]);
677  psi2(0,1,2) = -6.0*b[0]*xi[0]*xi[0]*xi[1] - 8.0*xi[0]*xi[0]*xi[0]*(b[1]) - 30.0*xi[0]*xi[0]*xi[1]*(b[1]*lamb_p[1]);
678  psi2(0,2,2) = 6.0*c[0]*xi[0]*xi[0]*xi[1] + 8.0*xi[0]*xi[0]*xi[0]*(c[1]) + 30.0*xi[0]*xi[0]*xi[1]*(c[1]*lamb_p[1]);
679  psi2(0,3,2) = xi[0]*xi[0]*xi[0]*(b[1]*b[1]) + 2.0*xi[0]*xi[0]*xi[1]*(b[0]*b[1]) + 5.0*xi[0]*xi[0]*xi[1]*(b[1]*b[1]*lamb_p[1]);
680  psi2(0,4,2) = xi[0]*xi[0]*xi[0]*(c[1]*c[1]) + 2.0*xi[0]*xi[0]*xi[1]*(c[0]*c[1]) + 5.0*xi[0]*xi[0]*xi[1]*(c[1]*c[1]*lamb_p[1]);
681  psi2(0,5,2) = b[0]*c[0]*xi[0]*xi[0]*xi[1] + b[0]*c[0]*xi[0]*xi[0]*xi[1] + b[1]*c[1]*xi[0]*xi[0]*(xi[1] - xi[0]) + b[1]*c[1]*xi[0]*xi[0]*(xi[1]- xi[0]) + b[2]*c[2]*xi[0]*xi[0]*xi[1]*(-2.0) - 5.0*xi[0]*xi[0]*xi[1]*(b[1]*c[1]*lamb_p[1]) - 5.0*xi[0]*xi[0]*xi[1]*(b[1]*c[1]*lamb_p[1]);
682 
683  // compute for the mixed-derivative wrt area coordinate0 and 1
684  psi2(0,0,3) = 5.0*4.0*xi[0]*xi[0]*xi[0] + 10.0*3.0*xi[0]*xi[0]*2.0*(xi[1]+xi[2]) + 30.0*2.0*xi[0]*xi[2]*(lamb[2]*xi[1] + lamb_p[1]*xi[2]) + 30.0*2.0*xi[0]*xi[1]*xi[2]*(lamb[2]);
685  psi2(0,1,3) = 3.0*b[0]*2.0*xi[0]*xi[2]*(xi[1]-xi[2]) + 3.0*b[0]*2.0*xi[0]*xi[1]*xi[2] + 3.0*xi[0]*xi[0]*(b[2])*(xi[0] + 4.0*xi[1] + 4.0*xi[2])
686  + 3.0*xi[0]*xi[0]*(b[2]*xi[1] -b[1]*xi[2])*(4.0) + xi[0]*xi[0]*xi[0]*(b[2]) + 15*2.0*xi[0]*xi[2]*(b[2]*lamb[2]*xi[1] - b[1]*lamb_p[1]*xi[2]) + 15*2.0*xi[0]*xi[1]*xi[2]*(b[2]*lamb[2]);
687  psi2(0,2,3) = -3.0*c[0]*2.0*xi[0]*xi[2]*(xi[1]-xi[2]) -3.0*c[0]*2.0*xi[0]*xi[1]*xi[2] - 3.0*xi[0]*xi[0]*(c[2])*(xi[0] + 4.0*xi[1] + 4.0*xi[2]) - 3.0*xi[0]*xi[0]*(c[2]*xi[1] -c[1]*xi[2])*(4.0)
688  - xi[0]*xi[0]*xi[0]*(c[2]) -15.0*2.0*xi[0]*xi[2]*(c[2]*lamb[2]*xi[1] -c[1]*lamb_p[1]*xi[2]) -15.0*2.0*xi[0]*xi[1]*xi[2]*(c[2]*lamb[2]);
689  psi2(0,3,3) = 3.0*xi[0]*xi[0]*(b[2]*b[2]*xi[1]) + 2.0*xi[0]*xi[2]*(-b[1]*b[2]*xi[0] + b[2]*b[0]*xi[1] + b[0]*b[1]*xi[2]) + 2.0*xi[0]*xi[1]*xi[2]*(b[2]*b[0])
690  + 5.0/2.0*2.0*xi[0]*xi[2]*(b[2]*b[2]*lamb[2]*xi[1] + b[1]*b[1]*lamb_p[1]*xi[2])+ 5.0/2.0*2.0*xi[0]*xi[1]*xi[2]*(b[2]*b[2]*lamb[2]) + xi[0]*xi[0]*xi[2]*(-b[1])*b[2];
691  psi2(0,4,3) = 3.0*xi[0]*xi[0]*(c[2]*c[2]*xi[1]) + 2.0*xi[0]*xi[2]*(-c[1]*c[2]*xi[0] + c[2]*c[0]*xi[1] + c[0]*c[1]*xi[2]) + 2.0*xi[0]*xi[1]*xi[2]*(c[2]*c[0]) + 5.0*xi[0]*xi[2]*(c[2]*c[2]*lamb[2]*xi[1] + c[1]*c[1]*lamb_p[1]*xi[2]) + 5.0*xi[0]*xi[1]*xi[2]*(c[2]*c[2]*lamb[2])+ xi[0]*xi[0]*xi[2]*(-c[1])*c[2];
692  psi2(0,5,3) = b[0]*c[0]*2.0*xi[0]*xi[2]*(xi[0] + xi[1] + xi[2]) + b[0]*c[0]*2.0*xi[0]*xi[1]*xi[2] + b[0]*c[0]*xi[0]*xi[0]*xi[2] + b[1]*c[1]*2.0*xi[0]*xi[2]*(xi[2] - xi[0] - 2.0*xi[1]) + b[1]*c[1]*xi[0]*xi[0]*xi[2]*(-1.0) + b[2]*c[2]*2.0*xi[0]*(xi[1]*xi[2] - xi[2]*xi[0] -xi[0]*xi[1] - xi[2]*xi[2])+ b[2]*c[2]*2.0*xi[0]*xi[1]*(xi[2]-xi[0]) + b[2]*c[2]*xi[0]*xi[0]*(-xi[2]-xi[1]) + b[2]*c[2]*xi[0]*xi[0]*xi[1]*(-1.0) - 5.0*2.0*xi[0]*xi[2]*(b[1]*c[1]*lamb_p[1]*xi[2] + b[2]*c[2]*lamb[2]*xi[1])- 5.0*2.0*xi[0]*xi[1]*xi[2]*(b[2]*c[2]*lamb[2]);
693 
694  // compute for the mixed-derivative wrt area coordinate0 and 2
695  psi2(0,0,4) = 5.0*4.0*xi[0]*xi[0]*xi[0] + 10.0*3.0*xi[0]*xi[0]*2.0*(xi[1]+xi[2]) + 30.0*2.0*xi[0]*xi[1]*(lamb[2]*xi[1] + lamb_p[1]*xi[2]) + 30.0*2.0*xi[0]*xi[1]*xi[2]*(lamb_p[1]);
696  psi2(0,1,4) = 3.0*b[0]*2.0*xi[0]*xi[1]*(xi[1]-xi[2]) + 3.0*b[0]*2.0*xi[0]*xi[1]*xi[2]*(-1.0) - 3.0*xi[0]*xi[0]*(b[1])*(xi[0] + 4.0*xi[1] + 4.0*xi[2])
697  + 3.0*xi[0]*xi[0]*(b[2]*xi[1] -b[1]*xi[2])*(4.0) + xi[0]*xi[0]*xi[0]*(-b[1]) + 15*2.0*xi[0]*xi[1]*(b[2]*lamb[2]*xi[1] - b[1]*lamb_p[1]*xi[2])
698  - 15*2.0*xi[0]*xi[1]*xi[2]*(b[1]*lamb_p[1]);
699  psi2(0,2,4) = -3.0*c[0]*2.0*xi[0]*xi[1]*(xi[1]-xi[2]) + 3.0*c[0]*2.0*xi[0]*xi[1]*xi[2] + 3.0*xi[0]*xi[0]*(c[1])*(xi[0] + 4.0*xi[1] + 4.0*xi[2])
700  - 3.0*xi[0]*xi[0]*(c[2]*xi[1] -c[1]*xi[2])*(4.0) + xi[0]*xi[0]*xi[0]*(c[1]) - 15.0*2.0*xi[0]*xi[1]*(c[2]*lamb[2]*xi[1] -c[1]*lamb_p[1]*xi[2])
701  + 15.0*2.0*xi[0]*xi[1]*xi[2]*(c[1]*lamb_p[1]);
702  psi2(0,3,4) = 3.0*xi[0]*xi[0]*(b[1]*b[1]*xi[2]) + 2.0*xi[0]*xi[1]*(-b[1]*b[2]*xi[0] + b[2]*b[0]*xi[1] + b[0]*b[1]*xi[2])
703  + 2.0*xi[0]*xi[1]*xi[2]*(b[0]*b[1]) + 5.0/2.0*2.0*xi[0]*xi[1]*(b[2]*b[2]*lamb[2]*xi[1] + b[1]*b[1]*lamb_p[1]*xi[2]) + 5.0/2.0*2.0*xi[0]*xi[1]*xi[2]*(b[1]*b[1]*lamb_p[1]) + xi[0]*xi[0]*xi[1]*(-b[1])*b[2];
704  psi2(0,4,4) = 3.0*xi[0]*xi[0]*(c[1]*c[1]*xi[2]) + 2.0*xi[0]*xi[1]*(-c[1]*c[2]*xi[0] + c[2]*c[0]*xi[1] + c[0]*c[1]*xi[2]) + 2.0*xi[0]*xi[1]*xi[2]*(c[0]*c[1]) + 5.0*xi[0]*xi[1]*(c[2]*c[2]*lamb[2]*xi[1] + c[1]*c[1]*lamb_p[1]*xi[2]) + 5.0*xi[0]*xi[1]*xi[2]*(c[1]*c[1]*lamb_p[1]) - xi[0]*xi[0]*xi[1]*(c[1])*c[2];
705  psi2(0,5,4) = b[0]*c[0]*2.0*xi[0]*xi[1]*xi[2] + b[0]*c[0]*2.0*xi[0]*xi[1]*(xi[0] + xi[1] + xi[2]) + b[0]*c[0]*xi[0]*xi[0]*xi[1] + b[1]*c[1]*2.0*xi[0]*(xi[1]*xi[2] - xi[2]*xi[0] - xi[0]*xi[1] - xi[1]*xi[1])
706  + b[1]*c[1]*2.0*xi[0]*xi[2]*(xi[1]- xi[0]) + b[1]*c[1]*xi[0]*xi[0]*(-xi[1] - xi[2])+ b[1]*c[1]*xi[0]*xi[0]*xi[2]*(-1.0)
707  + b[2]*c[2]*2.0*xi[0]*xi[1]*(xi[1]-xi[0]- 2.0*xi[2]) + b[2]*c[2]*xi[0]*xi[0]*xi[1]*(-1.0)- 5.0*2.0*xi[0]*xi[1]*(b[1]*c[1]*lamb_p[1]*xi[2] + b[2]*c[2]*lamb[2]*xi[1]) - 5.0*2.0*xi[0]*xi[1]*xi[2]*(b[1]*c[1]*lamb_p[1]);
708 
709  // compute for the mixed-derivative wrt area coordinate1 and 2
710  psi2(0,0,5) = 10.0*xi[0]*xi[0]*xi[0]*2.0 + 30.0*xi[0]*xi[0]*(lamb[2]*xi[1] + lamb_p[1]*xi[2]) + 30.0*xi[0]*xi[0]*xi[2]*(lamb_p[1]) + 30.0*xi[0]*xi[0]*xi[1]*(lamb[2]);
711  psi2(0,1,5) = 3.0*b[0]*xi[0]*xi[0]*(xi[1]-xi[2]) - 3.0*b[0]*xi[0]*xi[0]*xi[2] + 3.0*b[0]*xi[0]*xi[0]*xi[1] + xi[0]*xi[0]*xi[0]*(-b[1])*(4.0) + xi[0]*xi[0]*xi[0]*(b[2])*(4.0)+ 15*xi[0]*xi[0]*(b[2]*lamb[2]*xi[1] - b[1]*lamb_p[1]*xi[2])+ 15*xi[0]*xi[0]*xi[2]*(-b[1]*lamb_p[1]) +15*xi[0]*xi[0]*xi[1]*(b[2]*lamb[2]);
712  psi2(0,2,5) = -3.0*c[0]*xi[0]*xi[0]*xi[1] + 3.0*c[0]*xi[0]*xi[0]*xi[2] - 3.0*c[0]*xi[0]*xi[0]*(xi[1]-xi[2]) + xi[0]*xi[0]*xi[0]*(c[1])*(4.0) - xi[0]*xi[0]*xi[0]*(c[2])*(4.0) -15.0*xi[0]*xi[0]*xi[1]*(c[2]*lamb[2])
713  + 15.0*xi[0]*xi[0]*xi[2]*(c[1]*lamb_p[1]) - 15.0*xi[0]*xi[0]*(c[2]*lamb[2]*xi[1] -c[1]*lamb_p[1]*xi[2]);
714  psi2(0,3,5) = xi[0]*xi[0]*xi[2]*(b[0]*b[1]) + xi[0]*xi[0]*(-b[1]*b[2]*xi[0] + b[2]*b[0]*xi[1] + b[0]*b[1]*xi[2]) + xi[0]*xi[0]*xi[1]*(b[2]*b[0]) + 5.0/2.0*xi[0]*xi[0]*xi[2]*(b[1]*b[1]*lamb_p[1]) + 5.0/2.0*xi[0]*xi[0]*(b[2]*b[2]*lamb[2]*xi[1] + b[1]*b[1]*lamb_p[1]*xi[2])+ 5.0/2.0*xi[0]*xi[0]*xi[1]*(b[2]*b[2]*lamb[2]);
715  psi2(0,4,5) = xi[0]*xi[0]*xi[1]*(c[2]*c[0]) + xi[0]*xi[0]*(-c[1]*c[2]*xi[0] + c[2]*c[0]*xi[1] + c[0]*c[1]*xi[2]) + xi[0]*xi[0]*xi[2]*(c[0]*c[1]) + 5.0/2.0*xi[0]*xi[0]*xi[1]*(c[2]*c[2]*lamb[2]) + 5.0/2.0*xi[0]*xi[0]*(c[2]*c[2]*lamb[2]*xi[1] + c[1]*c[1]*lamb_p[1]*xi[2]) + 5.0/2.0*xi[0]*xi[0]*xi[2]*(c[1]*c[1]*lamb_p[1]);
716  psi2(0,5,5) = b[0]*c[0]*xi[0]*xi[0]*xi[1]+ b[0]*c[0]*xi[0]*xi[0]*(xi[0] + xi[1] + xi[2]) + b[0]*c[0]*xi[0]*xi[0]*xi[2] + b[1]*c[1]*xi[0]*xi[0]*(xi[2] - xi[0] - 2.0*xi[1])
717  + b[1]*c[1]*xi[0]*xi[0]*xi[2] + b[2]*c[2]*xi[0]*xi[0]*(xi[1]-xi[0]-2.0*xi[2]) + b[2]*c[2]*xi[0]*xi[0]*xi[1] - 5.0*xi[0]*xi[0]*(b[1]*c[1]*lamb_p[1]*xi[2] + b[2]*c[2]*lamb[2]*xi[1])
718  - 5.0*xi[0]*xi[0]*xi[2]*(b[1]*c[1]*lamb_p[1]) - 5.0*xi[0]*xi[0]*xi[1]*(b[2]*c[2]*lamb[2]);
719 
720  // by chain rule, we can obtain d2shape wrt s0s0 at node0
721  d2psids(0,0,0) = (psi2(0,0,0)*dxids0[0] + psi2(0,0,3)*dxids0[1] + psi2(0,0,4)*dxids0[2])*dxids0[0] +
722  (psi2(0,0,3)*dxids0[0] + psi2(0,0,1)*dxids0[1] + psi2(0,0,5)*dxids0[2])*dxids0[1] +
723  (psi2(0,0,4)*dxids0[0] + psi2(0,0,5)*dxids0[1] + psi2(0,0,2)*dxids0[2])*dxids0[2];
724  d2psids(0,1,0) = (psi2(0,1,0)*dxids0[0] + psi2(0,1,3)*dxids0[1] + psi2(0,1,4)*dxids0[2])*dxids0[0] +
725  (psi2(0,1,3)*dxids0[0] + psi2(0,1,1)*dxids0[1] + psi2(0,1,5)*dxids0[2])*dxids0[1] +
726  (psi2(0,1,4)*dxids0[0] + psi2(0,1,5)*dxids0[1] + psi2(0,1,2)*dxids0[2])*dxids0[2];
727  d2psids(0,2,0) = (psi2(0,2,0)*dxids0[0] + psi2(0,2,3)*dxids0[1] + psi2(0,2,4)*dxids0[2])*dxids0[0] +
728  (psi2(0,2,3)*dxids0[0] + psi2(0,2,1)*dxids0[1] + psi2(0,2,5)*dxids0[2])*dxids0[1] +
729  (psi2(0,2,4)*dxids0[0] + psi2(0,2,5)*dxids0[1] + psi2(0,2,2)*dxids0[2])*dxids0[2];
730  d2psids(0,3,0) = (psi2(0,3,0)*dxids0[0] + psi2(0,3,3)*dxids0[1] + psi2(0,3,4)*dxids0[2])*dxids0[0] +
731  (psi2(0,3,3)*dxids0[0] + psi2(0,3,1)*dxids0[1] + psi2(0,3,5)*dxids0[2])*dxids0[1] +
732  (psi2(0,3,4)*dxids0[0] + psi2(0,3,5)*dxids0[1] + psi2(0,3,2)*dxids0[2])*dxids0[2];
733  d2psids(0,4,0) = (psi2(0,4,0)*dxids0[0] + psi2(0,4,3)*dxids0[1] + psi2(0,4,4)*dxids0[2])*dxids0[0] +
734  (psi2(0,4,3)*dxids0[0] + psi2(0,4,1)*dxids0[1] + psi2(0,4,5)*dxids0[2])*dxids0[1] +
735  (psi2(0,4,4)*dxids0[0] + psi2(0,4,5)*dxids0[1] + psi2(0,4,2)*dxids0[2])*dxids0[2];
736  d2psids(0,5,0) = (psi2(0,5,0)*dxids0[0] + psi2(0,5,3)*dxids0[1] + psi2(0,5,4)*dxids0[2])*dxids0[0] +
737  (psi2(0,5,3)*dxids0[0] + psi2(0,5,1)*dxids0[1] + psi2(0,5,5)*dxids0[2])*dxids0[1] +
738  (psi2(0,5,4)*dxids0[0] + psi2(0,5,5)*dxids0[1] + psi2(0,5,2)*dxids0[2])*dxids0[2];
739 
740  // by chain rule, we can obtain d2shape wrt s1s1 at node0
741  d2psids(0,0,1) = (psi2(0,0,0)*dxids1[0] + psi2(0,0,3)*dxids1[1] + psi2(0,0,4)*dxids1[2])*dxids1[0] +
742  (psi2(0,0,3)*dxids1[0] + psi2(0,0,1)*dxids1[1] + psi2(0,0,5)*dxids1[2])*dxids1[1] +
743  (psi2(0,0,4)*dxids1[0] + psi2(0,0,5)*dxids1[1] + psi2(0,0,2)*dxids1[2])*dxids1[2];
744  d2psids(0,1,1) = (psi2(0,1,0)*dxids1[0] + psi2(0,1,3)*dxids1[1] + psi2(0,1,4)*dxids1[2])*dxids1[0] +
745  (psi2(0,1,3)*dxids1[0] + psi2(0,1,1)*dxids1[1] + psi2(0,1,5)*dxids1[2])*dxids1[1] +
746  (psi2(0,1,4)*dxids1[0] + psi2(0,1,5)*dxids1[1] + psi2(0,1,2)*dxids1[2])*dxids1[2];
747  d2psids(0,2,1) = (psi2(0,2,0)*dxids1[0] + psi2(0,2,3)*dxids1[1] + psi2(0,2,4)*dxids1[2])*dxids1[0] +
748  (psi2(0,2,3)*dxids1[0] + psi2(0,2,1)*dxids1[1] + psi2(0,2,5)*dxids1[2])*dxids1[1] +
749  (psi2(0,2,4)*dxids1[0] + psi2(0,2,5)*dxids1[1] + psi2(0,2,2)*dxids1[2])*dxids1[2];
750  d2psids(0,3,1) = (psi2(0,3,0)*dxids1[0] + psi2(0,3,3)*dxids1[1] + psi2(0,3,4)*dxids1[2])*dxids1[0] +
751  (psi2(0,3,3)*dxids1[0] + psi2(0,3,1)*dxids1[1] + psi2(0,3,5)*dxids1[2])*dxids1[1] +
752  (psi2(0,3,4)*dxids1[0] + psi2(0,3,5)*dxids1[1] + psi2(0,3,2)*dxids1[2])*dxids1[2];
753  d2psids(0,4,1) = (psi2(0,4,0)*dxids1[0] + psi2(0,4,3)*dxids1[1] + psi2(0,4,4)*dxids1[2])*dxids1[0] +
754  (psi2(0,4,3)*dxids1[0] + psi2(0,4,1)*dxids1[1] + psi2(0,4,5)*dxids1[2])*dxids1[1] +
755  (psi2(0,4,4)*dxids1[0] + psi2(0,4,5)*dxids1[1] + psi2(0,4,2)*dxids1[2])*dxids1[2];
756  d2psids(0,5,1) = (psi2(0,5,0)*dxids1[0] + psi2(0,5,3)*dxids1[1] + psi2(0,5,4)*dxids1[2])*dxids1[0] +
757  (psi2(0,5,3)*dxids1[0] + psi2(0,5,1)*dxids1[1] + psi2(0,5,5)*dxids1[2])*dxids1[1] +
758  (psi2(0,5,4)*dxids1[0] + psi2(0,5,5)*dxids1[1] + psi2(0,5,2)*dxids1[2])*dxids1[2];
759 
760  // by chain rule, we can obtain d2shape wrt s0s1 at node0
761  d2psids(0,0,2) = (psi2(0,0,0)*dxids0[0] + psi2(0,0,3)*dxids0[1] + psi2(0,0,4)*dxids0[2])*dxids1[0] +
762  (psi2(0,0,3)*dxids0[0] + psi2(0,0,1)*dxids0[1] + psi2(0,0,5)*dxids0[2])*dxids1[1] +
763  (psi2(0,0,4)*dxids0[0] + psi2(0,0,5)*dxids0[1] + psi2(0,0,2)*dxids0[2])*dxids1[2];
764  d2psids(0,1,2) = (psi2(0,1,0)*dxids0[0] + psi2(0,1,3)*dxids0[1] + psi2(0,1,4)*dxids0[2])*dxids1[0] +
765  (psi2(0,1,3)*dxids0[0] + psi2(0,1,1)*dxids0[1] + psi2(0,1,5)*dxids0[2])*dxids1[1] +
766  (psi2(0,1,4)*dxids0[0] + psi2(0,1,5)*dxids0[1] + psi2(0,1,2)*dxids0[2])*dxids1[2];
767  d2psids(0,2,2) = (psi2(0,2,0)*dxids0[0] + psi2(0,2,3)*dxids0[1] + psi2(0,2,4)*dxids0[2])*dxids1[0] +
768  (psi2(0,2,3)*dxids0[0] + psi2(0,2,1)*dxids0[1] + psi2(0,2,5)*dxids0[2])*dxids1[1] +
769  (psi2(0,2,4)*dxids0[0] + psi2(0,2,5)*dxids0[1] + psi2(0,2,2)*dxids0[2])*dxids1[2];
770  d2psids(0,3,2) = (psi2(0,3,0)*dxids0[0] + psi2(0,3,3)*dxids0[1] + psi2(0,3,4)*dxids0[2])*dxids1[0] +
771  (psi2(0,3,3)*dxids0[0] + psi2(0,3,1)*dxids0[1] + psi2(0,3,5)*dxids0[2])*dxids1[1] +
772  (psi2(0,3,4)*dxids0[0] + psi2(0,3,5)*dxids0[1] + psi2(0,3,2)*dxids0[2])*dxids1[2];
773  d2psids(0,4,2) = (psi2(0,4,0)*dxids0[0] + psi2(0,4,3)*dxids0[1] + psi2(0,4,4)*dxids0[2])*dxids1[0] +
774  (psi2(0,4,3)*dxids0[0] + psi2(0,4,1)*dxids0[1] + psi2(0,4,5)*dxids0[2])*dxids1[1] +
775  (psi2(0,4,4)*dxids0[0] + psi2(0,4,5)*dxids0[1] + psi2(0,4,2)*dxids0[2])*dxids1[2];
776  d2psids(0,5,2) = (psi2(0,5,0)*dxids0[0] + psi2(0,5,3)*dxids0[1] + psi2(0,5,4)*dxids0[2])*dxids1[0] +
777  (psi2(0,5,3)*dxids0[0] + psi2(0,5,1)*dxids0[1] + psi2(0,5,5)*dxids0[2])*dxids1[1] +
778  (psi2(0,5,4)*dxids0[0] + psi2(0,5,5)*dxids0[1] + psi2(0,5,2)*dxids0[2])*dxids1[2];
779  //-------------------------------------------------------------------------------------
780  // compute for all second derivatives at node 1
781  //------------------------------------------------------------------------------------
782  // compute for the second derivatives wrt area coordinate1
783  psi2(1,0,1) = 5.0*4.0*xi[1]*xi[1]*xi[1] +5.0*4.0*3.0*xi[1]*xi[1]*(xi[2]+xi[0]) + 10.0*3.0*2.0*xi[1]*(xi[2]+xi[0])*(xi[2]+xi[0]) +30.0*2.0*xi[2]*xi[0]*(lamb[0]*xi[2] + lamb_p[2]*xi[0]);
784  psi2(1,1,1) = 3.0*b[1]*2.0*xi[2]*xi[0]*(xi[2]-xi[0]) + 3.0*2.0*xi[1]*(b[0]*xi[2] -b[2]*xi[0])*(xi[1] + 4.0*xi[2] + 4.0*xi[0])+ 3.0*xi[1]*xi[1]*(b[0]*xi[2] -b[2]*xi[0]) + 3.0*xi[1]*xi[1]*(b[0]*xi[2] -b[2]*xi[0]) + 15*2.0*xi[2]*xi[0]*(b[0]*lamb[0]*xi[2] - b[2]*lamb_p[2]*xi[0]);
785  psi2(1,2,1) = -3.0*c[1]*2.0*xi[2]*xi[0]*(xi[2]-xi[0]) - 3.0*2.0*xi[1]*(c[0]*xi[2] -c[2]*xi[0])*(xi[1] + 4.0*xi[2] + 4.0*xi[0]) - 3.0*xi[1]*xi[1]*(c[0]*xi[2] -c[2]*xi[0]) - 3.0*xi[1]*xi[1]*(c[0]*xi[2] -c[2]*xi[0]) -15.0*2.0*xi[2]*xi[0]*(c[0]*lamb[0]*xi[2] -c[2]*lamb_p[2]*xi[0]);
786  psi2(1,3,1) = 1.0/2.0*3.0*2.0*xi[1]*(b[0]*b[0]*xi[2]*xi[2] + b[2]*b[2]*xi[0]*xi[0]) + 2.0*xi[2]*xi[0]*(-b[2]*b[0]*xi[1] + b[0]*b[1]*xi[2] + b[1]*b[2]*xi[0]) - 4.0*xi[1]*xi[2]*xi[0]*(b[2]*b[0])+ 5.0*xi[2]*xi[0]*(b[0]*b[0]*lamb[0]*xi[2] + b[2]*b[2]*lamb_p[2]*xi[0]);
787  psi2(1,4,1) = 1.0/2.0*3.0*2.0*xi[1]*(c[0]*c[0]*xi[2]*xi[2] + c[2]*c[2]*xi[0]*xi[0]) + 2.0*xi[2]*xi[0]*(-c[2]*c[0]*xi[1] + c[0]*c[1]*xi[2] + c[1]*c[2]*xi[0]) - 4.0*xi[1]*xi[2]*xi[0]*(c[2]*c[0])+ 5.0*xi[2]*xi[0]*(c[0]*c[0]*lamb[0]*xi[2] + c[2]*c[2]*lamb_p[2]*xi[0]);
788  psi2(1,5,1) = b[1]*c[1]*2.0*xi[2]*xi[0]*(xi[1] + xi[2] + xi[0]) + b[1]*c[1]*2.0*xi[1]*xi[2]*xi[0] + b[1]*c[1]*2.0*xi[1]*xi[2]*xi[0] + b[2]*c[2]*2.0*xi[0]*(xi[2]*xi[0] - xi[0]*xi[1] - xi[1]*xi[2] - xi[2]*xi[2]) - 4.0*b[2]*c[2]*xi[1]*xi[0]*(xi[0]+xi[2]) + b[0]*c[0]*2.0*xi[2]*(xi[2]*xi[0] - xi[0]*xi[1] -xi[1]*xi[2] - xi[0]*xi[0]) - 4.0*b[0]*c[0]*2.0*xi[1]*xi[2]*(xi[0]+xi[2]) - 5.0*2.0*xi[2]*xi[0]*(b[2]*c[2]*lamb_p[2]*xi[0] + b[0]*c[0]*lamb[0]*xi[2]);
789 
790  // compute for the second derivatives wrt area coordinate2
791  psi2(1,0,2) = 10.0*xi[1]*xi[1]*xi[1]*2.0 +30.0*xi[1]*xi[1]*xi[0]*(lamb[0]) +30.0*xi[1]*xi[1]*xi[0]*(lamb[0]);
792  psi2(1,1,2) = 3.0*b[1]*xi[1]*xi[1]*xi[0]+ 3.0*b[1]*xi[1]*xi[1]*xi[0] + xi[1]*xi[1]*xi[1]*(b[0])*(4.0)+ xi[1]*xi[1]*xi[1]*(b[0])*(4.0)+ 15*xi[1]*xi[1]*xi[0]*(b[0]*lamb[0]) + 15*xi[1]*xi[1]*xi[0]*(b[0]*lamb[0]);
793  psi2(1,2,2) = -3.0*c[1]*xi[1]*xi[1]*xi[0]- 3.0*c[1]*xi[1]*xi[1]*xi[0]- xi[1]*xi[1]*xi[1]*(c[0])*(4.0) - xi[1]*xi[1]*xi[1]*(c[0])*(4.0) -15.0*xi[1]*xi[1]*xi[0]*(c[0]*lamb[0])-15.0*xi[1]*xi[1]*xi[0]*(c[0]*lamb[0]);
794  psi2(1,3,2) = 1.0/2.0*xi[1]*xi[1]*xi[1]*(b[0]*b[0]*2.0) + xi[1]*xi[1]*xi[0]*(b[0]*b[1]) + xi[1]*xi[1]*xi[0]*(b[0]*b[1]) + 5.0*xi[1]*xi[1]*xi[0]*(b[0]*b[0]*lamb[0]);
795  psi2(1,4,2) = 1.0/2.0*xi[1]*xi[1]*xi[1]*(c[0]*c[0]*2.0) + xi[1]*xi[1]*xi[0]*(c[0]*c[1]) + xi[1]*xi[1]*xi[0]*(c[0]*c[1]) + 5.0*xi[1]*xi[1]*xi[0]*(c[0]*c[0]*lamb[0]);
796  psi2(1,5,2) = b[1]*c[1]*xi[1]*xi[1]*xi[0] + b[1]*c[1]*xi[1]*xi[1]*xi[0] + b[2]*c[2]*xi[1]*xi[1]*xi[0]*(-2.0) + b[0]*c[0]*xi[1]*xi[1]*(xi[0]-xi[1]) + b[0]*c[0]*xi[1]*xi[1]*(xi[0]-xi[1]) - 5.0*xi[1]*xi[1]*xi[0]*( b[0]*c[0]*lamb[0]) - 5.0*xi[1]*xi[1]*xi[0]*(b[0]*c[0]*lamb[0]);
797 
798  // compute for the second derivatives wrt area coordinate0
799  psi2(1,0,0) = 10.0*xi[1]*xi[1]*xi[1]*2.0 +30.0*xi[1]*xi[1]*xi[2]*(lamb_p[2]) +30.0*xi[1]*xi[1]*xi[2]*(lamb_p[2]);
800  psi2(1,1,0) = -6.0*b[1]*xi[1]*xi[1]*xi[2] + xi[1]*xi[1]*xi[1]*(-b[2])*( 4.0)+ xi[1]*xi[1]*xi[1]*(-b[2])*(4.0) - 30*xi[1]*xi[1]*xi[2]*(b[2]*lamb_p[2]);
801  psi2(1,2,0) = 3.0*c[1]*xi[1]*xi[1]*xi[2] + 3.0*c[1]*xi[1]*xi[1]*xi[2] + xi[1]*xi[1]*xi[1]*(c[2])*(4.0) + xi[1]*xi[1]*xi[1]*(c[2])*(4.0) + 30.0*xi[1]*xi[1]*xi[2]*(c[2]*lamb_p[2]);
802  psi2(1,3,0) = xi[1]*xi[1]*xi[1]*(b[2]*b[2]) + 2.0*xi[1]*xi[1]*xi[2]*(b[1]*b[2]) + 5.0*xi[1]*xi[1]*xi[2]*(b[2]*b[2]*lamb_p[2]);
803  psi2(1,4,0) = xi[1]*xi[1]*xi[1]*(c[2]*c[2]) + 2.0*xi[1]*xi[1]*xi[2]*(c[1]*c[2]) + 5.0*xi[1]*xi[1]*xi[2]*(c[2]*c[2]*lamb_p[2]);
804  psi2(1,5,0) = 2.0*b[1]*c[1]*xi[1]*xi[1]*xi[2] + b[2]*c[2]*xi[1]*xi[1]*(xi[2] - xi[1]) + b[2]*c[2]*xi[1]*xi[1]*(xi[2]- xi[1]) + b[0]*c[0]*xi[1]*xi[1]*xi[2]*(-2.0) - 5.0*xi[1]*xi[1]*xi[2]*(b[2]*c[2]*lamb_p[2]) - 5.0*xi[1]*xi[1]*xi[2]*(b[2]*c[2]*lamb_p[2]);
805 
806  // compute for the second derivatives wrt area coordinate0 and 1
807  psi2(1,0,3) = 5.0*4.0*xi[1]*xi[1]*xi[1] + 10.0*3.0*xi[1]*xi[1]*2.0*(xi[2]+xi[0])+ 30.0*2.0*xi[1]*xi[2]*xi[0]*(lamb_p[2])+30.0*2.0*xi[1]*xi[2]*(lamb[0]*xi[2] + lamb_p[2]*xi[0]);
808  psi2(1,1,3) = 3.0*b[1]*2.0*xi[1]*xi[2]*(xi[2]-xi[0]) + 3.0*b[1]*2.0*xi[1]*xi[2]*xi[0]*(-1.0)+ 3.0*xi[1]*xi[1]*(-b[2])*(xi[1] + 4.0*xi[2] + 4.0*xi[0]) + 3.0*xi[1]*xi[1]*(b[0]*xi[2] -b[2]*xi[0])*(4.0) + xi[1]*xi[1]*xi[1]*(-b[2]) + 15*2.0*xi[1]*xi[2]*(b[0]*lamb[0]*xi[2] - b[2]*lamb_p[2]*xi[0])+ 15*2.0*xi[1]*xi[2]*xi[0]*(-b[2]*lamb_p[2]);
809  psi2(1,2,3) = 3.0*c[1]*2.0*xi[1]*xi[2]*xi[0] -3.0*c[1]*2.0*xi[1]*xi[2]*(xi[2]-xi[0]) - 3.0*xi[1]*xi[1]*(c[0]*xi[2] - c[2]*xi[0])*(4.0) + 3.0*xi[1]*xi[1]*(c[2])*(xi[1] + 4.0*xi[2] + 4.0*xi[0]) + xi[1]*xi[1]*xi[1]*(c[2]) + 15.0*2.0*xi[1]*xi[2]*xi[0]*(c[2]*lamb_p[2]) - 15.0*2.0*xi[1]*xi[2]*(c[0]*lamb[0]*xi[2] -c[2]*lamb_p[2]*xi[0]);
810  psi2(1,3,3) = 3.0*xi[1]*xi[1]*(b[2]*b[2]*xi[0]) + 2.0*xi[1]*xi[2]*(-b[2]*b[0]*xi[1] + b[0]*b[1]*xi[2] + b[1]*b[2]*xi[0])+ 2.0*xi[1]*xi[2]*xi[0]*(b[1]*b[2]) + 5.0/2.0*2.0*xi[1]*xi[2]*(b[0]*b[0]*lamb[0]*xi[2] + b[2]*b[2]*lamb_p[2]*xi[0])+ 5.0/2.0*2.0*xi[1]*xi[2]*xi[0]*(b[2]*b[2]*lamb_p[2]) + xi[1]*xi[1]*xi[2]*(-b[2])*b[0];
811  psi2(1,4,3) = 3.0*xi[1]*xi[1]*(c[2]*c[2]*xi[0]) + 2.0*xi[1]*xi[2]*(-c[2]*c[0]*xi[1] + c[0]*c[1]*xi[2] + c[1]*c[2]*xi[0]) + 2.0*xi[1]*xi[2]*xi[0]*(c[1]*c[2])+ 5.0/2.0*2.0*xi[1]*xi[2]*(c[0]*c[0]*lamb[0]*xi[2] + c[2]*c[2]*lamb_p[2]*xi[0])+ 5.0/2.0*2.0*xi[1]*xi[2]*xi[0]*(c[2]*c[2]*lamb_p[2])+ xi[1]*xi[1]*xi[2]*(-c[2])*c[0];
812  psi2(1,5,3) = b[1]*c[1]*2.0*xi[1]*xi[2]*xi[0] + b[1]*c[1]*2.0*xi[1]*xi[2]*(xi[1] + xi[2] + xi[0]) + b[1]*c[1]*xi[1]*xi[1]*xi[2] + b[2]*c[2]*2.0*xi[1]*(xi[2]*xi[0] - xi[0]*xi[1] - xi[1]*xi[2] - xi[2]*xi[2]) + b[2]*c[2]*2.0*xi[1]*xi[0]*(xi[2]- xi[1]) + b[2]*c[2]*xi[1]*xi[1]*(-xi[2] - xi[0])+ b[2]*c[2]*xi[1]*xi[1]*xi[0]*(-1.0)
813  + b[0]*c[0]*2.0*xi[1]*xi[2]*(xi[2]-xi[1]- 2.0*xi[0]) + b[0]*c[0]*xi[1]*xi[1]*xi[2]*(-1.0)- 5.0*2.0*xi[1]*xi[2]*(b[2]*c[2]*lamb_p[2]*xi[0] + b[0]*c[0]*lamb[0]*xi[2]) - 5.0*2.0*xi[1]*xi[2]*xi[0]*(b[2]*c[2]*lamb_p[2]);
814 
815  // compute for the second derivatives wrt area coordinate0 and 2
816  psi2(1,0,4) = 10.0*xi[1]*xi[1]*xi[1]*2.0 + 30.0*xi[1]*xi[1]*(lamb[0]*xi[2] + lamb_p[2]*xi[0]) +30.0*xi[1]*xi[1]*xi[0]*(lamb_p[2]) + 30.0*xi[1]*xi[1]*xi[2]*(lamb[0]);
817  psi2(1,1,4) = 3.0*b[1]*xi[1]*xi[1]*(xi[2]-xi[0]) + 3.0*b[1]*xi[1]*xi[1]*xi[0]*(-1.0)+ 3.0*b[1]*xi[1]*xi[1]*xi[2] + xi[1]*xi[1]*xi[1]*(-b[2])*(4.0)+ xi[1]*xi[1]*xi[1]*(b[0])*(4.0) + 15*xi[1]*xi[1]*(b[0]*lamb[0]*xi[2] - b[2]*lamb_p[2]*xi[0]) + 15*xi[1]*xi[1]*xi[0]*(-b[2]*lamb_p[2]) + 15*xi[1]*xi[1]*xi[2]*(b[0]*lamb[0]);
818  psi2(1,2,4) = 3.0*c[1]*xi[1]*xi[1]*xi[0] - 3.0*c[1]*xi[1]*xi[1]*(xi[2]-xi[0]) - 3.0*c[1]*xi[1]*xi[1]*xi[2] - xi[1]*xi[1]*xi[1]*(c[0])*(4.0) + 4.0*xi[1]*xi[1]*xi[1]*(c[2]) + 15.0*xi[1]*xi[1]*xi[0]*(c[2]*lamb_p[2]) - 15.0*xi[1]*xi[1]*(c[0]*lamb[0]*xi[2] -c[2]*lamb_p[2]*xi[0]) -15.0*xi[1]*xi[1]*xi[2]*(c[0]*lamb[0]);
819  psi2(1,3,4) = xi[1]*xi[1]*xi[0]*(b[1]*b[2]) + xi[1]*xi[1]*(-b[2]*b[0]*xi[1] + b[0]*b[1]*xi[2] + b[1]*b[2]*xi[0]) + xi[1]*xi[1]*xi[2]*(b[0]*b[1]) + 5.0/2.0*xi[1]*xi[1]*xi[0]*(b[2]*b[2]*lamb_p[2]) + 5.0/2.0*xi[1]*xi[1]*(b[0]*b[0]*lamb[0]*xi[2] + b[2]*b[2]*lamb_p[2]*xi[0]) + 5.0/2.0*xi[1]*xi[1]*xi[2]*(b[0]*b[0]*lamb[0]);
820  psi2(1,4,4) = xi[1]*xi[1]*xi[2]*(c[0]*c[1]) + xi[1]*xi[1]*(-c[2]*c[0]*xi[1] + c[0]*c[1]*xi[2] + c[1]*c[2]*xi[0])+ xi[1]*xi[1]*xi[0]*(c[1]*c[2]) + 5.0/2.0*xi[1]*xi[1]*xi[2]*(c[0]*c[0]*lamb[0]) + 5.0/2.0*xi[1]*xi[1]*(c[0]*c[0]*lamb[0]*xi[2] + c[2]*c[2]*lamb_p[2]*xi[0]) + 5.0/2.0*xi[1]*xi[1]*xi[0]*(c[2]*c[2]*lamb_p[2]);
821  psi2(1,5,4) = b[1]*c[1]*xi[1]*xi[1]*xi[2]+ b[1]*c[1]*xi[1]*xi[1]*(xi[1] + xi[2] + xi[0]) + b[1]*c[1]*xi[1]*xi[1]*xi[0] + b[2]*c[2]*xi[1]*xi[1]*(xi[0] - xi[1] - 2.0*xi[2]) + b[2]*c[2]*xi[1]*xi[1]*xi[0] + b[0]*c[0]*xi[1]*xi[1]*xi[2] + b[0]*c[0]*xi[1]*xi[1]*(xi[2]- xi[1] - 2.0*xi[0]) - 5.0*xi[1]*xi[1]*xi[2]*(b[0]*c[0]*lamb[0])- 5.0*xi[1]*xi[1]*(b[2]*c[2]*lamb_p[2]*xi[0] + b[0]*c[0]*lamb[0]*xi[2]) - 5.0*xi[1]*xi[1]*xi[0]*(b[2]*c[2]*lamb_p[2]);
822 
823  // compute for the second derivatives wrt area coordinate1 and 2
824  psi2(1,0,5) = 5.0*4.0*xi[1]*xi[1]*xi[1] + 10.0*3.0*xi[1]*xi[1]*2.0*(xi[2]+xi[0]) +30.0*2.0*xi[1]*xi[0]*(lamb[0]*xi[2] + lamb_p[2]*xi[0]) + 30.0*2.0*xi[1]*xi[2]*xi[0]*(lamb[0]);
825  psi2(1,1,5) = 3.0*b[1]*2.0*xi[1]*xi[0]*(xi[2]-xi[0])+ 3.0*b[1]*2.0*xi[1]*xi[2]*xi[0] + 3.0*xi[1]*xi[1]*(b[0])*(xi[1] + 4.0*xi[2] + 4.0*xi[0]) + 3.0*xi[1]*xi[1]*(b[0]*xi[2] -b[2]*xi[0])*(4.0) + xi[1]*xi[1]*xi[1]*(b[0])+ 15*2.0*xi[1]*xi[0]*(b[0]*lamb[0]*xi[2] - b[2]*lamb_p[2]*xi[0]) + 15*2.0*xi[1]*xi[2]*xi[0]*(b[0]*lamb[0]);
826  psi2(1,2,5) = -3.0*c[1]*2.0*xi[1]*xi[0]*(xi[2]-xi[0]) -3.0*c[1]*2.0*xi[1]*xi[2]*xi[0] - 3.0*xi[1]*xi[1]*(c[0])*(xi[1] + 4.0*xi[2] + 4.0*xi[0]) - 3.0*xi[1]*xi[1]*(c[0]*xi[2] -c[2]*xi[0])*(4.0) - xi[1]*xi[1]*xi[1]*(c[0]) -15.0*2.0*xi[1]*xi[0]*(c[0]*lamb[0]*xi[2] -c[2]*lamb_p[2]*xi[0]) -15.0*2.0*xi[1]*xi[2]*xi[0]*(c[0]*lamb[0]);
827  psi2(1,3,5) = 3.0*xi[1]*xi[1]*(b[0]*b[0]*xi[2]) + 2.0*xi[1]*xi[0]*(-b[2]*b[0]*xi[1] + b[0]*b[1]*xi[2] + b[1]*b[2]*xi[0]) + 2.0*xi[1]*xi[2]*xi[0]*(b[0]*b[1]) + 5.0/2.0*2.0*xi[1]*xi[0]*(b[0]*b[0]*lamb[0]*xi[2] + b[2]*b[2]*lamb_p[2]*xi[0])+ 5.0/2.0*2.0*xi[1]*xi[2]*xi[0]*(b[0]*b[0]*lamb[0]) + xi[1]*xi[1]*xi[0]*(-b[2])*b[0];
828  psi2(1,4,5) = 3.0*xi[1]*xi[1]*(c[0]*c[0]*xi[2]) + 2.0*xi[1]*xi[0]*(-c[2]*c[0]*xi[1] + c[0]*c[1]*xi[2] + c[1]*c[2]*xi[0]) + 2.0*xi[1]*xi[2]*xi[0]*(c[0]*c[1]) + 5.0/2.0*2.0*xi[1]*xi[0]*(c[0]*c[0]*lamb[0]*xi[2] + c[2]*c[2]*lamb_p[2]*xi[0])+ 5.0/2.0*2.0*xi[1]*xi[2]*xi[0]*(c[0]*c[0]*lamb[0])+ xi[1]*xi[1]*xi[0]*(-c[2])*c[0];
829  psi2(1,5,5) = b[1]*c[1]*2.0*xi[1]*xi[0]*(xi[1] + xi[2] + xi[0]) + b[1]*c[1]*2.0*xi[1]*xi[2]*xi[0] + b[1]*c[1]*xi[1]*xi[1]*xi[0] + b[2]*c[2]*2.0*xi[1]*xi[0]*(xi[0] - xi[1] - 2.0*xi[2]) + b[2]*c[2]*xi[1]*xi[1]*xi[0]*(-1.0) + b[0]*c[0]*2.0*xi[1]*(xi[2]*xi[0] - xi[0]*xi[1] -xi[1]*xi[2] - xi[0]*xi[0]) + b[0]*c[0]*2.0*xi[1]*xi[2]*(xi[0] -xi[1]) + b[0]*c[0]*xi[1]*xi[1]*(- xi[0]-xi[2]) + b[0]*c[0]*xi[1]*xi[1]*xi[2]*(-1.0) - 5.0*2.0*xi[1]*xi[0]*(b[2]*c[2]*lamb_p[2]*xi[0] + b[0]*c[0]*lamb[0]*xi[2]) - 5.0*2.0*xi[1]*xi[2]*xi[0]*(b[0]*c[0]*lamb[0]);
830 
831  // by chain rule, we can obtain d2shape wrt s0s0 at node1
832  d2psids(1,0,0) = (psi2(1,0,0)*dxids0[0] + psi2(1,0,3)*dxids0[1] + psi2(1,0,4)*dxids0[2])*dxids0[0] +
833  (psi2(1,0,3)*dxids0[0] + psi2(1,0,1)*dxids0[1] + psi2(1,0,5)*dxids0[2])*dxids0[1] +
834  (psi2(1,0,4)*dxids0[0] + psi2(1,0,5)*dxids0[1] + psi2(1,0,2)*dxids0[2])*dxids0[2];
835  d2psids(1,1,0) = (psi2(1,1,0)*dxids0[0] + psi2(1,1,3)*dxids0[1] + psi2(1,1,4)*dxids0[2])*dxids0[0] +
836  (psi2(1,1,3)*dxids0[0] + psi2(1,1,1)*dxids0[1] + psi2(1,1,5)*dxids0[2])*dxids0[1] +
837  (psi2(1,1,4)*dxids0[0] + psi2(1,1,5)*dxids0[1] + psi2(1,1,2)*dxids0[2])*dxids0[2];
838  d2psids(1,2,0) = (psi2(1,2,0)*dxids0[0] + psi2(1,2,3)*dxids0[1] + psi2(1,2,4)*dxids0[2])*dxids0[0] +
839  (psi2(1,2,3)*dxids0[0] + psi2(1,2,1)*dxids0[1] + psi2(1,2,5)*dxids0[2])*dxids0[1] +
840  (psi2(1,2,4)*dxids0[0] + psi2(1,2,5)*dxids0[1] + psi2(1,2,2)*dxids0[2])*dxids0[2];
841  d2psids(1,3,0) = (psi2(1,3,0)*dxids0[0] + psi2(1,3,3)*dxids0[1] + psi2(1,3,4)*dxids0[2])*dxids0[0] +
842  (psi2(1,3,3)*dxids0[0] + psi2(1,3,1)*dxids0[1] + psi2(1,3,5)*dxids0[2])*dxids0[1] +
843  (psi2(1,3,4)*dxids0[0] + psi2(1,3,5)*dxids0[1] + psi2(1,3,2)*dxids0[2])*dxids0[2];
844  d2psids(1,4,0) = (psi2(1,4,0)*dxids0[0] + psi2(1,4,3)*dxids0[1] + psi2(1,4,4)*dxids0[2])*dxids0[0] +
845  (psi2(1,4,3)*dxids0[0] + psi2(1,4,1)*dxids0[1] + psi2(1,4,5)*dxids0[2])*dxids0[1] +
846  (psi2(1,4,4)*dxids0[0] + psi2(1,4,5)*dxids0[1] + psi2(1,4,2)*dxids0[2])*dxids0[2];
847  d2psids(1,5,0) = (psi2(1,5,0)*dxids0[0] + psi2(1,5,3)*dxids0[1] + psi2(1,5,4)*dxids0[2])*dxids0[0] +
848  (psi2(1,5,3)*dxids0[0] + psi2(1,5,1)*dxids0[1] + psi2(1,5,5)*dxids0[2])*dxids0[1] +
849  (psi2(1,5,4)*dxids0[0] + psi2(1,5,5)*dxids0[1] + psi2(1,5,2)*dxids0[2])*dxids0[2];
850 
851  // by chain rule, we can obtain d2shape wrt s1s1 at node1
852  d2psids(1,0,1) = (psi2(1,0,0)*dxids1[0] + psi2(1,0,3)*dxids1[1] + psi2(1,0,4)*dxids1[2])*dxids1[0] +
853  (psi2(1,0,3)*dxids1[0] + psi2(1,0,1)*dxids1[1] + psi2(1,0,5)*dxids1[2])*dxids1[1] +
854  (psi2(1,0,4)*dxids1[0] + psi2(1,0,5)*dxids1[1] + psi2(1,0,2)*dxids1[2])*dxids1[2];
855  d2psids(1,1,1) = (psi2(1,1,0)*dxids1[0] + psi2(1,1,3)*dxids1[1] + psi2(1,1,4)*dxids1[2])*dxids1[0] +
856  (psi2(1,1,3)*dxids1[0] + psi2(1,1,1)*dxids1[1] + psi2(1,1,5)*dxids1[2])*dxids1[1] +
857  (psi2(1,1,4)*dxids1[0] + psi2(1,1,5)*dxids1[1] + psi2(1,1,2)*dxids1[2])*dxids1[2];
858  d2psids(1,2,1) = (psi2(1,2,0)*dxids1[0] + psi2(1,2,3)*dxids1[1] + psi2(1,2,4)*dxids1[2])*dxids1[0] +
859  (psi2(1,2,3)*dxids1[0] + psi2(1,2,1)*dxids1[1] + psi2(1,2,5)*dxids1[2])*dxids1[1] +
860  (psi2(1,2,4)*dxids1[0] + psi2(1,2,5)*dxids1[1] + psi2(1,2,2)*dxids1[2])*dxids1[2];
861  d2psids(1,3,1) = (psi2(1,3,0)*dxids1[0] + psi2(1,3,3)*dxids1[1] + psi2(1,3,4)*dxids1[2])*dxids1[0] +
862  (psi2(1,3,3)*dxids1[0] + psi2(1,3,1)*dxids1[1] + psi2(1,3,5)*dxids1[2])*dxids1[1] +
863  (psi2(1,3,4)*dxids1[0] + psi2(1,3,5)*dxids1[1] + psi2(1,3,2)*dxids1[2])*dxids1[2];
864  d2psids(1,4,1) = (psi2(1,4,0)*dxids1[0] + psi2(1,4,3)*dxids1[1] + psi2(1,4,4)*dxids1[2])*dxids1[0] +
865  (psi2(1,4,3)*dxids1[0] + psi2(1,4,1)*dxids1[1] + psi2(1,4,5)*dxids1[2])*dxids1[1] +
866  (psi2(1,4,4)*dxids1[0] + psi2(1,4,5)*dxids1[1] + psi2(1,4,2)*dxids1[2])*dxids1[2];
867  d2psids(1,5,1) = (psi2(1,5,0)*dxids1[0] + psi2(1,5,3)*dxids1[1] + psi2(1,5,4)*dxids1[2])*dxids1[0] +
868  (psi2(1,5,3)*dxids1[0] + psi2(1,5,1)*dxids1[1] + psi2(1,5,5)*dxids1[2])*dxids1[1] +
869  (psi2(1,5,4)*dxids1[0] + psi2(1,5,5)*dxids1[1] + psi2(1,5,2)*dxids1[2])*dxids1[2];
870 
871  // by chain rule, we can obtain d2shape wrt s0s1 at node1
872  d2psids(1,0,2) = (psi2(1,0,0)*dxids0[0] + psi2(1,0,3)*dxids0[1] + psi2(1,0,4)*dxids0[2])*dxids1[0] +
873  (psi2(1,0,3)*dxids0[0] + psi2(1,0,1)*dxids0[1] + psi2(1,0,5)*dxids0[2])*dxids1[1] +
874  (psi2(1,0,4)*dxids0[0] + psi2(1,0,5)*dxids0[1] + psi2(1,0,2)*dxids0[2])*dxids1[2];
875  d2psids(1,1,2) = (psi2(1,1,0)*dxids0[0] + psi2(1,1,3)*dxids0[1] + psi2(1,1,4)*dxids0[2])*dxids1[0] +
876  (psi2(1,1,3)*dxids0[0] + psi2(1,1,1)*dxids0[1] + psi2(1,1,5)*dxids0[2])*dxids1[1] +
877  (psi2(1,1,4)*dxids0[0] + psi2(1,1,5)*dxids0[1] + psi2(1,1,2)*dxids0[2])*dxids1[2];
878  d2psids(1,2,2) = (psi2(1,2,0)*dxids0[0] + psi2(1,2,3)*dxids0[1] + psi2(1,2,4)*dxids0[2])*dxids1[0] +
879  (psi2(1,2,3)*dxids0[0] + psi2(1,2,1)*dxids0[1] + psi2(1,2,5)*dxids0[2])*dxids1[1] +
880  (psi2(1,2,4)*dxids0[0] + psi2(1,2,5)*dxids0[1] + psi2(1,2,2)*dxids0[2])*dxids1[2];
881  d2psids(1,3,2) = (psi2(1,3,0)*dxids0[0] + psi2(1,3,3)*dxids0[1] + psi2(1,3,4)*dxids0[2])*dxids1[0] +
882  (psi2(1,3,3)*dxids0[0] + psi2(1,3,1)*dxids0[1] + psi2(1,3,5)*dxids0[2])*dxids1[1] +
883  (psi2(1,3,4)*dxids0[0] + psi2(1,3,5)*dxids0[1] + psi2(1,3,2)*dxids0[2])*dxids1[2];
884  d2psids(1,4,2) = (psi2(1,4,0)*dxids0[0] + psi2(1,4,3)*dxids0[1] + psi2(1,4,4)*dxids0[2])*dxids1[0] +
885  (psi2(1,4,3)*dxids0[0] + psi2(1,4,1)*dxids0[1] + psi2(1,4,5)*dxids0[2])*dxids1[1] +
886  (psi2(1,4,4)*dxids0[0] + psi2(1,4,5)*dxids0[1] + psi2(1,4,2)*dxids0[2])*dxids1[2];
887  d2psids(1,5,2) = (psi2(1,5,0)*dxids0[0] + psi2(1,5,3)*dxids0[1] + psi2(1,5,4)*dxids0[2])*dxids1[0] +
888  (psi2(1,5,3)*dxids0[0] + psi2(1,5,1)*dxids0[1] + psi2(1,5,5)*dxids0[2])*dxids1[1] +
889  (psi2(1,5,4)*dxids0[0] + psi2(1,5,5)*dxids0[1] + psi2(1,5,2)*dxids0[2])*dxids1[2];
890  //-------------------------------------------------------------------------------------
891  // compute for all second derivatives at node 2
892  //------------------------------------------------------------------------------------
893  // compute for the second derivatives wrt area coordinate2
894  psi2(2,0,2) = 5.0*4.0*xi[2]*xi[2]*xi[2] +5.0*4.0*3.0*xi[2]*xi[2]*(xi[0]+xi[1]) + 10.0*3.0*2.0*xi[2]*(xi[0]+xi[1])*(xi[0]+xi[1]) + 30.0*2.0*xi[0]*xi[1]*(lamb[1]*xi[0] + lamb_p[0]*xi[1]);
895  psi2(2,1,2) = 3.0*b[2]*2.0*xi[0]*xi[1]*(xi[0]-xi[1]) + 6.0*xi[2]*xi[2]*(b[1]*xi[0] - b[0]*xi[1]) + 30.0*xi[0]*xi[1]*(b[1]*lamb[1]*xi[0] - b[0]*lamb_p[0]*xi[1]) + 3.0*2.0*xi[2]*(b[1]*xi[0] -b[0]*xi[1])*(xi[2] + 4.0*xi[0] + 4*xi[1]);
896  psi2(2,2,2) = -3.0*c[2]*2.0*xi[0]*xi[1]*(xi[0]-xi[1]) - 3.0*2.0*xi[2]*(c[1]*xi[0] -c[0]*xi[1])*(xi[2] + 4.0*xi[0] + 4.0*xi[1]) - 6.0*xi[2]*xi[2]*(c[1]*xi[0] -c[0]*xi[1]) -15.0*2.0*xi[0]*xi[1]*(c[1]*lamb[1]*xi[0] -c[0]*lamb_p[0]*xi[1]);
897  psi2(2,3,2) = 1.0/2.0*3.0*2.0*xi[2]*(b[1]*b[1]*xi[0]*xi[0] + b[0]*b[0]*xi[1]*xi[1]) + 2.0*xi[0]*xi[1]*(-b[0]*b[1]*xi[2] + b[1]*b[2]*xi[0] + b[2]*b[0]*xi[1]) + 2.0*xi[2]*xi[0]*xi[1]*(-b[0]*b[1])
898  + 5.0/2.0*2.0*xi[0]*xi[1]*(b[1]*b[1]*lamb[1]*xi[0] + b[0]*b[0]*lamb_p[0]*xi[1]) + 2.0*xi[2]*xi[0]*xi[1]*(-b[0])*b[1];
899  psi2(2,4,2) = 1.0/2.0*3.0*2.0*xi[2]*(c[1]*c[1]*xi[0]*xi[0] + c[0]*c[0]*xi[1]*xi[1]) + 2.0*xi[0]*xi[1]*(-c[0]*c[1]*xi[2] + c[1]*c[2]*xi[0] + c[2]*c[0]*xi[1]) + 2.0*xi[2]*xi[0]*xi[1]*(-c[0]*c[1])
900  + 5.0/2.0*2.0*xi[0]*xi[1]*(c[1]*c[1]*lamb[1]*xi[0] + c[0]*c[0]*lamb_p[0]*xi[1])+ 2.0*xi[2]*xi[0]*xi[1]*(-c[0])*c[1];
901  psi2(2,5,2) = b[2]*c[2]*2.0*xi[0]*xi[1]*(xi[2] + xi[0] + xi[1]) + b[2]*c[2]*2.0*xi[2]*xi[0]*xi[1] + b[2]*c[2]*2.0*xi[2]*xi[0]*xi[1] + b[0]*c[0]*2.0*xi[1]*(xi[0]*xi[1] - xi[1]*xi[2] - xi[2]*xi[0] - xi[0]*xi[0]) + b[0]*c[0]*2.0*xi[2]*xi[1]*(-1.0*xi[1] - 1.0*xi[0]) + b[0]*c[0]*2.0*xi[2]*xi[1]*(-xi[0] - xi[1])
902  + b[1]*c[1]*2.0*xi[0]*(xi[0]*xi[1] - xi[1]*xi[2] -xi[2]*xi[0] - xi[1]*xi[1]) + b[1]*c[1]*2.0*xi[2]*xi[0]*(-xi[1] -xi[0])+ b[1]*c[1]*2.0*xi[2]*xi[0]*(- xi[1]-xi[0]) - 5.0*2.0*xi[0]*xi[1]*(b[0]*c[0]*lamb_p[0]*xi[1] + b[1]*c[1]*lamb[1]*xi[0]);
903 
904  // compute for the second derivatives wrt area coordinate0
905  psi2(2,0,0) = 10.0*xi[2]*xi[2]*xi[2]*2.0 + 60.0*xi[2]*xi[2]*xi[1]*(lamb[1]);
906  psi2(2,1,0) = 6.0*b[2]*xi[2]*xi[2]*xi[1] + xi[2]*xi[2]*xi[2]*(b[1])*(8.0) + 30*xi[2]*xi[2]*xi[1]*(b[1]*lamb[1]);
907  psi2(2,2,0) =-6.0*c[2]*xi[2]*xi[2]*xi[1] - xi[2]*xi[2]*xi[2]*(c[1])*(8.0) - 30.0*xi[2]*xi[2]*xi[1]*(c[1]*lamb[1]);
908  psi2(2,3,0) = 1.0/2.0*xi[2]*xi[2]*xi[2]*(b[1]*b[1]*2.0) + xi[2]*xi[2]*xi[1]*(b[1]*b[2]) + xi[2]*xi[2]*xi[1]*(b[1]*b[2]) + 5.0/2.0*xi[2]*xi[2]*xi[1]*(b[1]*b[1]*lamb[1]) + 5.0/2.0*xi[2]*xi[2]*xi[1]*(b[1]*b[1]*lamb[1]);
909  psi2(2,4,0) = 1.0/2.0*xi[2]*xi[2]*xi[2]*(c[1]*c[1]*2.0) + xi[2]*xi[2]*xi[1]*( c[1]*c[2]) + xi[2]*xi[2]*xi[1]*(c[1]*c[2])+ 5.0/2.0*xi[2]*xi[2]*xi[1]*(c[1]*c[1]*lamb[1]) + 5.0/2.0*xi[2]*xi[2]*xi[1]*(c[1]*c[1]*lamb[1]);
910  psi2(2,5,0) = b[2]*c[2]*xi[2]*xi[2]*xi[1] + b[2]*c[2]*xi[2]*xi[2]*xi[1] + b[0]*c[0]*xi[2]*xi[2]*xi[1]*(-2.0)
911  + b[1]*c[1]*xi[2]*xi[2]*(xi[1] -xi[2]) + b[1]*c[1]*xi[2]*xi[2]*(xi[1] -xi[2]) - 5.0*xi[2]*xi[2]*xi[1]*( b[1]*c[1]*lamb[1]) - 5.0*xi[2]*xi[2]*xi[1]*(b[1]*c[1]*lamb[1]);
912 
913  // compute for the second derivatives wrt area coordinate1
914  psi2(2,0,1) = 10.0*xi[2]*xi[2]*xi[2]*2.0 +30.0*xi[2]*xi[2]*xi[0]*(lamb_p[0]) +30.0*xi[2]*xi[2]*xi[0]*(lamb_p[0]);
915  psi2(2,1,1) = -30.0*b[0]*lamb_p[0]*xi[0]*xi[2]*xi[2] - 6.0*b[2]*xi[2]*xi[2]*xi[0] - xi[2]*xi[2]*xi[2]*(b[0])*(8.0);
916  psi2(2,2,1) = 6.0*c[2]*xi[2]*xi[2]*xi[0] + xi[2]*xi[2]*xi[2]*(c[0])*(8.0) + 30.0*xi[2]*xi[2]*xi[0]*(c[0]*lamb_p[0]);
917  psi2(2,3,1) = 1.0/2.0*xi[2]*xi[2]*xi[2]*(b[0]*b[0]*2.0) + xi[2]*xi[2]*xi[0]*( b[2]*b[0]) + xi[2]*xi[2]*xi[0]*(b[2]*b[0]) + 5.0/2.0*xi[2]*xi[2]*xi[0]*( b[0]*b[0]*lamb_p[0])+ 5.0/2.0*xi[2]*xi[2]*xi[0]*(b[0]*b[0]*lamb_p[0]);
918  psi2(2,4,1) = 1.0/2.0*xi[2]*xi[2]*xi[2]*(c[0]*c[0]*2.0) + xi[2]*xi[2]*xi[0]*(c[2]*c[0]) + xi[2]*xi[2]*xi[0]*(c[2]*c[0]) + 5.0/2.0*xi[2]*xi[2]*xi[0]*(c[0]*c[0]*lamb_p[0]) + 5.0/2.0*xi[2]*xi[2]*xi[0]*(c[0]*c[0]*lamb_p[0]);
919  psi2(2,5,1) = b[2]*c[2]*xi[2]*xi[2]*xi[0] + b[2]*c[2]*xi[2]*xi[2]*xi[0] + b[0]*c[0]*xi[2]*xi[2]*(xi[0] - xi[2]) + b[0]*c[0]*xi[2]*xi[2]*(xi[0]- xi[2]) + b[1]*c[1]*xi[2]*xi[2]*xi[0]*(-2.0) - 5.0*xi[2]*xi[2]*xi[0]*(b[0]*c[0]*lamb_p[0]) - 5.0*xi[2]*xi[2]*xi[0]*(b[0]*c[0]*lamb_p[0]);
920 
921  // compute for the second derivatives wrt area coordinate0 and 1
922  psi2(2,0,3) = 10.0*xi[2]*xi[2]*xi[2]*2.0 + 30.0*xi[2]*xi[2]*(lamb[1]*xi[0] + lamb_p[0]*xi[1]) + 30.0*xi[2]*xi[2]*xi[0]*(lamb[1]) + 30.0*xi[2]*xi[2]*xi[1]*(lamb_p[0]);
923  psi2(2,1,3) = 3.0*b[2]*xi[2]*xi[2]*(xi[0]-xi[1])-3.0*b[2]*xi[2]*xi[2]*xi[1] + 3.0*b[2]*xi[2]*xi[2]*xi[0] + xi[2]*xi[2]*xi[2]*(b[1])*(4.0)+ xi[2]*xi[2]*xi[2]*(-b[0])*(4.0) + 15*xi[2]*xi[2]*(b[1]*lamb[1]*xi[0] - b[0]*lamb_p[0]*xi[1]) + 15*xi[2]*xi[2]*xi[1]*(-b[0]*lamb_p[0]) + 15*xi[2]*xi[2]*xi[0]*(b[1]*lamb[1]);
924  psi2(2,2,3) = -3.0*c[2]*xi[2]*xi[2]*xi[0] + -3.0*c[2]*xi[2]*xi[2]*(xi[0]-xi[1])+ 3.0*c[2]*xi[2]*xi[2]*xi[1] + xi[2]*xi[2]*xi[2]*(c[0])*(4.0) - xi[2]*xi[2]*xi[2]*(c[1])*(4.0) - 15.0*xi[2]*xi[2]*xi[0]*(c[1]*lamb[1]) - 15.0*xi[2]*xi[2]*(c[1]*lamb[1]*xi[0] -c[0]*lamb_p[0]*xi[1]) + 15.0*xi[2]*xi[2]*xi[1]*(c[0]*lamb_p[0]);
925  psi2(2,3,3) = xi[2]*xi[2]*xi[0]*(b[1]*b[2]) + xi[2]*xi[2]*(-b[0]*b[1]*xi[2] + b[1]*b[2]*xi[0] + b[2]*b[0]*xi[1]) + xi[2]*xi[2]*xi[1]*(b[2]*b[0]) + 5.0/2.0*xi[2]*xi[2]*xi[0]*(b[1]*b[1]*lamb[1]) + 5.0/2.0*xi[2]*xi[2]*(b[1]*b[1]*lamb[1]*xi[0] + b[0]*b[0]*lamb_p[0]*xi[1]) + 5.0/2.0*xi[2]*xi[2]*xi[1]*( b[0]*b[0]*lamb_p[0]);
926  psi2(2,4,3) = xi[2]*xi[2]*xi[0]*(c[1]*c[2]) + xi[2]*xi[2]*(-c[0]*c[1]*xi[2] + c[1]*c[2]*xi[0] + c[2]*c[0]*xi[1]) + xi[2]*xi[2]*xi[1]*(c[2]*c[0])+ 5.0/2.0*xi[2]*xi[2]*xi[0]*(c[1]*c[1]*lamb[1]) + 5.0/2.0*xi[2]*xi[2]*(c[1]*c[1]*lamb[1]*xi[0] + c[0]*c[0]*lamb_p[0]*xi[1]) + 5.0/2.0*xi[2]*xi[2]*xi[1]*(c[0]*c[0]*lamb_p[0]);
927  psi2(2,5,3) = b[2]*c[2]*xi[2]*xi[2]*xi[0] + b[2]*c[2]*xi[2]*xi[2]*(xi[2] + xi[0] + xi[1])+ b[2]*c[2]*xi[2]*xi[2]*xi[1] + b[0]*c[0]*xi[2]*xi[2]*(xi[1] - xi[2] - 2.0*xi[0])+ b[0]*c[0]*xi[2]*xi[2]*xi[1] + b[1]*c[1]*xi[2]*xi[2]*xi[0] + b[1]*c[1]*xi[2]*xi[2]*(xi[0] - xi[2] - 2.0*xi[1]) - 5.0*xi[2]*xi[2]*xi[0]*( b[1]*c[1]*lamb[1]) - 5.0*xi[2]*xi[2]*(b[0]*c[0]*lamb_p[0]*xi[1] + b[1]*c[1]*lamb[1]*xi[0]) - 5.0*xi[2]*xi[2]*xi[1]*(b[0]*c[0]*lamb_p[0]);
928 
929  // compute for the second derivatives wrt area coordinate0 and 2
930  psi2(2,0,4) = 5.0*4.0*xi[2]*xi[2]*xi[2] + 10.0*3.0*xi[2]*xi[2]*2.0*(xi[0]+xi[1]) + 30.0*2.0*xi[2]*xi[1]*(lamb[1]*xi[0] + lamb_p[0]*xi[1]) + 30.0*2.0*xi[2]*xi[0]*xi[1]*(lamb[1]);
931  psi2(2,1,4) = 3.0*b[2]*2.0*xi[2]*xi[1]*(xi[0]-xi[1]) + 3.0*b[2]*2.0*xi[2]*xi[0]*xi[1] + 3.0*xi[2]*xi[2]*(b[1])*(xi[2] + 4.0*xi[0] + 4.0*xi[1])+ xi[2]*xi[2]*xi[2]*(b[1]) + 12.0*xi[2]*xi[2]*(b[1]*xi[0] - b[0]*xi[1]) + 15*2.0*xi[2]*xi[1]*(b[1]*lamb[1]*xi[0] - b[0]*lamb_p[0]*xi[1]) + 15*2.0*xi[2]*xi[0]*xi[1]*(b[1]*lamb[1]);
932  psi2(2,2,4) = -3.0*c[2]*2.0*xi[2]*xi[1]*(xi[0]-xi[1]) -3.0*c[2]*2.0*xi[2]*xi[0]*xi[1] - 3.0*xi[2]*xi[2]*(c[1])*(xi[2] + 4.0*xi[0] + 4.0*xi[1]) - 3.0*xi[2]*xi[2]*(c[1]*xi[0] -c[0]*xi[1])*(4.0) - xi[2]*xi[2]*xi[2]*(c[1]) -15.0*2.0*xi[2]*xi[1]*(c[1]*lamb[1]*xi[0] -c[0]*lamb_p[0]*xi[1]) -15.0*2.0*xi[2]*xi[0]*xi[1]*(c[1]*lamb[1]);
933  psi2(2,3,4) = 1.0/2.0*3.0*xi[2]*xi[2]*(b[1]*b[1]*2.0*xi[0]) + 2.0*xi[2]*xi[1]*(-b[0]*b[1]*xi[2] + b[1]*b[2]*xi[0] + b[2]*b[0]*xi[1]) + 2.0*xi[2]*xi[0]*xi[1]*(b[1]*b[2])
934  + 5.0/2.0*2.0*xi[2]*xi[1]*(b[1]*b[1]*lamb[1]*xi[0] + b[0]*b[0]*lamb_p[0]*xi[1])+ 5.0/2.0*2.0*xi[2]*xi[0]*xi[1]*(b[1]*b[1]*lamb[1]) + xi[2]*xi[2]*xi[1]*(-b[0])*b[1];
935  psi2(2,4,4) = 1.0/2.0*3.0*xi[2]*xi[2]*(c[1]*c[1]*2.0*xi[0]) + 2.0*xi[2]*xi[1]*(-c[0]*c[1]*xi[2] + c[1]*c[2]*xi[0] + c[2]*c[0]*xi[1]) + 2.0*xi[2]*xi[0]*xi[1]*(c[1]*c[2])
936  + 5.0/2.0*2.0*xi[2]*xi[1]*(c[1]*c[1]*lamb[1]*xi[0] + c[0]*c[0]*lamb_p[0]*xi[1])+ 5.0/2.0*2.0*xi[2]*xi[0]*xi[1]*(c[1]*c[1]*lamb[1])+ xi[2]*xi[2]*xi[1]*(-c[0])*c[1];
937  psi2(2,5,4) = b[2]*c[2]*2.0*xi[2]*xi[1]*(xi[2] + xi[0] + xi[1]) + b[2]*c[2]*2.0*xi[2]*xi[0]*xi[1] + b[2]*c[2]*xi[2]*xi[2]*xi[1] + b[0]*c[0]*2.0*xi[2]*xi[1]*(xi[1] - xi[2] - 2.0*xi[0]) + b[0]*c[0]*xi[2]*xi[2]*xi[1]*(-1.0) + b[1]*c[1]*2.0*xi[2]*(xi[0]*xi[1] - xi[1]*xi[2] -xi[2]*xi[0] - xi[1]*xi[1])+ b[1]*c[1]*2.0*xi[2]*xi[0]*(xi[1] -xi[2]) + b[1]*c[1]*xi[2]*xi[2]*(- xi[1]-xi[0])+ b[1]*c[1]*xi[2]*xi[2]*xi[0]*(-1.0) - 5.0*2.0*xi[2]*xi[1]*(b[0]*c[0]*lamb_p[0]*xi[1] + b[1]*c[1]*lamb[1]*xi[0])- 5.0*2.0*xi[2]*xi[0]*xi[1]*(b[1]*c[1]*lamb[1]);
938 
939  // compute for the second derivatives wrt area coordinate1 and 2
940  psi2(2,0,5) = 5.0*4.0*xi[2]*xi[2]*xi[2] + 10.0*3.0*xi[2]*xi[2]*2.0*(xi[0]+xi[1]) + 30.0*2.0*xi[2]*xi[0]*(lamb[1]*xi[0] + lamb_p[0]*xi[1]) + 60.0*lamb_p[0]*xi[0]*xi[1]*xi[2];
941  psi2(2,1,5) = 3.0*b[2]*2.0*xi[2]*xi[0]*xi[1]*(-1.0) + 3.0*b[2]*2.0*xi[2]*xi[0]*(xi[0]-xi[1]) + 12.0*xi[2]*xi[2]*(b[1]*xi[0] -b[0]*xi[1])+ 3.0*xi[2]*xi[2]*(-b[0])*(xi[2] + 4.0*xi[0] + 4*xi[1])+ xi[2]*xi[2]*xi[2]*(-b[0]) + 15*2.0*xi[2]*xi[0]*xi[1]*(- b[0]*lamb_p[0]) + 15*2.0*xi[2]*xi[0]*(b[1]*lamb[1]*xi[0] - b[0]*lamb_p[0]*xi[1]);
942  psi2(2,2,5) = 3.0*c[2]*2.0*xi[2]*xi[0]*xi[1] + -3.0*c[2]*2.0*xi[2]*xi[0]*(xi[0]-xi[1]) - 3.0*xi[2]*xi[2]*(c[1]*xi[0] - c[0]*xi[1])*( 4.0) + 3.0*xi[2]*xi[2]*(c[0])*(xi[2] + 4.0*xi[0] + 4.0*xi[1]) + xi[2]*xi[2]*xi[2]*(c[0]) + 15.0*2.0*xi[2]*xi[0]*xi[1]*(c[0]*lamb_p[0]) -15.0*2.0*xi[2]*xi[0]*(c[1]*lamb[1]*xi[0] -c[0]*lamb_p[0]*xi[1]);
943  psi2(2,3,5) = 1.0/2.0*3.0*xi[2]*xi[2]*(b[0]*b[0]*2.0*xi[1]) + 2.0*xi[2]*xi[0]*xi[1]*( b[2]*b[0]) + 2.0*xi[2]*xi[0]*(-b[0]*b[1]*xi[2] + b[1]*b[2]*xi[0] + b[2]*b[0]*xi[1])+ xi[2]*xi[2]*xi[0]*(-b[0]*b[1]) + 5.0/2.0*2.0*xi[2]*xi[0]*xi[1]*( b[0]*b[0]*lamb_p[0])+ 5.0/2.0*2.0*xi[2]*xi[0]*(b[1]*b[1]*lamb[1]*xi[0] + b[0]*b[0]*lamb_p[0]*xi[1]);
944  psi2(2,4,5) = 3.0*xi[2]*xi[2]*(c[0]*c[0]*xi[1]) + 2.0*xi[2]*xi[0]*xi[1]*(c[2]*c[0]) + 2.0*xi[2]*xi[0]*(-c[0]*c[1]*xi[2] + c[1]*c[2]*xi[0] + c[2]*c[0]*xi[1]) + xi[2]*xi[2]*xi[0]*(-c[0]*c[1]) + 5.0/2.0*2.0*xi[2]*xi[0]*xi[1]*(c[0]*c[0]*lamb_p[0]) + 5.0/2.0*2.0*xi[2]*xi[0]*(c[1]*c[1]*lamb[1]*xi[0] + c[0]*c[0]*lamb_p[0]*xi[1]);
945  psi2(2,5,5) = b[2]*c[2]*2.0*xi[2]*xi[0]*xi[1] + b[2]*c[2]*2.0*xi[2]*xi[0]*(xi[2] + xi[0] + xi[1]) + b[2]*c[2]*xi[2]*xi[2]*xi[0] + b[0]*c[0]*xi[2]*xi[2]*xi[1]*(-1.0)+ b[0]*c[0]*2.0*xi[2]*xi[1]*(xi[0] - xi[2]) + b[0]*c[0]*2.0*xi[2]*(xi[0]*xi[1] - xi[1]*xi[2] - xi[2]*xi[0] - xi[0]*xi[0]) + b[0]*c[0]*xi[2]*xi[2]*( -xi[1] -xi[0]) + b[1]*c[1]*2.0*xi[2]*xi[0]*(xi[0] - xi[2] - 2.0*xi[1]) + b[1]*c[1]*xi[2]*xi[2]*xi[0]*(-1.0) - 5.0*2.0*xi[2]*xi[0]*xi[1]*(b[0]*c[0]*lamb_p[0]) - 5.0*2.0*xi[2]*xi[0]*(b[0]*c[0]*lamb_p[0]*xi[1] + b[1]*c[1]*lamb[1]*xi[0]);
946 
947  // by chain rule, we can obtain d2shape wrt s0s0 at node2
948  d2psids(2,0,0) = (psi2(2,0,0)*dxids0[0] + psi2(2,0,3)*dxids0[1] + psi2(2,0,4)*dxids0[2])*dxids0[0] +
949  (psi2(2,0,3)*dxids0[0] + psi2(2,0,1)*dxids0[1] + psi2(2,0,5)*dxids0[2])*dxids0[1] +
950  (psi2(2,0,4)*dxids0[0] + psi2(2,0,5)*dxids0[1] + psi2(2,0,2)*dxids0[2])*dxids0[2];
951  d2psids(2,1,0) = (psi2(2,1,0)*dxids0[0] + psi2(2,1,3)*dxids0[1] + psi2(2,1,4)*dxids0[2])*dxids0[0] +
952  (psi2(2,1,3)*dxids0[0] + psi2(2,1,1)*dxids0[1] + psi2(2,1,5)*dxids0[2])*dxids0[1] +
953  (psi2(2,1,4)*dxids0[0] + psi2(2,1,5)*dxids0[1] + psi2(2,1,2)*dxids0[2])*dxids0[2];
954  d2psids(2,2,0) = (psi2(2,2,0)*dxids0[0] + psi2(2,2,3)*dxids0[1] + psi2(2,2,4)*dxids0[2])*dxids0[0] +
955  (psi2(2,2,3)*dxids0[0] + psi2(2,2,1)*dxids0[1] + psi2(2,2,5)*dxids0[2])*dxids0[1] +
956  (psi2(2,2,4)*dxids0[0] + psi2(2,2,5)*dxids0[1] + psi2(2,2,2)*dxids0[2])*dxids0[2];
957  d2psids(2,3,0) = (psi2(2,3,0)*dxids0[0] + psi2(2,3,3)*dxids0[1] + psi2(2,3,4)*dxids0[2])*dxids0[0] +
958  (psi2(2,3,3)*dxids0[0] + psi2(2,3,1)*dxids0[1] + psi2(2,3,5)*dxids0[2])*dxids0[1] +
959  (psi2(2,3,4)*dxids0[0] + psi2(2,3,5)*dxids0[1] + psi2(2,3,2)*dxids0[2])*dxids0[2];
960  d2psids(2,4,0) = (psi2(2,4,0)*dxids0[0] + psi2(2,4,3)*dxids0[1] + psi2(2,4,4)*dxids0[2])*dxids0[0] +
961  (psi2(2,4,3)*dxids0[0] + psi2(2,4,1)*dxids0[1] + psi2(2,4,5)*dxids0[2])*dxids0[1] +
962  (psi2(2,4,4)*dxids0[0] + psi2(2,4,5)*dxids0[1] + psi2(2,4,2)*dxids0[2])*dxids0[2];
963  d2psids(2,5,0) = (psi2(2,5,0)*dxids0[0] + psi2(2,5,3)*dxids0[1] + psi2(2,5,4)*dxids0[2])*dxids0[0] +
964  (psi2(2,5,3)*dxids0[0] + psi2(2,5,1)*dxids0[1] + psi2(2,5,5)*dxids0[2])*dxids0[1] +
965  (psi2(2,5,4)*dxids0[0] + psi2(2,5,5)*dxids0[1] + psi2(2,5,2)*dxids0[2])*dxids0[2];
966 
967  // by chain rule, we can obtain d2shape wrt s1s1 at node2
968  d2psids(2,0,1) = (psi2(2,0,0)*dxids1[0] + psi2(2,0,3)*dxids1[1] + psi2(2,0,4)*dxids1[2])*dxids1[0] +
969  (psi2(2,0,3)*dxids1[0] + psi2(2,0,1)*dxids1[1] + psi2(2,0,5)*dxids1[2])*dxids1[1] +
970  (psi2(2,0,4)*dxids1[0] + psi2(2,0,5)*dxids1[1] + psi2(2,0,2)*dxids1[2])*dxids1[2];
971  d2psids(2,1,1) = (psi2(2,1,0)*dxids1[0] + psi2(2,1,3)*dxids1[1] + psi2(2,1,4)*dxids1[2])*dxids1[0] +
972  (psi2(2,1,3)*dxids1[0] + psi2(2,1,1)*dxids1[1] + psi2(2,1,5)*dxids1[2])*dxids1[1] +
973  (psi2(2,1,4)*dxids1[0] + psi2(2,1,5)*dxids1[1] + psi2(2,1,2)*dxids1[2])*dxids1[2];
974  d2psids(2,2,1) = (psi2(2,2,0)*dxids1[0] + psi2(2,2,3)*dxids1[1] + psi2(2,2,4)*dxids1[2])*dxids1[0] +
975  (psi2(2,2,3)*dxids1[0] + psi2(2,2,1)*dxids1[1] + psi2(2,2,5)*dxids1[2])*dxids1[1] +
976  (psi2(2,2,4)*dxids1[0] + psi2(2,2,5)*dxids1[1] + psi2(2,2,2)*dxids1[2])*dxids1[2];
977  d2psids(2,3,1) = (psi2(2,3,0)*dxids1[0] + psi2(2,3,3)*dxids1[1] + psi2(2,3,4)*dxids1[2])*dxids1[0] +
978  (psi2(2,3,3)*dxids1[0] + psi2(2,3,1)*dxids1[1] + psi2(2,3,5)*dxids1[2])*dxids1[1] +
979  (psi2(2,3,4)*dxids1[0] + psi2(2,3,5)*dxids1[1] + psi2(2,3,2)*dxids1[2])*dxids1[2];
980  d2psids(2,4,1) = (psi2(2,4,0)*dxids1[0] + psi2(2,4,3)*dxids1[1] + psi2(2,4,4)*dxids1[2])*dxids1[0] +
981  (psi2(2,4,3)*dxids1[0] + psi2(2,4,1)*dxids1[1] + psi2(2,4,5)*dxids1[2])*dxids1[1] +
982  (psi2(2,4,4)*dxids1[0] + psi2(2,4,5)*dxids1[1] + psi2(2,4,2)*dxids1[2])*dxids1[2];
983  d2psids(2,5,1) = (psi2(2,5,0)*dxids1[0] + psi2(2,5,3)*dxids1[1] + psi2(2,5,4)*dxids1[2])*dxids1[0] +
984  (psi2(2,5,3)*dxids1[0] + psi2(2,5,1)*dxids1[1] + psi2(2,5,5)*dxids1[2])*dxids1[1] +
985  (psi2(2,5,4)*dxids1[0] + psi2(2,5,5)*dxids1[1] + psi2(2,5,2)*dxids1[2])*dxids1[2];
986 
987  // by chain rule, we can obtain d2shape wrt s0s1 at node2
988  d2psids(2,0,2) = (psi2(2,0,0)*dxids0[0] + psi2(2,0,3)*dxids0[1] + psi2(2,0,4)*dxids0[2])*dxids1[0] +
989  (psi2(2,0,3)*dxids0[0] + psi2(2,0,1)*dxids0[1] + psi2(2,0,5)*dxids0[2])*dxids1[1] +
990  (psi2(2,0,4)*dxids0[0] + psi2(2,0,5)*dxids0[1] + psi2(2,0,2)*dxids0[2])*dxids1[2];
991  d2psids(2,1,2) = (psi2(2,1,0)*dxids0[0] + psi2(2,1,3)*dxids0[1] + psi2(2,1,4)*dxids0[2])*dxids1[0] +
992  (psi2(2,1,3)*dxids0[0] + psi2(2,1,1)*dxids0[1] + psi2(2,1,5)*dxids0[2])*dxids1[1] +
993  (psi2(2,1,4)*dxids0[0] + psi2(2,1,5)*dxids0[1] + psi2(2,1,2)*dxids0[2])*dxids1[2];
994  d2psids(2,2,2) = (psi2(2,2,0)*dxids0[0] + psi2(2,2,3)*dxids0[1] + psi2(2,2,4)*dxids0[2])*dxids1[0] +
995  (psi2(2,2,3)*dxids0[0] + psi2(2,2,1)*dxids0[1] + psi2(2,2,5)*dxids0[2])*dxids1[1] +
996  (psi2(2,2,4)*dxids0[0] + psi2(2,2,5)*dxids0[1] + psi2(2,2,2)*dxids0[2])*dxids1[2];
997  d2psids(2,3,2) = (psi2(2,3,0)*dxids0[0] + psi2(2,3,3)*dxids0[1] + psi2(2,3,4)*dxids0[2])*dxids1[0] +
998  (psi2(2,3,3)*dxids0[0] + psi2(2,3,1)*dxids0[1] + psi2(2,3,5)*dxids0[2])*dxids1[1] +
999  (psi2(2,3,4)*dxids0[0] + psi2(2,3,5)*dxids0[1] + psi2(2,3,2)*dxids0[2])*dxids1[2];
1000  d2psids(2,4,2) = (psi2(2,4,0)*dxids0[0] + psi2(2,4,3)*dxids0[1] + psi2(2,4,4)*dxids0[2])*dxids1[0] +
1001  (psi2(2,4,3)*dxids0[0] + psi2(2,4,1)*dxids0[1] + psi2(2,4,5)*dxids0[2])*dxids1[1] +
1002  (psi2(2,4,4)*dxids0[0] + psi2(2,4,5)*dxids0[1] + psi2(2,4,2)*dxids0[2])*dxids1[2];
1003  d2psids(2,5,2) = (psi2(2,5,0)*dxids0[0] + psi2(2,5,3)*dxids0[1] + psi2(2,5,4)*dxids0[2])*dxids1[0] +
1004  (psi2(2,5,3)*dxids0[0] + psi2(2,5,1)*dxids0[1] + psi2(2,5,5)*dxids0[2])*dxids1[1] +
1005  (psi2(2,5,4)*dxids0[0] + psi2(2,5,5)*dxids0[1] + psi2(2,5,2)*dxids0[2])*dxids1[2];
1006  }
1007  };
1008 
1009 ///////////////////////////////////////////////////////////////////////////
1010 ///////////////////////////////////////////////////////////////////////////
1011 // C1CurvedElementsShape
1012 ///////////////////////////////////////////////////////////////////////////
1013 ///////////////////////////////////////////////////////////////////////////
1014 //========================================================================
1015 /// A class for Linear triangular shape function with 3 vertex nodes
1016 //========================================================================
1017 template<unsigned DIM>
1018  class LinearTElement { };
1019 
1020 template<>
1022  {
1023  public:
1024 //=======================================================================
1025 /// Return local coordinates of node j
1026 //=======================================================================
1027  void local_coordinate_of_node(const unsigned& j,
1028  Vector<double>& s) const
1029  {
1030  switch (j)
1031  {
1032  case 0:
1033  s[0]=1.0;
1034  s[1]=0.0;
1035  break;
1036 
1037  case 1:
1038  s[0]=0.0;
1039  s[1]=1.0;
1040  break;
1041 
1042  case 2:
1043  s[0]=0.0;
1044  s[1]=0.0;
1045  break;
1046 
1047  default:
1048  std::ostringstream error_message;
1049  error_message << "Element only has three nodes; called with node number "
1050  << j << std::endl;
1051 
1052  throw OomphLibError(error_message.str(),
1053  "TElement::local_coordinate_of_node()",
1054  OOMPH_EXCEPTION_LOCATION);
1055  }
1056  }
1057 
1058 
1059 //=======================================================================
1060 /// Shape function for specific TElement<2,2>
1061 //=======================================================================
1062  void Lshape(const Vector<double> &s, Shape &psi) const
1063  {
1064  psi[0] = s[0];
1065  psi[1] = s[1];
1066  psi[2] = 1.0-s[0]-s[1];
1067  }
1068 
1069 
1070 //=======================================================================
1071 /// Derivatives of shape functions for specific TElement<2,2>
1072 //=======================================================================
1074  Shape &psi, DShape &dpsids) const
1075  {
1076  this->Lshape(s, psi);
1077 
1078  // Derivatives
1079  dpsids(0,0) = 1.0;
1080  dpsids(0,1) = 0.0;
1081  dpsids(1,0) = 0.0;
1082  dpsids(1,1) = 1.0;
1083  dpsids(2,0) = -1.0;
1084  dpsids(2,1) = -1.0;
1085  }
1086 
1087 
1088 //=======================================================================
1089 /// Second derivatives of shape functions for specific TElement<2,2>:
1090  /// d2psids(i,0) = \f$ \partial^2 \psi_j / \partial s_0^2 \f$ \n
1091  /// d2psids(i,1) = \f$ \partial^2 \psi_j / \partial s_1^2 \f$ \n
1092  /// d2psids(i,2) = \f$ \partial^2 \psi_j / \partial s_0 \partial s_1 \f$ \n
1093 //=======================================================================
1095  Shape &psi,
1096  DShape &dpsids,
1097  DShape &d2psids) const
1098  {
1099  this->dLshape_local(s, psi,dpsids);
1100 
1101  for(unsigned i=0;i<3;i++)
1102  {
1103  d2psids(i,0) = 0.0;
1104  d2psids(i,1) = 0.0;
1105  d2psids(i,2) = 0.0;
1106  }
1107  }
1108  };
1109 
1110 //=====================================================================
1111 /// Define integration schemes that are required to exactly integrate
1112 /// the mass matrices of the bubble-enriched elements. The enrichement
1113 /// increases the polynomial order which means that higher-order Gauss
1114 /// rules must be used.
1115 //====================================================================
1116 template<unsigned DIM, unsigned NNODE_1D>
1118 {
1119 };
1120 
1121 //====================================================================
1122 ///Specialisation for two-dimensional elements, in which the highest
1123 ///order polynomial is cubic, so we need the integration scheme
1124 ///for the unenriched cubic element
1125 //======================================================================
1126 template<>
1127 class CurvedTGauss<2,2> : public TGauss<2,4>
1128 {
1129  public:
1130  CurvedTGauss() : TGauss<2,4>() {}
1131 };
1132 
1133 //========================================================================
1134 /// A class for subparametric shape functions of
1135 /// a curved triangular element with 3 vertex nodes
1136 /// Affine mapping is used when dealing with a straight-boundary element
1137 /// Nonlinear mapping is used when dealing with a curved-boundary element
1138 /// Note that a cubic-Hermite polynomial is employed to approximate a
1139 /// curved boundary
1140 //========================================================================
1141 template<unsigned DIM>
1143 
1144 template<>
1146  {
1147  public:
1148 //=======================================================================
1149 /// Return local coordinates of node j
1150 //=======================================================================
1151  void local_coordinate_of_node(const unsigned& j,
1152  Vector<double>& s) const
1153  {
1154  switch (j)
1155  {
1156  case 0:
1157  s[0]=1.0;
1158  s[1]=0.0;
1159  break;
1160 
1161  case 1:
1162  s[0]=0.0;
1163  s[1]=1.0;
1164  break;
1165 
1166  case 2:
1167  s[0]=0.0;
1168  s[1]=0.0;
1169  break;
1170 
1171  default:
1172  std::ostringstream error_message;
1173  error_message << "Element only has three nodes; called with node number "
1174  << j << std::endl;
1175 
1176  throw OomphLibError(error_message.str(),
1177  "GeometricTElement::local_coordinate_of_node()",
1178  OOMPH_EXCEPTION_LOCATION);
1179  }
1180  }
1181 //=======================================================================
1182 /// Geometric interpolation for specific C1CurvedElement<>
1183 /// This function return the physical coordinates at the local coordinate s
1184 /// rather than a value of shape function at the local coordinate s
1185 //=======================================================================
1186  void Lshape(const Vector<double> &s, Shape &psi, Shape &phi, DenseMatrix<double> &position,
1187  unsigned &bd_element, DenseMatrix<double> &bd_position, Vector<double> &x) const
1188  {
1189  // assign shape functions to the interior elements
1190  psi[0] = s[0];
1191  psi[1] = s[1];
1192  psi[2] = 1.0-s[0]-s[1];
1193 
1194  // assign shape functions to the boundary elements
1195  double angle_1 = atan2(bd_position(0,1),bd_position(0,0));
1196  double angle_2 = atan2(bd_position(1,1),bd_position(1,0));
1197  double angle_min=0.0;
1198  double angle_max=0.0;
1199 
1200  DenseMatrix<double> p(3,2);
1201  if(angle_1 < angle_2)
1202  {
1203  angle_min = angle_1;
1204  angle_max = angle_2;
1205 
1206  p(0,0) = bd_position(0,0);
1207  p(0,1) = bd_position(0,1);
1208 
1209  p(1,0) = bd_position(1,0);
1210  p(1,1) = bd_position(1,1);
1211  }
1212  else if(angle_1 > angle_2)
1213  {
1214  angle_min = angle_2;
1215  angle_max = angle_1;
1216 
1217  p(0,0) = bd_position(1,0);
1218  p(0,1) = bd_position(1,1);
1219 
1220  p(1,0) = bd_position(0,0);
1221  p(1,1) = bd_position(0,1);
1222  }
1223 
1224  Vector<double> b_fn_derivative_min(2), b_fn_derivative_max(2);
1225  b_fn_derivative_min[0] = -1.0*sin(angle_min);
1226  b_fn_derivative_min[1] = cos(angle_min);
1227  b_fn_derivative_max[0] = -1.0*sin(angle_max);
1228  b_fn_derivative_max[1] = cos(angle_max);
1229 
1230  // compute the physical coordinates at the local coordinate s
1231  if(bd_element == 0)
1232  {
1233  phi[0] = position(2,0) + (position(0,0) - position(2,0))*s[0] + (position(1,0) - position(2,0))*s[1];
1234  phi[1] = position(2,1) + (position(0,1) - position(2,1))*s[0] + (position(1,1) - position(2,1))*s[1];
1235  }
1236  else
1237  {
1238  Vector<double> psi_h(2);
1239  for(unsigned i=0;i<2;i++)
1240  {
1241  // polynomial of degree 3 to approximate boundary
1242  psi_h[i] = ( (2.0*(p(1,i)-p(0,i))-(angle_max-angle_min)*(b_fn_derivative_min[i]+b_fn_derivative_max[i]))*(s[1]-s[0]) + (angle_max-angle_min)*(b_fn_derivative_min[i]-b_fn_derivative_max[i]) );
1243  phi[i] = x[i] + (p(0,i) - x[i])*s[0] + (p(1,i) - x[i])*s[1] + 1.0/2.0*s[0]*s[1]*psi_h[i];
1244  }
1245  }
1246  }
1247 
1248 
1249 //=======================================================================
1250 /// Derivatives of Geometric interpolation for specific C1CurvedElement<>
1251 /// This function return the derivatives of physical coordinates at
1252 /// the local coordinate s rather than a value of the derivatives of
1253 /// shape function at the local coordinate s
1254 //=======================================================================
1256  Shape &psi, DShape &dpsids, Shape &phi, DShape &dphids, DenseMatrix<double> &position,
1257  unsigned &bd_element, DenseMatrix<double> &bd_position, Vector<double> &x) const
1258  {
1259  this->Lshape(s,psi,phi,position,bd_element,bd_position,x);
1260  // Derivatives
1261  dpsids(0,0) = 1.0;
1262  dpsids(0,1) = 0.0;
1263  dpsids(1,0) = 0.0;
1264  dpsids(1,1) = 1.0;
1265  dpsids(2,0) = -1.0;
1266  dpsids(2,1) = -1.0;
1267 
1268  double angle_1 = atan2(bd_position(0,1),bd_position(0,0));
1269  double angle_2 = atan2(bd_position(1,1),bd_position(1,0));
1270  double angle_min=0.0;
1271  double angle_max=0.0;
1272 
1273  DenseMatrix<double> p(3,2);
1274  if(angle_1 < angle_2)
1275  {
1276  angle_min = angle_1;
1277  angle_max = angle_2;
1278 
1279  p(0,0) = bd_position(0,0);
1280  p(0,1) = bd_position(0,1);
1281 
1282  p(1,0) = bd_position(1,0);
1283  p(1,1) = bd_position(1,1);
1284  }
1285  else if(angle_1 > angle_2)
1286  {
1287  angle_min = angle_2;
1288  angle_max = angle_1;
1289 
1290  p(0,0) = bd_position(1,0);
1291  p(0,1) = bd_position(1,1);
1292 
1293  p(1,0) = bd_position(0,0);
1294  p(1,1) = bd_position(0,1);
1295  }
1296 
1297  Vector<double> b_fn_derivative_min(2), b_fn_derivative_max(2);
1298  b_fn_derivative_min[0] = -1.0*sin(angle_min);
1299  b_fn_derivative_min[1] = cos(angle_min);
1300  b_fn_derivative_max[0] = -1.0*sin(angle_max);
1301  b_fn_derivative_max[1] = cos(angle_max);
1302 
1303  // compute shape functions
1304  if(bd_element == 0)
1305  {
1306  dphids(0,0) = position(0,0) - position(2,0);
1307  dphids(0,1) = position(1,0) - position(2,0);
1308  dphids(1,0) = position(0,1) - position(2,1);
1309  dphids(1,1) = position(1,1) - position(2,1);
1310  }
1311  else
1312  {
1313  Vector<double> psi_h(2);
1314  for(unsigned i=0;i<2;i++)
1315  {
1316  psi_h[i] = ( (2.0*(p(1,i)-p(0,i))-(angle_max-angle_min)*(b_fn_derivative_min[i]+b_fn_derivative_max[i]))*(s[1]-s[0]) + (angle_max-angle_min)*(b_fn_derivative_min[i]-b_fn_derivative_max[i]) );
1317  }
1318  // compute shape functions derivatives
1319  DenseMatrix<double> dpsi_h(2,2);
1320  for(unsigned i=0;i<2;i++)
1321  {
1322  dpsi_h(i,0) = (2.0*(p(1,i)-p(0,i))-(angle_max-angle_min)*(b_fn_derivative_min[i]+b_fn_derivative_max[i]))*(-1.0);
1323  dpsi_h(i,1) = (2.0*(p(1,i)-p(0,i))-(angle_max-angle_min)*(b_fn_derivative_min[i]+b_fn_derivative_max[i]));
1324  }
1325  for(unsigned i=0;i<2;i++)
1326  {
1327  dphids(i,0) = p(0,i) - x[i] + 1.0/2.0*s[0]*s[1]*dpsi_h(i,0) + psi_h[i]*s[1]/2.0 ;
1328  dphids(i,1) = p(1,i) - x[i] + 1.0/2.0*s[0]*s[1]*dpsi_h(i,1) + psi_h[i]*s[0]/2.0 ;
1329  }
1330  }
1331  }
1332 
1333 //=======================================================================
1334 /// Second derivatives of Geometric interpolation for
1335 /// specific C1CurvedElement<>:
1336 /// This function return the second-order derivatives of physical coordinates at
1337 /// the local coordinate s rather than a value of the second-order derivatives of
1338 /// shape function at the local coordinate s
1339 ///=======================================================================
1341  Shape &psi,
1342  DShape &dpsids,
1343  DShape &d2psids,
1344  Shape &phi,
1345  DShape &dphids,
1346  DShape &d2phids,
1347  DenseMatrix<double> &position,
1348  unsigned &bd_element,
1349  DenseMatrix<double> &bd_position,
1350  Vector<double> &x) const
1351  {
1352  this->dLshape_local(s,psi,dpsids,phi,dphids,position,bd_element,bd_position,x);
1353  // 2nd Derivatives
1354  for(unsigned i=0;i<3;i++)
1355  {
1356  d2psids(i,0) = 0.0;
1357  d2psids(i,1) = 0.0;
1358  d2psids(i,2) = 0.0;
1359  }
1360  double angle_1 = atan2(bd_position(0,1),bd_position(0,0));
1361  double angle_2 = atan2(bd_position(1,1),bd_position(1,0));
1362  double angle_min=0.0;
1363  double angle_max=0.0;
1364 
1365  DenseMatrix<double> p(3,2);
1366  if(angle_1 < angle_2)
1367  {
1368  angle_min = angle_1;
1369  angle_max = angle_2;
1370 
1371  p(0,0) = bd_position(0,0);
1372  p(0,1) = bd_position(0,1);
1373 
1374  p(1,0) = bd_position(1,0);
1375  p(1,1) = bd_position(1,1);
1376  }
1377  else if(angle_1 > angle_2)
1378  {
1379  angle_min = angle_2;
1380  angle_max = angle_1;
1381 
1382  p(0,0) = bd_position(1,0);
1383  p(0,1) = bd_position(1,1);
1384 
1385  p(1,0) = bd_position(0,0);
1386  p(1,1) = bd_position(0,1);
1387  }
1388 
1389  Vector<double> b_fn_derivative_min(2), b_fn_derivative_max(2);
1390  b_fn_derivative_min[0] = -1.0*sin(angle_min);
1391  b_fn_derivative_min[1] = cos(angle_min);
1392  b_fn_derivative_max[0] = -1.0*sin(angle_max);
1393  b_fn_derivative_max[1] = cos(angle_max);
1394 
1395  // compute the 2nd-order of derivatives of the physical coordinates
1396  if(bd_element == 0)
1397  {
1398  for(unsigned i=0;i<2;i++)
1399  {
1400  d2phids(i,0) = 0.0;
1401  d2phids(i,1) = 0.0;
1402  d2phids(i,2) = 0.0;
1403  }
1404  }
1405  else
1406  {
1407  // compute the 2nd-order derivatives of the physical coordinates
1408  Vector<double> psi_h(2);
1409  DenseMatrix<double> dpsi_h(2,2), d2psi_h(2,3);
1410 
1411  for(unsigned i=0;i<2;i++)
1412  {
1413  psi_h[i] = ( (2.0*(p(1,i)-p(0,i))-(angle_max-angle_min)*(b_fn_derivative_min[i]+b_fn_derivative_max[i]))*(s[1]-s[0]) + (angle_max-angle_min)*(b_fn_derivative_min[i]-b_fn_derivative_max[i]) );
1414  }
1415 
1416  for(unsigned i=0;i<2;i++)
1417  {
1418  dpsi_h(i,0) = (2.0*(p(1,i)-p(0,i))-(angle_max-angle_min)*(b_fn_derivative_min[i]+b_fn_derivative_max[i]))*(-1.0);
1419  dpsi_h(i,1) = (2.0*(p(1,i)-p(0,i))-(angle_max-angle_min)*(b_fn_derivative_min[i]+b_fn_derivative_max[i]));
1420  }
1421 
1422  for(unsigned i=0;i<2;i++)
1423  {
1424  d2psi_h(i,0) = 0.0;
1425  d2psi_h(i,1) = 0.0;
1426  d2psi_h(i,2) = 0.0;
1427  }
1428 
1429  for(unsigned i=0;i<2;i++)
1430  {
1431  d2phids(i,0) = 1.0/2.0*s[0]*s[1]*d2psi_h(i,0) + dpsi_h(i,0)*s[1]/2.0 + 1.0/2.0*s[1]*dpsi_h(i,0);
1432  d2phids(i,1) = 1.0/2.0*s[0]*s[1]*d2psi_h(i,1) + 1.0/2.0*s[0]*dpsi_h(i,1) + 1.0/2.0*s[0]*dpsi_h(i,1);
1433  d2phids(i,2) = 1.0/2.0*s[0]*s[1]*d2psi_h(i,2) + 1.0/2.0*s[0]*dpsi_h(i,0) + psi_h[i]/2.0 + dpsi_h(i,1)*s[1]/2.0;
1434  }
1435  }
1436  }
1437  };
1438 
1439 //========================================================================
1440 /// A class for C1-curved triangular shape function with 3 vertex nodes and
1441 /// 3 middle-side node
1442 //========================================================================
1443 template<unsigned DIM, unsigned NNODE_1D>
1445 
1446  template<unsigned NNODE_1D>
1447  class C1CurvedElementShape<2,NNODE_1D>
1448  {
1449  public:
1450  //=======================================================================
1451  /// Return local coordinates of node j
1452  //=======================================================================
1453  void local_coordinate_of_node(const unsigned& j,
1454  Vector<double>& s) const
1455  {
1456  if(NNODE_1D == 2)
1457  {
1458  switch (j)
1459  {
1460  case 0:
1461  s[0]=1.0;
1462  s[1]=0.0;
1463  break;
1464 
1465  case 1:
1466  s[0]=0.0;
1467  s[1]=1.0;
1468  break;
1469 
1470  case 2:
1471  s[0]=0.0;
1472  s[1]=0.0;
1473  break;
1474 
1475  case 3:
1476  s[0]=1.0/2.0;
1477  s[1]=1.0/4.0;
1478  break;
1479 
1480  case 4:
1481  s[0]=1.0/4.0;
1482  s[1]=1.0/2.0;
1483  break;
1484 
1485  case 5:
1486  s[0]=1.0/4.0;
1487  s[1]=1.0/4.0;
1488  break;
1489 
1490  default:
1491  std::ostringstream error_message;
1492  error_message << "Element only has three vertices and three internal nodes; called with node number "
1493  << j << std::endl;
1494 
1495  throw OomphLibError(error_message.str(),
1496  "CurvedTElement::local_coordinate_of_node()",
1497  OOMPH_EXCEPTION_LOCATION);
1498  }
1499  }
1500 
1501  else if(NNODE_1D == 3)
1502  {
1503  switch (j)
1504  {
1505  case 0:
1506  s[0]=1.0;
1507  s[1]=0.0;
1508  break;
1509 
1510  case 1:
1511  s[0]=0.0;
1512  s[1]=1.0;
1513  break;
1514 
1515  case 2:
1516  s[0]=0.0;
1517  s[1]=0.0;
1518  break;
1519 
1520  case 3:
1521  s[0]=0.5;
1522  s[1]=0.5;
1523  break;
1524 
1525  case 4:
1526  s[0]=0.0;
1527  s[1]=0.5;
1528  break;
1529 
1530  case 5:
1531  s[0]=0.5;
1532  s[1]=0.0;
1533  break;
1534 
1535  case 6:
1536  s[0]=1.0/2.0;
1537  s[1]=1.0/4.0;
1538  break;
1539 
1540  case 7:
1541  s[0]=1.0/4.0;
1542  s[1]=1.0/2.0;
1543  break;
1544 
1545  case 8:
1546  s[0]=1.0/4.0;
1547  s[1]=1.0/4.0;
1548  break;
1549 
1550  default:
1551  std::ostringstream error_message;
1552  error_message << "Element has maximum of six nodes and three internal nodes; called with node number "
1553  << j << std::endl;
1554 
1555  throw OomphLibError(error_message.str(),
1556  "CurvedTElement::local_coordinate_of_node()",
1557  OOMPH_EXCEPTION_LOCATION);
1558  }
1559  }
1560  }
1561 
1562  ///============================================================
1563  /// compute for the set of value in the reference triangle
1564  ///============================================================
1566  unsigned &bd_element, DenseMatrix<double> &bd_position, Vector<double> &x) const
1567  {
1568  double angle_1 = atan2(bd_position(0,1),bd_position(0,0));
1569  double angle_2 = atan2(bd_position(1,1),bd_position(1,0));
1570  double angle_min=0.0;
1571  double angle_max=0.0;
1572 
1573  DenseMatrix<double> p(3,2);
1574  if(angle_1 < angle_2)
1575  {
1576  angle_min = angle_1;
1577  angle_max = angle_2;
1578 
1579  p(0,0) = bd_position(0,0);
1580  p(0,1) = bd_position(0,1);
1581 
1582  p(1,0) = bd_position(1,0);
1583  p(1,1) = bd_position(1,1);
1584  }
1585  else if(angle_1 > angle_2)
1586  {
1587  angle_min = angle_2;
1588  angle_max = angle_1;
1589 
1590  p(0,0) = bd_position(1,0);
1591  p(0,1) = bd_position(1,1);
1592 
1593  p(1,0) = bd_position(0,0);
1594  p(1,1) = bd_position(0,1);
1595  }
1596  p(2,0) = x[0];
1597  p(2,1) = x[1];
1598 
1599  Vector<double> fn_derivative1(2), fn_derivative2(2);
1600  fn_derivative1[0] = (angle_max-angle_min)*-1.0*sin(angle_min);
1601  fn_derivative1[1] = (angle_max-angle_min)*-1.0*sin(angle_max);
1602  fn_derivative2[0] = (angle_max-angle_min)*cos(angle_min);
1603  fn_derivative2[1] = (angle_max-angle_min)*cos(angle_max);
1604 
1605  // compute for the transformation matrix D from global to local coordinates
1606  //initialise the matrix first
1607  for(unsigned i=0;i<21;i++)
1608  {
1609  for(unsigned j=0;j<21;j++)
1610  {
1611  D(i,j) = 0.0;
1612  }
1613  }
1614  double x31, x23, x13, x32, y13 ,y31, y32, y23;
1615  x31 = p(2,0)-p(0,0);
1616  y31 = p(2,1)-p(0,1);
1617  x32 = p(2,0)-p(1,0);
1618  y32 = p(2,1)-p(1,1);
1619  x23 = p(1,0)-p(2,0);
1620  y23 = p(1,1)-p(2,1);
1621  x13 = p(0,0)-p(2,0);
1622  y13 = p(0,1)-p(2,1);
1623 
1624  // assign values to the matrix D
1625  D(0,0) = 1.0;
1626  D(1,1) = 1.0;
1627  D(2,2) = 1.0;
1628  D(3+0,3+0)=x31;
1629  D(3+0,3+1)=fn_derivative1[0];
1630  D(3+1,3+0)=y31;
1631  D(3+1,3+1)=fn_derivative2[0];
1632  // define submatrix d2
1633  D(5+0,5+0)=-1.0*fn_derivative1[1];
1634  D(5+0,5+1)=x32;
1635  D(5+1,5+0)=-1.0*fn_derivative2[1];
1636  D(5+1,5+1)=y32;
1637  // define submatrix d3
1638  D(7+0,7+0)=x23;
1639  D(7+0,7+1)=x13;
1640  D(7+1,7+0)=y23;
1641  D(7+1,7+1)=y13;
1642  // define submatrix d4
1643  D(9+0,9+0)=x31*x31;
1644  D(9+0,9+1)=fn_derivative1[0]*fn_derivative1[0];
1645  D(9+0,9+6)=x32*x32;
1646  D(9+1,9+0)=2.0*x31*y31;
1647  D(9+1,9+1)=2.0*fn_derivative1[0]*fn_derivative2[0];
1648  D(9+1,9+6)=2.0*x32*y32;
1649  D(9+2,9+0)=y31*y31;
1650  D(9+2,9+1)=fn_derivative2[0]*fn_derivative2[0];
1651  D(9+2,9+6)=y32*y32;
1652  D(9+3,9+2)=fn_derivative1[1]*fn_derivative1[1];
1653  D(9+3,9+3)=x32*x32;
1654  D(9+3,9+7)=x31*x31;
1655  D(9+4,9+2)=2.0*fn_derivative1[1]*fn_derivative2[1];
1656  D(9+4,9+3)=2.0*x32*y32;
1657  D(9+4,9+7)=2.0*x31*y31;
1658  D(9+5,9+2)=fn_derivative2[1]*fn_derivative2[1];
1659  D(9+5,9+3)=y32*y32;
1660  D(9+5,9+7)=y31*y31;
1661  D(9+6,9+4)=x32*x32;
1662  D(9+6,9+5)=x31*x31;
1663  D(9+6,9+8)=fn_derivative1[0]*fn_derivative1[1];
1664  D(9+7,9+4)=2.0*x32*y32;
1665  D(9+7,9+5)=2.0*x31*y31;
1666  D(9+7,9+8)=fn_derivative1[0]*fn_derivative2[1]+fn_derivative2[0]*fn_derivative1[1];
1667  D(9+8,9+4)=y32*y32;
1668  D(9+8,9+5)=y31*y31;
1669  D(9+8,9+8)=fn_derivative2[0]*fn_derivative2[1];
1670 
1671  D(18,18) = 1.0;
1672  D(19,19) = 1.0;
1673  D(20,20) = 1.0;
1674  //assign the matrix of transformation from the dofs on curved element to the dofs on reference element
1675  DenseMatrix<double> Bt(36,21);
1676  //Initialize the matrix
1677  for(unsigned i=0;i<36;i++)
1678  {
1679  for(unsigned j=0;j<21;j++)
1680  {
1681  Bt(i,j) = 0.0;
1682  }
1683  }
1684  // submatrix b1
1685  Bt(0,0)=1.0;
1686  Bt(1,1)=1.0;
1687  Bt(2,2)=1.0;
1688  // submatrix b2
1689  Bt(3+0,3+0)=-1.0;
1690  Bt(3+1,3+0)=-1.0;
1691  Bt(3+1,3+1)=1.0;
1692  Bt(3+2,3+2)=1.0;
1693  Bt(3+2,3+3)=-1.0;
1694  Bt(3+3,3+3)=-1.0;
1695  Bt(3+4,3+5)=1.0;
1696  Bt(3+5,3+4)=1.0;
1697  // submatrix b3
1698  double a1, a2, aa1, aa2, b1, b2, bb1, bb2, c1, c2, cc1, cc2;
1699  Vector<double> A1(2), A2(2), B1(2), B2(2), C1(2), C2(2);
1700  for(unsigned i=0;i<2;i++)
1701  {
1702  A1[i] = p(2,i)-p(0,i);
1703  B2[i] = p(2,i)-p(1,i);
1704  C1[i] = p(1,i)-p(2,i);
1705  C2[i] = p(0,i)-p(2,i);
1706  }
1707  A2[0] = (angle_max-angle_min)*-1.0*sin(angle_min);
1708  A2[1] = (angle_max-angle_min)*cos(angle_min);
1709  B1[0] = -1.0*(angle_max-angle_min)*-1.0*sin(angle_max);
1710  B1[1] = -1.0*(angle_max-angle_min)*cos(angle_max);
1711  double B2xA2, A1xA2, A1xB2, B1xA2, A1xB1, B1xA1, A2xB2, B1xB2;
1712  B2xA2 = B2[0]*A2[1]-B2[1]*A2[0];
1713  A1xA2 = A1[0]*A2[1]-A1[1]*A2[0];
1714  A1xB2 = A1[0]*B2[1]-A1[1]*B2[0];
1715  B1xA2 = B1[0]*A2[1]-B1[1]*A2[0];
1716  A1xB1 = A1[0]*B1[1]-A1[1]*B1[0];
1717  A2xB2 = A2[0]*B2[1]-A2[1]*B2[0];
1718  B1xA1 = B1[0]*A1[1]-B1[1]*A1[0];
1719  B1xB2 = B1[0]*B2[1]-B1[1]*B2[0];
1720  a1 = B2xA2/A1xA2 - 1.0;
1721  a2 = A1xB2/A1xA2;
1722  aa1 = -1.0*B1xA2/A1xA2;
1723  aa2 = -1.0*A1xB1/A1xA2;
1724  b1 = A1xB2/B1xB2;
1725  b2 = B1xA1/B1xB2 - 1.0;
1726  bb1 = A2xB2/B1xB2;
1727  bb2 = B1xA2/B1xB2;
1728  c1 = -1.0/a2;
1729  c2 = -1.0*bb1/b1;
1730  cc1 = aa2/a2;
1731  cc2 = -1.0/b1;
1732 
1733  Bt(9+1,3+0)=2.0*a1+aa1/2.0;
1734  Bt(9+2,3+0)=-1.0*(2.0*a1+aa1);
1735  Bt(9+1,3+1)=3.0/2.0+2.0*a2+aa2/2.0;
1736  Bt(9+2,3+1)=-1.0*(1.0+2.0*a2+aa2);
1737  Bt(9+3,3+2)=-1.0*(1.0+2.0*b1-bb1);
1738  Bt(9+4,3+2)=3.0/2.0+2.0*b1-bb1/2.0;
1739  Bt(9+3,3+3)=-1.0*(2.0*b2-bb2);
1740  Bt(9+4,3+3)=2.0*b2-bb2/2.0;
1741  Bt(9+7,3+4)=(c1+cc1)/2.0;
1742  Bt(9+7,3+5)=(c2+cc2)/2.0;
1743 
1744  Bt(9+0,9+0)=1.0;
1745  Bt(9+1,9+0)=1.0+(1.0+a1)/(2.0*a2);
1746  Bt(9+2,9+0)=1.0+(1.0+a1)/(a2);
1747  Bt(9+1,9+1)=(a2)/(2.0*(1.0+a1));
1748  Bt(9+2,9+1)=1.0+(a2)/(1.0+a1);
1749  Bt(9+3,9+2)=1.0+(b1)/(1.0+b2);
1750  Bt(9+4,9+2)=(b1)/(2.0*(1.0+b2));
1751  Bt(9+3,9+3)=1.0+(1.0+b2)/(b1);
1752  Bt(9+4,9+3)=1.0+(1.0+b2)/(2.0*b1);
1753  Bt(9+5,9+3)=1.0;
1754  Bt(9+7,9+4)=-1.0*(c1*cc1)/(c1*cc2+c2*cc1);
1755  Bt(9+8,9+4)=1.0;
1756  Bt(9+6,9+5)=1.0;
1757  Bt(9+7,9+5)=-1.0*(c2*cc2)/(c1*cc2+c2*cc1);
1758  Bt(9+1,9+6)=(-1.0)/(2.0*a2*(1.0+a1));
1759  Bt(9+2,9+6)=(-1.0)/(a2*(1.0+a1));
1760  Bt(9+3,9+7)=(-1.0)/(b1*(1.0+b2));
1761  Bt(9+4,9+7)=(-1.0)/(2.0*b1*(1.0+b2));
1762  Bt(9+7,9+8)=(-1.0)/(c1*cc2+c2*cc1);
1763 
1764  double ata1, ata2;
1765  // assign the points of perpendicular for the sides a1a3 nd a2a3
1766  Vector<double> s1(2), s2(2);
1767  // find the point that the point a1(on the boundary) is perpendicular to the vector a2a3
1768  double m = (p(1,1) - p(2,1))/(p(1,0) - p(2,0));
1769  double k = p(2,1) - m*p(2,0);
1770  s1[0] = ( (p(1,0) - p(2,0))*p(0,0) + (p(1,1) - p(2,1))*(p(0,1)-k) )/((p(1,0) - p(2,0)) + (p(1,1) - p(2,1))*m);
1771  s1[1] = m*s1[0] + k;
1772 
1773  if((p(1,0) - p(2,0))==0)
1774  {
1775  m = (p(1,0) - p(2,0))/(p(1,1) - p(2,1));
1776  k = p(2,0) - m*p(2,1);
1777  s1[1] = ( (p(1,0) - p(2,0))*(p(0,0)-k) + (p(1,1) - p(2,1))*(p(0,1)) )/((p(1,0) - p(2,0))*m + (p(1,1) - p(2,1)));
1778  s1[0] = m*s1[1] + k;
1779  }
1780 
1781  // find the point that the point a2(on the boundary) is perpendicular to the vector a1a3
1782  m = (p(0,1) - p(2,1))/(p(0,0) - p(2,0));
1783  k = p(2,1) - m*p(2,0);
1784  s2[0] = ( (p(0,0) - p(2,0))*p(1,0) + (p(0,1) - p(2,1))*(p(1,1)-k) )/((p(0,0) - p(2,0)) + (p(0,1) - p(2,1))*m);
1785  s2[1] = m*s2[0] + k;
1786 
1787  if((p(0,0) - p(2,0))==0)
1788  {
1789  m = (p(0,0) - p(2,0))/(p(0,1) - p(2,1));
1790  k = p(2,0) - m*p(2,1);
1791  s2[1] = ( (p(0,0) - p(2,0))*(p(1,0)-k) + (p(0,1) - p(2,1))*(p(1,1)) )/((p(0,0) - p(2,0))*m + (p(0,1) - p(2,1)));
1792  s2[0] = m*s2[1] + k;
1793  }
1794 
1795  double len1, len2, len3;
1796  len1 = sqrt((p(1,0)-p(2,0))*(p(1,0)-p(2,0)) + (p(1,1)-p(2,1))*(p(1,1)-p(2,1)) );
1797  len2 = sqrt((p(0,0)-p(2,0))*(p(0,0)-p(2,0)) + (p(0,1)-p(2,1))*(p(0,1)-p(2,1)) );
1798  len3 = sqrt((p(1,0)-p(0,0))*(p(1,0)-p(0,0)) + (p(1,1)-p(0,1))*(p(1,1)-p(0,1)) );
1799  ata1 = (len3*len3-len2*len2)/(len1*len1);
1800  ata2 = (len1*len1-len3*len3)/(len2*len2);
1801 
1802  Vector<double> F1(21,0.0), F2(21,0.0), F3(21,0.0), H1(21,0.0), H2(21,0.0), H3(21,0.0);
1803  DenseMatrix<double> F1_div(21,2,0.0), F2_div(21,2,0.0);
1804  //Initialize the Vectors
1805  for(unsigned i=0;i<21;i++)
1806  {
1807  F1[i] = 0.0;
1808  F2[i] = 0.0;
1809  F3[i] = 0.0;
1810  H1[i] = 0.0;
1811  H2[i] = 0.0;
1812  H3[i] = 0.0;
1813  for(unsigned j=0;j<2;j++)
1814  {
1815  F1_div(i,j) = 0;
1816  F2_div(i,j) = 0;
1817  }
1818  }
1819  double e1,e2,f1,f2;
1820  double magnitude;
1821  Vector<double> t(2,0.0),aa(2,0.0),s(2,0.0);
1822 
1823  t[0] = p(2,0)-p(0,0) + 1.0/4.0*(p(0,0)-p(1,0))+1.0/8.0*(angle_max-angle_min)*(-3.0*sin(angle_max)+sin(angle_min));
1824  t[1] = p(2,1)-p(0,1) + 1.0/4.0*(p(0,1)-p(1,1))+1.0/8.0*(angle_max-angle_min)*(3.0*cos(angle_max)-cos(angle_min));
1825  magnitude = sqrt((p(1,0)-p(2,0))*(p(1,0)-p(2,0)) + (p(1,1)-p(2,1))*(p(1,1)-p(2,1)));
1826  aa[0] = (p(1,0)-p(2,0))/(magnitude*magnitude);
1827  aa[1] = (p(1,1)-p(2,1))/(magnitude*magnitude);
1828  e1 = (t[0]*aa[0] + t[1]*aa[1]);
1829 
1830  magnitude = sqrt((p(0,0)-s1[0])*(p(0,0)-s1[0]) + (p(0,1)-s1[1])*(p(0,1)-s1[1]));
1831  aa[0] = (p(0,0)-s1[0])/(magnitude*magnitude);
1832  aa[1] = (p(0,1)-s1[1])/(magnitude*magnitude);
1833  e2 = (t[0]*aa[0] + t[1]*aa[1]);
1834 
1835  s[1] = 1.0/2.0;
1836  F2_div(1,1) = 5.0*s[1]*s[1]*6.0*s[1]*s[1]-4.0*s[1]*s[1]*15.0*s[1]+3.0*s[1]*s[1]*10.0;
1837  F2_div(2,1) = (1.0-s[1])*(1.0-s[1])*(1.0-s[1])*(12.0*s[1]+3.0)-3.0*(1.0-s[1])*(1.0-s[1])*(6.0*s[1]*s[1]+3.0*s[1]+1.0);
1838  F2_div(6,1) = s[1]*s[1]*s[1]*(1.0-s[1])*(-3.0)+(4.0-3.0*s[1])*(-s[1]*s[1]*s[1]+3.0*s[1]*s[1]*(1.0-s[1]));
1839  F2_div(7,1) = s[1]*(1.0-s[1])*(1.0-s[1])*(1.0-s[1])*3.0 + ( -3.0*s[1]*(1.0-s[1])*(1.0-s[1]) + (1.0-s[1])*(1.0-s[1])*(1.0-s[1]) )*(1.0+3.0*s[1]);
1840  F2_div(12,1) = -1.0*s[1]*s[1]*s[1]*(1.0-s[1])+3.0/2.0*(1.0-s[1])*(1.0-s[1])*s[1]*s[1];
1841  F2_div(13,1) = -3.0/2.0*s[1]*s[1]*(1.0-s[1])*(1.0-s[1]) + 1.0/2.0*(1.0-s[1])*(1.0-s[1])*(1.0-s[1])*2.0*s[1];
1842 
1843  s[1] = 1.0/2.0;
1844  H2[5] = -1.0*b1*(3.0*s[1]*s[1]-2.0*s[1]*s[1]*s[1]);
1845  H2[6] = -1.0/2.0*(2.0*b2+1.0+ata1)*(3.0*s[1]*s[1]-2.0*s[1]*s[1]*s[1]);
1846  H2[7] = -1.0/2.0*(1.0-ata1)*(1.0-3.0*s[1]*s[1]+2.0*s[1]*s[1]*s[1]);
1847  H2[8] = (1.0-3.0*s[1]*s[1]+2.0*s[1]*s[1]*s[1]);
1848  H2[11] = -1.0/2.0*((b1*b1)/(1.0+b2))*(s[1]*s[1]*s[1]-s[1]*s[1]);
1849  H2[12] = 1.0/2.0*(b2+ata1)*(s[1]*s[1]*s[1]-s[1]*s[1]);
1850  H2[13] = -1.0/2.0*( (2.0*c1*cc1)/(c1*cc2+c2*cc1) +1.0-ata1)*(s[1]-2.0*s[1]*s[1]+s[1]*s[1]*s[1]);
1851  H2[14] = -1.0*((c2*cc2)/(c1*cc2+c2*cc1))*(s[1]-2.0*s[1]*s[1]+s[1]*s[1]*s[1]);
1852  H2[16] = 1.0/2.0*(1.0/(1.0+b2))*(s[1]*s[1]*s[1]-s[1]*s[1]);
1853  H2[17] = ((-1.0)/(c1*cc2+c2*cc1))*(s[1]-2.0*s[1]*s[1]+s[1]*s[1]*s[1]);
1854 
1855  for(unsigned i=0;i<21;i++)
1856  {
1857  Bt(18,i) = e1*F2_div(i,1)+e2*H2[i];
1858  }
1859 
1860  t[0] = p(2,0)-p(1,0) + 1.0/4.0*(p(1,0)-p(0,0))-1.0/8.0*(angle_max-angle_min)*(-3.0*sin(angle_min)+sin(angle_max));
1861  t[1] = p(2,1)-p(1,1) + 1.0/4.0*(p(1,1)-p(0,1))-1.0/8.0*(angle_max-angle_min)*(3.0*cos(angle_min)-cos(angle_max));
1862  magnitude = sqrt((p(0,0)-p(2,0))*(p(0,0)-p(2,0)) + (p(0,1)-p(2,1))*(p(0,1)-p(2,1)));
1863  aa[0] = (p(0,0)-p(2,0))/(magnitude*magnitude);
1864  aa[1] = (p(0,1)-p(2,1))/(magnitude*magnitude);
1865  f1 = (t[0]*aa[0] + t[1]*aa[1]);
1866 
1867  magnitude = sqrt((p(1,0)-s2[0])*(p(1,0)-s2[0]) + (p(1,1)-s2[1])*(p(1,1)-s2[1]));
1868  aa[0] = (p(1,0)-s2[0])/(magnitude*magnitude);
1869  aa[1] = (p(1,1)-s2[1])/(magnitude*magnitude);
1870  f2 = (t[0]*aa[0] + t[1]*aa[1]);
1871 
1872  s[0] = 1.0/2.0;
1873  F1_div(0,0) = 5.0*s[0]*s[0]*6.0*s[0]*s[0]-4.0*s[0]*s[0]*15.0*s[0]+3.0*s[0]*s[0]*10.0;
1874  F1_div(2,0) = (1.0-s[0])*(1.0-s[0])*(1.0-s[0])*(12.0*s[0]+3.0)-3.0*(1.0-s[0])*(1.0-s[0])*(6.0*s[0]*s[0]+3.0*s[0]+1.0);
1875  F1_div(3,0) = s[0]*s[0]*s[0]*(1.0-s[0])*(-3.0)+(4.0-3.0*s[0])*(-s[0]*s[0]*s[0]+3.0*s[0]*s[0]*(1.0-s[0]));
1876  F1_div(8,0) = s[0]*(1.0-s[0])*(1.0-s[0])*(1.0-s[0])*3.0+(-3.0*s[0]*(1.0-s[0])*(1.0-s[0])+(1.0-s[0])*(1.0-s[0])*(1.0-s[0]))*(1.0+3.0*s[0]);
1877  F1_div(9,0) = -1.0*s[0]*s[0]*s[0]*(1.0-s[0])+3.0/2.0*(1.0-s[0])*(1.0-s[0])*s[0]*s[0];
1878  F1_div(14,0) = -3.0/2.0*s[0]*s[0]*(1.0-s[0])*(1.0-s[0]) + 1.0/2.0*(1.0-s[0])*(1.0-s[0])*(1.0-s[0])*2.0*s[0];
1879 
1880  s[0] = 1.0/2.0;
1881  H1[3] = -1.0/2.0*(1.0-ata2+2.0*a1)*(3.0*s[0]*s[0]-2.0*s[0]*s[0]*s[0]);
1882  H1[4] = -1.0*a2*(3.0*s[0]*s[0]-2.0*s[0]*s[0]*s[0]);
1883  H1[7] = 1.0-3.0*s[0]*s[0]+2.0*s[0]*s[0]*s[0];
1884  H1[8] = -1.0/2.0*(1.0+ata2)*(1.0-3.0*s[0]*s[0]+2.0*s[0]*s[0]*s[0]);
1885  H1[9] = 1.0/2.0*(a1-ata2)*(s[0]*s[0]*s[0]-s[0]*s[0]);
1886  H1[10] = -1.0/2.0*(a2*a2/(1.0+a1))*(s[0]*s[0]*s[0]-s[0]*s[0]);
1887  H1[13] = ((-1.0*c1*cc1)/(c1*cc2+c2*cc1))*(s[0]-2.0*s[0]*s[0]+s[0]*s[0]*s[0]);
1888  H1[14] = -1.0*( 1.0/2.0*(1.0+ata2)+(c2*cc2/(c1*cc2+c2*cc1)) )*(s[0]-2.0*s[0]*s[0]+s[0]*s[0]*s[0]);
1889  H1[15] = (s[0]*s[0]*s[0]-s[0]*s[0])/(2.0*(1.0+a1));
1890  H1[17] = -1.0/(c1*cc2+c2*cc1)*(s[0]-2.0*s[0]*s[0]+s[0]*s[0]*s[0]);
1891 
1892  for(unsigned i=0;i<21;i++)
1893  {
1894  Bt(19,i) = f1*F1_div(i,0)+f2*H1[i];
1895  }
1896 
1897  double A = a1 + 1.0/2.0*aa1;
1898  double BB = a2 + 1.0/2.0*aa2;
1899  double C = 2.0*b1-bb1;
1900  double E = 2.0*b2-bb2;
1901  s[0] = 1.0/2.0;
1902  H3[3] = (3.0*s[0]*s[0]-2.0*s[0]*s[0]*s[0]) - A*(-1.0*s[0]*s[0]+s[0]*s[0]*s[0]);
1903  H3[4] = -1.0/2.0*(3.0*s[0]*s[0]-2.0*s[0]*s[0]*s[0]) - (BB+1.0/2.0)*(-1.0*s[0]*s[0]+s[0]*s[0]*s[0]);
1904  H3[5] = -1.0/2.0*(1.0-3.0*s[0]*s[0]+2.0*s[0]*s[0]*s[0]) + 1.0/2.0*(C+1.0)*(s[0]-2.0*s[0]*s[0]+s[0]*s[0]*s[0]);
1905  H3[6] = (1.0-3.0*s[0]*s[0]+2.0*s[0]*s[0]*s[0]) + 1.0/2.0*E*(s[0]-2.0*s[0]*s[0]+s[0]*s[0]*s[0]);
1906  H3[9] = (1.0+a1)/(2.0*a2)*(s[0]*s[0]*s[0]-s[0]*s[0]);
1907  H3[10] = 1.0/2.0*(1.0+ a2/(1.0+a1))*(s[0]*s[0]*s[0]-s[0]*s[0]);
1908  H3[11] = -1.0/2.0*(1.0+ b1/(1.0+b2) )*(s[0]-2.0*s[0]*s[0]+s[0]*s[0]*s[0]);
1909  H3[12] = -1.0*(1.0+b2)/(2.0*b1)*(s[0]-2.0*s[0]*s[0]+s[0]*s[0]*s[0]);
1910  H3[15] = -1.0/(2.0*(1.0+a1)*a2)*(s[0]*s[0]*s[0]-s[0]*s[0]);
1911  H3[16] = 1.0/(2.0*b1*(1.0+b2))*(s[0]-2.0*s[0]*s[0]+s[0]*s[0]*s[0]);
1912 
1913  for(unsigned i=0;i<21;i++)
1914  {
1915  Bt(20,i) = -1.0*sqrt(2.0)*H3[i];
1916  }
1917 
1918  s[1] = 3.0/4.0;
1919  F2[1] = s[1]*s[1]*s[1]*(6.0*s[1]*s[1]-15.0*s[1]+10.0);
1920  F2[2] = (1.0-s[1])*(1.0-s[1])*(1.0-s[1])*(6.0*s[1]*s[1]+3.0*s[1]+1.0);
1921  F2[6] = s[1]*s[1]*s[1]*(1.0-s[1])*(4.0-3.0*s[1]);
1922  F2[7] = s[1]*(1.0-s[1])*(1.0-s[1])*(1.0-s[1])*(1.0+3.0*s[1]);
1923  F2[12] = 1.0/2.0*s[1]*s[1]*s[1]*(1.0-s[1])*(1.0-s[1]);
1924  F2[13] = 1.0/2.0*s[1]*s[1]*(1.0-s[1])*(1.0-s[1])*(1.0-s[1]);
1925  for(unsigned i=0;i<21;i++)
1926  {
1927  Bt(21,i) = F2[i];
1928  }
1929 
1930  s[1] = 1.0/4.0;
1931  F2[1] = s[1]*s[1]*s[1]*(6.0*s[1]*s[1]-15.0*s[1]+10.0);
1932  F2[2] = (1.0-s[1])*(1.0-s[1])*(1.0-s[1])*(6.0*s[1]*s[1]+3.0*s[1]+1.0);
1933  F2[6] = s[1]*s[1]*s[1]*(1.0-s[1])*(4.0-3.0*s[1]);
1934  F2[7] = s[1]*(1.0-s[1])*(1.0-s[1])*(1.0-s[1])*(1.0+3.0*s[1]);
1935  F2[12] = 1.0/2.0*s[1]*s[1]*s[1]*(1.0-s[1])*(1.0-s[1]);
1936  F2[13] = 1.0/2.0*s[1]*s[1]*(1.0-s[1])*(1.0-s[1])*(1.0-s[1]);
1937  for(unsigned i=0;i<21;i++)
1938  {
1939  Bt(22,i) = F2[i];
1940  }
1941 
1942  s[0] = 1.0/4.0;
1943  F1[0] = s[0]*s[0]*s[0]*(6.0*s[0]*s[0]-15.0*s[0]+10.0);
1944  F1[2] = (1.0-s[0])*(1.0-s[0])*(1.0-s[0])*(6.0*s[0]*s[0]+3.0*s[0]+1.0);
1945  F1[3] = s[0]*s[0]*s[0]*(1.0-s[0])*(4.0-3.0*s[0]);
1946  F1[8] = s[0]*(1.0-s[0])*(1.0-s[0])*(1.0-s[0])*(1.0+3.0*s[0]);
1947  F1[9] = 1.0/2.0*s[0]*s[0]*s[0]*(1.0-s[0])*(1.0-s[0]);
1948  F1[14] = 1.0/2.0*s[0]*s[0]*(1.0-s[0])*(1.0-s[0])*(1.0-s[0]);
1949  for(unsigned i=0;i<21;i++)
1950  {
1951  Bt(23,i) = F1[i];
1952  }
1953 
1954  s[0] = 3.0/4.0;
1955  F1[0] = s[0]*s[0]*s[0]*(6.0*s[0]*s[0]-15.0*s[0]+10.0);
1956  F1[2] = (1.0-s[0])*(1.0-s[0])*(1.0-s[0])*(6.0*s[0]*s[0]+3.0*s[0]+1.0);
1957  F1[3] = s[0]*s[0]*s[0]*(1.0-s[0])*(4.0-3.0*s[0]);
1958  F1[8] = s[0]*(1.0-s[0])*(1.0-s[0])*(1.0-s[0])*(1.0+3.0*s[0]);
1959  F1[9] = 1.0/2.0*s[0]*s[0]*s[0]*(1.0-s[0])*(1.0-s[0]);
1960  F1[14] = 1.0/2.0*s[0]*s[0]*(1.0-s[0])*(1.0-s[0])*(1.0-s[0]);
1961  for(unsigned i=0;i<21;i++)
1962  {
1963  Bt(24,i) = F1[i];
1964  }
1965 
1966  s[0] = 3.0/4.0;
1967  F3[0] = s[0]*s[0]*s[0]*(6.0*s[0]*s[0]-15.0*s[0]+10.0);
1968  F3[1] = (1.0-s[0])*(1.0-s[0])*(1.0-s[0])*(6.0*s[0]*s[0]+3.0*s[0]+1.0);
1969  F3[3] = -1.0*(3.0*a1+aa1)*s[0]*s[0]*s[0]*(1.0-s[0])*(1.0-s[0]);
1970  F3[4] = s[0]*s[0]*s[0]*(1.0-s[0])*(2.0-s[0]-(1.0-s[0])*(3.0*a2+aa2));
1971  F3[5] = s[0]*(1.0-s[0])*(1.0-s[0])*(1.0-s[0])*(1.0+s[0]-s[0]*(3.0*b1-bb1));
1972  F3[6] = -1.0*s[0]*s[0]*(1.0-s[0])*(1.0-s[0])*(1.0-s[0])*(3.0*b2-bb2);
1973  F3[10] = 1.0/2.0*s[0]*s[0]*s[0]*(1.0-s[0])*(1.0-s[0]);
1974  F3[11] = 1.0/2.0*s[0]*s[0]*(1.0-s[0])*(1.0-s[0])*(1.0-s[0]);
1975  for(unsigned i=0;i<21;i++)
1976  {
1977  Bt(25,i) = F3[i];
1978  }
1979 
1980  s[0] = 1.0/4.0;
1981  F3[0] = s[0]*s[0]*s[0]*(6.0*s[0]*s[0]-15.0*s[0]+10.0);
1982  F3[1] = (1.0-s[0])*(1.0-s[0])*(1.0-s[0])*(6.0*s[0]*s[0]+3.0*s[0]+1.0);
1983  F3[3] = -1.0*(3.0*a1+aa1)*s[0]*s[0]*s[0]*(1.0-s[0])*(1.0-s[0]);
1984  F3[4] = s[0]*s[0]*s[0]*(1.0-s[0])*(2.0-s[0]-(1.0-s[0])*(3.0*a2+aa2));
1985  F3[5] = s[0]*(1.0-s[0])*(1.0-s[0])*(1.0-s[0])*(1.0+s[0]-s[0]*(3.0*b1-bb1));
1986  F3[6] = -1.0*s[0]*s[0]*(1.0-s[0])*(1.0-s[0])*(1.0-s[0])*(3.0*b2-bb2);
1987  F3[10] = 1.0/2.0*s[0]*s[0]*s[0]*(1.0-s[0])*(1.0-s[0]);
1988  F3[11] = 1.0/2.0*s[0]*s[0]*(1.0-s[0])*(1.0-s[0])*(1.0-s[0]);
1989  for(unsigned i=0;i<21;i++)
1990  {
1991  Bt(26,i) = F3[i];
1992  }
1993 
1994  double g1,g2,h1,h2,k1,k2,j1,j2;
1995  t[0] = p(0,0)-p(2,0) + 9.0/16.0*(p(1,0)-p(0,0))+3.0/32.0*(angle_max-angle_min)*(-sin(angle_min)+7.0*sin(angle_max));
1996  t[1] = p(0,1)-p(2,1) + 9.0/16.0*(p(1,1)-p(0,1))+3.0/32.0*(angle_max-angle_min)*(cos(angle_min)-7.0*cos(angle_max));
1997  magnitude = sqrt((p(1,0)-p(2,0))*(p(1,0)-p(2,0)) + (p(1,1)-p(2,1))*(p(1,1)-p(2,1)));
1998  aa[0] = (p(1,0)-p(2,0))/(magnitude*magnitude);
1999  aa[1] = (p(1,1)-p(2,1))/(magnitude*magnitude);
2000  g1 = -1.0*(t[0]*aa[0] + t[1]*aa[1]);
2001 
2002  magnitude = sqrt((p(0,0)-s1[0])*(p(0,0)-s1[0]) + (p(0,1)-s1[1])*(p(0,1)-s1[1]));
2003  aa[0] = (p(0,0)-s1[0])/(magnitude*magnitude);
2004  aa[1] = (p(0,1)-s1[1])/(magnitude*magnitude);
2005  g2 = -1.0*(t[0]*aa[0] + t[1]*aa[1]);
2006 
2007  s[1] = 3.0/4.0;
2008  F2_div(1,1) = 5.0*s[1]*s[1]*6.0*s[1]*s[1]-4.0*s[1]*s[1]*15.0*s[1]+3.0*s[1]*s[1]*10.0;
2009  F2_div(2,1) = (1.0-s[1])*(1.0-s[1])*(1.0-s[1])*(12.0*s[1]+3.0)-3.0*(1.0-s[1])*(1.0-s[1])*(6.0*s[1]*s[1]+3.0*s[1]+1.0);
2010  F2_div(6,1) = s[1]*s[1]*s[1]*(1.0-s[1])*(-3.0)+(4.0-3.0*s[1])*(-s[1]*s[1]*s[1]+3.0*s[1]*s[1]*(1.0-s[1]));
2011  F2_div(7,1) = s[1]*(1.0-s[1])*(1.0-s[1])*(1.0-s[1])*3.0+(-3.0*s[1]*(1.0-s[1])*(1.0-s[1])+(1.0-s[1])*(1.0-s[1])*(1.0-s[1]))*(1.0+3.0*s[1]);
2012  F2_div(12,1) = -1.0*s[1]*s[1]*s[1]*(1.0-s[1])+3.0/2.0*(1.0-s[1])*(1.0-s[1])*s[1]*s[1];
2013  F2_div(13,1) = -3.0/2.0*s[1]*s[1]*(1.0-s[1])*(1.0-s[1]) + 1.0/2.0*(1.0-s[1])*(1.0-s[1])*(1.0-s[1])*2.0*s[1];
2014 
2015  s[1] = 3.0/4.0;
2016  H2[5] = -1.0*b1*(3.0*s[1]*s[1]-2.0*s[1]*s[1]*s[1]);
2017  H2[6] = -1.0/2.0*(2.0*b2+1.0+ata1)*(3.0*s[1]*s[1]-2.0*s[1]*s[1]*s[1]);
2018  H2[7] = -1.0/2.0*(1.0-ata1)*(1.0-3.0*s[1]*s[1]+2.0*s[1]*s[1]*s[1]);
2019  H2[8] = (1.0-3.0*s[1]*s[1]+2.0*s[1]*s[1]*s[1]);
2020  H2[11] = -1.0/2.0*((b1*b1)/(1.0+b2))*(s[1]*s[1]*s[1]-s[1]*s[1]);
2021  H2[12] = 1.0/2.0*(b2+ata1)*(s[1]*s[1]*s[1]-s[1]*s[1]);
2022  H2[13] = -1.0/2.0*( (2.0*c1*cc1)/(c1*cc2+c2*cc1) +1.0-ata1)*(s[1]-2.0*s[1]*s[1]+s[1]*s[1]*s[1]);
2023  H2[14] = -1.0*((c2*cc2)/(c1*cc2+c2*cc1))*(s[1]-2.0*s[1]*s[1]+s[1]*s[1]*s[1]);
2024  H2[16] = 1.0/2.0*(1.0/(1.0+b2))*(s[1]*s[1]*s[1]-s[1]*s[1]);
2025  H2[17] = ((-1.0)/(c1*cc2+c2*cc1))*(s[1]-2.0*s[1]*s[1]+s[1]*s[1]*s[1]);
2026  for(unsigned i=0;i<21;i++)
2027  {
2028  Bt(27,i) = g1*F2_div(i,1)+g2*H2[i];
2029  }
2030 
2031  t[0] = p(0,0)-p(2,0) + 1.0/16.0*(p(1,0)-p(0,0))+1.0/32.0*(angle_max-angle_min)*(-3.0*sin(angle_min)+5.0*sin(angle_max));
2032  t[1] = p(0,1)-p(2,1) + 1.0/16.0*(p(1,1)-p(0,1))+1.0/32.0*(angle_max-angle_min)*(3.0*cos(angle_min)-5.0*cos(angle_max));
2033  magnitude = sqrt((p(1,0)-p(2,0))*(p(1,0)-p(2,0)) + (p(1,1)-p(2,1))*(p(1,1)-p(2,1)));
2034  aa[0] = (p(1,0)-p(2,0))/(magnitude*magnitude);
2035  aa[1] = (p(1,1)-p(2,1))/(magnitude*magnitude);
2036  h1 = -1.0*(t[0]*aa[0] + t[1]*aa[1]);
2037 
2038  magnitude = sqrt((p(0,0)-s1[0])*(p(0,0)-s1[0]) + (p(0,1)-s1[1])*(p(0,1)-s1[1]));
2039  aa[0] = (p(0,0)-s1[0])/(magnitude*magnitude);
2040  aa[1] = (p(0,1)-s1[1])/(magnitude*magnitude);
2041  h2 = -1.0*(t[0]*aa[0] + t[1]*aa[1]);
2042 
2043  s[1] = 1.0/4.0;
2044  F2_div(1,1) = 5.0*s[1]*s[1]*6.0*s[1]*s[1]-4.0*s[1]*s[1]*15.0*s[1]+3.0*s[1]*s[1]*10.0;
2045  F2_div(2,1) = (1.0-s[1])*(1.0-s[1])*(1.0-s[1])*(12.0*s[1]+3.0)-3.0*(1.0-s[1])*(1.0-s[1])*(6.0*s[1]*s[1]+3.0*s[1]+1.0);
2046  F2_div(6,1) = s[1]*s[1]*s[1]*(1.0-s[1])*(-3.0)+(4.0-3.0*s[1])*(-s[1]*s[1]*s[1]+3.0*s[1]*s[1]*(1.0-s[1]));
2047  F2_div(7,1) = s[1]*(1.0-s[1])*(1.0-s[1])*(1.0-s[1])*3.0+(-3.0*s[1]*(1.0-s[1])*(1.0-s[1])+(1.0-s[1])*(1.0-s[1])*(1.0-s[1]))*(1.0+3.0*s[1]);
2048  F2_div(12,1) = -1.0*s[1]*s[1]*s[1]*(1.0-s[1])+3.0/2.0*(1.0-s[1])*(1.0-s[1])*s[1]*s[1];
2049  F2_div(13,1) = -3.0/2.0*s[1]*s[1]*(1.0-s[1])*(1.0-s[1]) + 1.0/2.0*(1.0-s[1])*(1.0-s[1])*(1.0-s[1])*2.0*s[1];
2050 
2051  s[1] = 1.0/4.0;
2052  H2[5] = -1.0*b1*(3.0*s[1]*s[1]-2.0*s[1]*s[1]*s[1]);
2053  H2[6] = -1.0/2.0*(2.0*b2+1.0+ata1)*(3.0*s[1]*s[1]-2.0*s[1]*s[1]*s[1]);
2054  H2[7] = -1.0/2.0*(1.0-ata1)*(1.0-3.0*s[1]*s[1]+2.0*s[1]*s[1]*s[1]);
2055  H2[8] = (1.0-3.0*s[1]*s[1]+2.0*s[1]*s[1]*s[1]);
2056  H2[11] = -1.0/2.0*((b1*b1)/(1.0+b2))*(s[1]*s[1]*s[1]-s[1]*s[1]);
2057  H2[12] = 1.0/2.0*(b2+ata1)*(s[1]*s[1]*s[1]-s[1]*s[1]);
2058  H2[13] = -1.0/2.0*( (2.0*c1*cc1)/(c1*cc2+c2*cc1) +1.0-ata1)*(s[1]-2.0*s[1]*s[1]+s[1]*s[1]*s[1]);
2059  H2[14] = -1.0*((c2*cc2)/(c1*cc2+c2*cc1))*(s[1]-2.0*s[1]*s[1]+s[1]*s[1]*s[1]);
2060  H2[16] = 1.0/2.0*(1.0/(1.0+b2))*(s[1]*s[1]*s[1]-s[1]*s[1]);
2061  H2[17] = ((-1.0)/(c1*cc2+c2*cc1))*(s[1]-2.0*s[1]*s[1]+s[1]*s[1]*s[1]);
2062 
2063  for(unsigned i=0;i<21;i++)
2064  {
2065  Bt(28,i) = h1*F2_div(i,1)+h2*H2[i];
2066  }
2067 
2068  t[0] = p(1,0)-p(2,0) + 1.0/16.0*(p(0,0)-p(1,0))-1.0/32.0*(angle_max-angle_min)*(-3.0*sin(angle_max)+5.0*sin(angle_min));
2069  t[1] = p(1,1)-p(2,1) + 1.0/16.0*(p(0,1)-p(1,1))-1.0/32.0*(angle_max-angle_min)*(3.0*cos(angle_max)-5.0*cos(angle_min));
2070  magnitude = sqrt((p(0,0)-p(2,0))*(p(0,0)-p(2,0)) + (p(0,1)-p(2,1))*(p(0,1)-p(2,1)));
2071  aa[0] = (p(0,0)-p(2,0))/(magnitude*magnitude);
2072  aa[1] = (p(0,1)-p(2,1))/(magnitude*magnitude);
2073  j1 = -1.0*(t[0]*aa[0] + t[1]*aa[1]);
2074 
2075  magnitude = sqrt((p(1,0)-s2[0])*(p(1,0)-s2[0]) + (p(1,1)-s2[1])*(p(1,1)-s2[1]));
2076  aa[0] = (p(1,0)-s2[0])/(magnitude*magnitude);
2077  aa[1] = (p(1,1)-s2[1])/(magnitude*magnitude);
2078  j2 = -1.0*(t[0]*aa[0] + t[1]*aa[1]);
2079 
2080  s[0] = 1.0/4.0;
2081  F1_div(0,0) = 5.0*s[0]*s[0]*6.0*s[0]*s[0]-4.0*s[0]*s[0]*15.0*s[0]+3.0*s[0]*s[0]*10.0;
2082  F1_div(2,0) = (1.0-s[0])*(1.0-s[0])*(1.0-s[0])*(12.0*s[0]+3.0)-3.0*(1.0-s[0])*(1.0-s[0])*(6.0*s[0]*s[0]+3.0*s[0]+1.0);
2083  F1_div(3,0) = s[0]*s[0]*s[0]*(1.0-s[0])*(-3.0)+(4.0-3.0*s[0])*(-s[0]*s[0]*s[0]+3.0*s[0]*s[0]*(1.0-s[0]));
2084  F1_div(8,0) = s[0]*(1.0-s[0])*(1.0-s[0])*(1.0-s[0])*3.0+(-3.0*s[0]*(1.0-s[0])*(1.0-s[0])+(1.0-s[0])*(1.0-s[0])*(1.0-s[0]))*(1.0+3.0*s[0]);
2085  F1_div(9,0) = -1.0*s[0]*s[0]*s[0]*(1.0-s[0])+3.0/2.0*(1.0-s[0])*(1.0-s[0])*s[0]*s[0];
2086  F1_div(14,0) = -3.0/2.0*s[0]*s[0]*(1.0-s[0])*(1.0-s[0]) + 1.0/2.0*(1.0-s[0])*(1.0-s[0])*(1.0-s[0])*2.0*s[0];
2087  s[0] = 1.0/4.0;
2088  H1[3] = -1.0/2.0*(1.0-ata2+2.0*a1)*(3.0*s[0]*s[0]-2.0*s[0]*s[0]*s[0]);
2089  H1[4] = -1.0*a2*(3.0*s[0]*s[0]-2.0*s[0]*s[0]*s[0]);
2090  H1[7] = 1.0-3.0*s[0]*s[0]+2.0*s[0]*s[0]*s[0];
2091  H1[8] = -1.0/2.0*(1.0+ata2)*(1.0-3.0*s[0]*s[0]+2.0*s[0]*s[0]*s[0]);
2092  H1[9] = 1.0/2.0*(a1-ata2)*(s[0]*s[0]*s[0]-s[0]*s[0]);
2093  H1[10] = -1.0/2.0*(a2*a2/(1.0+a1))*(s[0]*s[0]*s[0]-s[0]*s[0]);
2094  H1[13] = ((-1.0*c1*cc1)/(c1*cc2+c2*cc1))*(s[0]-2.0*s[0]*s[0]+s[0]*s[0]*s[0]);
2095  H1[14] = -1.0*( 1.0/2.0*(1.0+ata2)+(c2*cc2/(c1*cc2+c2*cc1)) )*(s[0]-2.0*s[0]*s[0]+s[0]*s[0]*s[0]);
2096  H1[15] = (s[0]*s[0]*s[0]-s[0]*s[0])/(2.0*(1.0+a1));
2097  H1[17] = -1.0/(c1*cc2+c2*cc1)*(s[0]-2.0*s[0]*s[0]+s[0]*s[0]*s[0]);
2098  for(unsigned i=0;i<21;i++)
2099  {
2100  Bt(29,i) = j1*F1_div(i,0)+j2*H1[i];
2101  }
2102 
2103  t[0] = p(1,0)-p(2,0) + 9.0/16.0*(p(0,0)-p(1,0))-3.0/32.0*(angle_max-angle_min)*(-sin(angle_max)+7.0*sin(angle_min));
2104  t[1] = p(1,1)-p(2,1) + 9.0/16.0*(p(0,1)-p(1,1))-3.0/32.0*(angle_max-angle_min)*(cos(angle_max)-7.0*cos(angle_min));
2105  magnitude = sqrt((p(0,0)-p(2,0))*(p(0,0)-p(2,0)) + (p(0,1)-p(2,1))*(p(0,1)-p(2,1)));
2106  aa[0] = (p(0,0)-p(2,0))/(magnitude*magnitude);
2107  aa[1] = (p(0,1)-p(2,1))/(magnitude*magnitude);
2108  k1 = -1.0*(t[0]*aa[0] + t[1]*aa[1]);
2109 
2110  magnitude = sqrt((p(1,0)-s2[0])*(p(1,0)-s2[0]) + (p(1,1)-s2[1])*(p(1,1)-s2[1]));
2111  aa[0] = (p(1,0)-s2[0])/(magnitude*magnitude);
2112  aa[1] = (p(1,1)-s2[1])/(magnitude*magnitude);
2113  k2 = -1.0*(t[0]*aa[0] + t[1]*aa[1]);
2114 
2115  s[0] = 3.0/4.0;
2116  F1_div(0,0) = 5.0*s[0]*s[0]*6.0*s[0]*s[0]-4.0*s[0]*s[0]*15.0*s[0]+3.0*s[0]*s[0]*10.0;
2117  F1_div(2,0) = (1.0-s[0])*(1.0-s[0])*(1.0-s[0])*(12.0*s[0]+3.0)-3.0*(1.0-s[0])*(1.0-s[0])*(6.0*s[0]*s[0]+3.0*s[0]+1.0);
2118  F1_div(3,0) = s[0]*s[0]*s[0]*(1.0-s[0])*(-3.0)+(4.0-3.0*s[0])*(-s[0]*s[0]*s[0]+3.0*s[0]*s[0]*(1.0-s[0]));
2119  F1_div(8,0) = s[0]*(1.0-s[0])*(1.0-s[0])*(1.0-s[0])*3.0+(-3.0*s[0]*(1.0-s[0])*(1.0-s[0])+(1.0-s[0])*(1.0-s[0])*(1.0-s[0]))*(1.0+3.0*s[0]);
2120  F1_div(9,0) = -1.0*s[0]*s[0]*s[0]*(1.0-s[0])+3.0/2.0*(1.0-s[0])*(1.0-s[0])*s[0]*s[0];
2121  F1_div(14,0) = -3.0/2.0*s[0]*s[0]*(1.0-s[0])*(1.0-s[0]) + 1.0/2.0*(1.0-s[0])*(1.0-s[0])*(1.0-s[0])*2.0*s[0];
2122 
2123  s[0] = 3.0/4.0;
2124  H1[3] = -1.0/2.0*(1.0-ata2+2.0*a1)*(3.0*s[0]*s[0]-2.0*s[0]*s[0]*s[0]);
2125  H1[4] = -1.0*a2*(3.0*s[0]*s[0]-2.0*s[0]*s[0]*s[0]);
2126  H1[7] = 1.0-3.0*s[0]*s[0]+2.0*s[0]*s[0]*s[0];
2127  H1[8] = -1.0/2.0*(1.0+ata2)*(1.0-3.0*s[0]*s[0]+2.0*s[0]*s[0]*s[0]);
2128  H1[9] = 1.0/2.0*(a1-ata2)*(s[0]*s[0]*s[0]-s[0]*s[0]);
2129  H1[10] = -1.0/2.0*(a2*a2/(1.0+a1))*(s[0]*s[0]*s[0]-s[0]*s[0]);
2130  H1[13] = ((-1.0*c1*cc1)/(c1*cc2+c2*cc1))*(s[0]-2.0*s[0]*s[0]+s[0]*s[0]*s[0]);
2131  H1[14] = -1.0*( 1.0/2.0*(1.0+ata2)+(c2*cc2/(c1*cc2+c2*cc1)) )*(s[0]-2.0*s[0]*s[0]+s[0]*s[0]*s[0]);
2132  H1[15] = (s[0]*s[0]*s[0]-s[0]*s[0])/(2.0*(1.0+a1));
2133  H1[17] = -1.0/(c1*cc2+c2*cc1)*(s[0]-2.0*s[0]*s[0]+s[0]*s[0]*s[0]);
2134  for(unsigned i=0;i<21;i++)
2135  {
2136  Bt(30,i) = k1*F1_div(i,0)+k2*H1[i];
2137  }
2138 
2139  s[0] = 3.0/4.0;
2140  H3[3] = (3.0*s[0]*s[0]-2.0*s[0]*s[0]*s[0]) - A*(-1.0*s[0]*s[0]+s[0]*s[0]*s[0]);
2141  H3[4] = -1.0/2.0*(3.0*s[0]*s[0]-2.0*s[0]*s[0]*s[0]) - (BB+1.0/2.0)*(-1.0*s[0]*s[0]+s[0]*s[0]*s[0]);
2142  H3[5] = -1.0/2.0*(1.0-3.0*s[0]*s[0]+2.0*s[0]*s[0]*s[0]) + 1.0/2.0*(C+1.0)*(s[0]-2.0*s[0]*s[0]+s[0]*s[0]*s[0]);
2143  H3[6] = (1.0-3.0*s[0]*s[0]+2.0*s[0]*s[0]*s[0]) + 1.0/2.0*E*(s[0]-2.0*s[0]*s[0]+s[0]*s[0]*s[0]);
2144  H3[9] = (1.0+a1)/(2.0*a2)*(s[0]*s[0]*s[0]-s[0]*s[0]);
2145  H3[10] = 1.0/2.0*(1.0+ a2/(1.0+a1))*(s[0]*s[0]*s[0]-s[0]*s[0]);
2146  H3[11] = -1.0/2.0*(1.0+ b1/(1.0+b2) )*(s[0]-2.0*s[0]*s[0]+s[0]*s[0]*s[0]);
2147  H3[12] = -1.0*(1.0+b2)/(2.0*b1)*(s[0]-2.0*s[0]*s[0]+s[0]*s[0]*s[0]);
2148  H3[15] = -1.0/(2.0*(1.0+a1)*a2)*(s[0]*s[0]*s[0]-s[0]*s[0]);
2149  H3[16] = 1.0/(2.0*b1*(1.0+b2))*(s[0]-2.0*s[0]*s[0]+s[0]*s[0]*s[0]);
2150 
2151  for(unsigned i=0;i<21;i++)
2152  for(unsigned i=0;i<21;i++)
2153  {
2154  Bt(31,i) = -1.0*sqrt(2.0)*H3[i];
2155  }
2156 
2157  s[0] = 1.0/4.0;
2158  H3[3] = (3.0*s[0]*s[0]-2.0*s[0]*s[0]*s[0]) - A*(-1.0*s[0]*s[0]+s[0]*s[0]*s[0]);
2159  H3[4] = -1.0/2.0*(3.0*s[0]*s[0]-2.0*s[0]*s[0]*s[0]) - (BB+1.0/2.0)*(-1.0*s[0]*s[0]+s[0]*s[0]*s[0]);
2160  H3[5] = -1.0/2.0*(1.0-3.0*s[0]*s[0]+2.0*s[0]*s[0]*s[0]) + 1.0/2.0*(C+1.0)*(s[0]-2.0*s[0]*s[0]+s[0]*s[0]*s[0]);
2161  H3[6] = (1.0-3.0*s[0]*s[0]+2.0*s[0]*s[0]*s[0]) + 1.0/2.0*E*(s[0]-2.0*s[0]*s[0]+s[0]*s[0]*s[0]);
2162  H3[9] = (1.0+a1)/(2.0*a2)*(s[0]*s[0]*s[0]-s[0]*s[0]);
2163  H3[10] = 1.0/2.0*(1.0+ a2/(1.0+a1))*(s[0]*s[0]*s[0]-s[0]*s[0]);
2164  H3[11] = -1.0/2.0*(1.0+ b1/(1.0+b2) )*(s[0]-2.0*s[0]*s[0]+s[0]*s[0]*s[0]);
2165  H3[12] = -1.0*(1.0+b2)/(2.0*b1)*(s[0]-2.0*s[0]*s[0]+s[0]*s[0]*s[0]);
2166  H3[15] = -1.0/(2.0*(1.0+a1)*a2)*(s[0]*s[0]*s[0]-s[0]*s[0]);
2167  H3[16] = 1.0/(2.0*b1*(1.0+b2))*(s[0]-2.0*s[0]*s[0]+s[0]*s[0]*s[0]);
2168 
2169  for(unsigned i=0;i<21;i++)
2170  {
2171  Bt(32,i) = -1.0*sqrt(2.0)*H3[i];
2172  }
2173  // submatrix b7
2174  Bt(33,18)=1.0;
2175  Bt(34,19)=1.0;
2176  Bt(35,20)=1.0;
2177  for(unsigned i=0;i<21;i++)
2178  {
2179  for(unsigned j=0;j<36;j++)
2180  {
2181  B(i,j) = Bt(j,i);
2182  }
2183  }
2184  }
2185 
2186  ///=========================================================================
2187  /// Compute C1-curved shape functions at the local coordinate s
2188  ///========================================================================
2189  void Cshape(const Vector<double> &s, Shape &psi_curve) const
2190  {
2191  // get basis
2192  Shape basis(36);
2193  basis_curve(s,basis);
2194  // get coefficient of the basis polynomial
2195  DenseMatrix<double> A(36,36);
2196  get_coefficient(A);
2197 
2198  Vector<double> psi(36,0.0);
2199  for(unsigned i=0;i<36;i++)
2200  {
2201  for(unsigned j=0;j<36;j++)
2202  {
2203  psi[i] += A(i,j)*basis[j];
2204  }
2205  }
2206  for(unsigned i=0;i<36;i++)
2207  {
2208  psi_curve[i] = psi[i];
2209  }
2210  }
2211 
2212  ///=========================================================================
2213  /// Compute the derivatives of C1-curved shape functions at the local
2214  /// coordinate s
2215  ///=========================================================================
2216  void dCshape_local(const Vector<double> &s, Shape &psi_curve, DShape &dpsi_curve) const
2217  {
2218  Cshape(s,psi_curve);
2219  // get dbasis
2220  Shape basis(36);
2221  DShape dbasis(36,2);
2222  dbasis_local_curve(s,basis,dbasis);
2223  // get coefficient of the basis polynomial
2224  DenseMatrix<double> A(36,36);
2225  get_coefficient(A);
2226  DenseMatrix<double> dpsi(36,2,0.0);
2227  for(unsigned i=0;i<36;i++)
2228  {
2229  for(unsigned j=0;j<36;j++)
2230  {
2231  for(unsigned k=0;k<2;k++)
2232  {
2233  dpsi(i,k) += A(i,j)*dbasis(j,k);
2234  }
2235  }
2236  }
2237  for(unsigned i=0;i<36;i++)
2238  {
2239  for(unsigned k=0;k<2;k++)
2240  {
2241  dpsi_curve(i,k) = dpsi(i,k);
2242  }
2243  }
2244  }
2245 
2246  ///=========================================================================
2247  /// Compute the second-order derivatives of C1-curved shape functions
2248  /// at the local coordinate s
2249  ///=========================================================================
2250  void d2Cshape_local(const Vector<double> &s, Shape &psi_curve, DShape &dpsi_curve, DShape &d2psi_curve) const
2251  {
2252  dCshape_local(s,psi_curve,dpsi_curve);
2253 
2254  // get d2basis
2255  Shape basis(36);
2256  DShape dbasis(36,2), d2basis(36,3);
2257  d2basis_local_curve(s,basis,dbasis,d2basis);
2258  // get coefficient of the basis polynomial
2259  DenseMatrix<double> A(36,36,0.0);
2260  get_coefficient(A);
2261  DenseMatrix<double> d2psi(36,3,0.0);
2262  for(unsigned i=0;i<36;i++)
2263  {
2264  for(unsigned j=0;j<36;j++)
2265  {
2266  for(unsigned k=0;k<3;k++)
2267  {
2268  d2psi(i,k) += A(i,j)*d2basis(j,k);
2269  }
2270  }
2271  }
2272  for(unsigned i=0;i<36;i++)
2273  {
2274  for(unsigned k=0;k<3;k++)
2275  {
2276  d2psi_curve(i,k) = d2psi(i,k);
2277  }
2278  }
2279  }
2280 
2281  ///=========================================================================
2282  /// Compute coefficients of the bases of the C1-curved shape functions
2283  ///=========================================================================
2285  {
2286  // initialize the matrix A
2287  for(unsigned i=0;i<36;i++)
2288  {
2289  for(unsigned j=0;j<36;j++)
2290  {A(i,j)=0.0;}
2291  }
2292  // 1
2293  A(1,0) = 6496.0/27.0;
2294  A(1,2) = 55376.0/27.0;
2295  A(1,3) = 15296.0/3.0;
2296  A(1,4) = 86464.0/27.0;
2297  A(1,5) = 464.0/3.0;
2298  A(1,8) = -6896.0/9.0;
2299  A(1,10) = -136424.0/27.0;
2300  A(1,11) = -187040.0/27.0;
2301  A(1,12) = -27880.0/27.0;
2302  A(1,15) = 7750.0/9.0;
2303  A(1,17) = 98371.0/27.0;
2304  A(1,18) = 41027.0/27.0;
2305  A(1,21) = -10501.0/27.0;
2306  A(1,23) = -17323.0/27.0;
2307  A(1,26) = 490.0/9.0;
2308  A(0,2) = 464.0/3.0;
2309  A(0,3) = 86464.0/27.0;
2310  A(0,4) = 15296.0/3.0;
2311  A(0,5) = 55376.0/27.0;
2312  A(0,7) = 6496.0/27.0;
2313  A(0,10) = -27880.0/27.0;
2314  A(0,11) = -187040.0/27.0;
2315  A(0,12) = -136424.0/27.0;
2316  A(0,14) = -6896.0/9.0;
2317  A(0,17) = 41027.0/27.0;
2318  A(0,18) = 98371.0/27.0;
2319  A(0,20) = 7750.0/9.00;
2320  A(0,23) = -17323.0/27.0;
2321  A(0,25) = -10501.0/27.0;
2322  A(0,29) = 490.00/9.0;
2323  A(2,0) = -6496.00/27.0;
2324  A(2,2) = 14176.00/27.00;
2325  A(2,3) = -2944.00/27.00;
2326  A(2,4) = -2944.00/27.00;
2327  A(2,5) = 14176.00/27.00;
2328  A(2,7) = -6496.00/27.00;
2329  A(2,8) = 24784.00/27.00;
2330  A(2,10) = -5680.00/27.00;
2331  A(2,11) = 12736.00/9.00;
2332  A(2,12) = -5680.00/27.00;
2333  A(2,14) = 24784.00/27.00;
2334  A(2,15) = -11846.00/9.00;
2335  A(2,17) = -26758.00/27.00;
2336  A(2,18) = -26758.00/27.00;
2337  A(2,20) = -11846.00/9.00;
2338  A(2,21) = 22789.00/27.00;
2339  A(2,23) = 18262.00/27.00;
2340  A(2,25) = 22789.00/27.00;
2341  A(2,26) = -5566.00/27.00;
2342  A(2,29) = -5566.00/27.00;
2343  A(2,35) = 1.00;
2344  A(6,0) = -400.00/9.00;
2345  A(6,2) = -3080.00/9.00;
2346  A(6,3) = -816.00;
2347  A(6,4) = -4496.00/9.00;
2348  A(6,5) = -232.00/9.00;
2349  A(6,8) = 416.00/3.00;
2350  A(6,10) = 7448.00/9.00;
2351  A(6,11) = 9872.00/9.00;
2352  A(6,12) = 1472.00/9.00;
2353  A(6,15) = -457.00/3.00;
2354  A(6,17) = -1177.00/2.00;
2355  A(6,18) = -4337.00/18.00;
2356  A(6,21) = 607.00/9.00;
2357  A(6,23) = 619.00/6.00;
2358  A(6,26) = -28.00/3.00;
2359  A(5,1) = -896.00/9.00;
2360  A(5,2) = -392.00/9.00;
2361  A(5,3) = 2384.00/9.00;
2362  A(5,4) = 2512.00/9.00;
2363  A(5,5) = 232.00/9.00;
2364  A(5,9) = 2336.00/9.00;
2365  A(5,10) = -8.00/9.00;
2366  A(5,11) = -3920.00/9.00;
2367  A(5,12) = -976.00/9.00;
2368  A(5,16) = -2104.00/9.00;
2369  A(5,17) = 123.00/2.00;
2370  A(5,18) = 1981.00/18.00;
2371  A(5,22) = 766.00/9.00;
2372  A(5,23) = -307.00/18.00;
2373  A(5,27) = -31.00/3.00;
2374  A(4,2) = 232.00/9.00;
2375  A(4,3) = 2512.00/9.00;
2376  A(4,4) = 2384.00/9.00;
2377  A(4,5) = -392.00/9.00;
2378  A(4,6) = -896.00/9.00;
2379  A(4,10) = -976.00/9.00;
2380  A(4,11) = -3920.00/9.00;
2381  A(4,12) = -8.00/9.00;
2382  A(4,13) = 2336.00/9.00;
2383  A(4,17) = 1981.00/18.00;
2384  A(4,18) = 123.00/2.00;
2385  A(4,19) = -2104.00/9.00;
2386  A(4,23) = -307.00/18.00;
2387  A(4,24) = 766.00/9.00;
2388  A(4,28) = -31.00/3.00;
2389  A(3,2) = -232.00/9.00;
2390  A(3,3) = -4496.00/9.00;
2391  A(3,4) = -816.00;
2392  A(3,5) = -3080.00/9.00;
2393  A(3,7) = -400.00/9.00;
2394  //------- 2
2395  A(3,10) = 1472.00/9.00;
2396  A(3,11) = 9872.00/9.00;
2397  A(3,12) = 7448.00/9.00;
2398  A(3,14) = 416.00/3.00;
2399  A(3,17) = -4337.00/18.00;
2400  A(3,18) = -1177.00/2.00;
2401  A(3,20) = -457.00/3.00;
2402  A(3,23) = 619.00/6.00;
2403  A(3,25) = 607.00/9.00;
2404  A(3,29) = -28.00/3.00;
2405  A(8,0) = -400.00/9.00;
2406  A(8,2) = 1456.00/9.00;
2407  A(8,3) = -992.00/9.00;
2408  A(8,4) = -5248.00/9.00;
2409  A(8,5) = -4096.00/9.00;
2410  A(8,6) = -896.00/9.00;
2411  A(8,8) = 1552.00/9.00;
2412  A(8,10) = -464.00/3.00;
2413  A(8,11) = 2464.00/3.00;
2414  A(8,12) = 3424.00/3.00;
2415  A(8,13) = 3040.00/9.00;
2416  A(8,15) = -761.00/3.00;
2417  A(8,17) = -1831.00/9.00;
2418  A(8,18) = -938.00;
2419  A(8,19) = -1288.00/3.00;
2420  A(8,21) = 1528.00/9.00;
2421  A(8,23) = 2266.00/9.00;
2422  A(8,24) = 2210.00/9.00;
2423  A(8,26) = -406.00/9.00;
2424  A(8,28) = -499.00/9.00;
2425  A(8,33) = 1.00;
2426  A(7,1) = -896.00/9.00;
2427  A(7,2) = -4096.00/9.00;
2428  A(7,3) = -5248.00/9.00;
2429  A(7,4) = -992.00/9.00;
2430  A(7,5) = 1456.00/9.00;
2431  A(7,7) = -400.00/9.00;
2432  A(7,9) = 3040.00/9.00;
2433  A(7,10) = 3424.00/3.00;
2434  A(7,11) = 2464.00/3.00;
2435  A(7,12) = -464.00/3.00;
2436  A(7,14) = 1552.00/9.00;
2437  A(7,16) = -1288.00/3.00;
2438  A(7,17) = -938.00;
2439  A(7,18) = -1831.00/9.00;
2440  A(7,20) = -761.00/3.00;
2441  A(7,22) = 2210.00/9.00;
2442  A(7,23) = 2266.00/9.00;
2443  A(7,25) = 1528.00/9.00;
2444  A(7,27) = -499.00/9.00;
2445  A(7,29) = -406.00/9.00;
2446  A(7,34) = 1.00;
2447  A(14,0) = 8.00/3.00;
2448  A(14,2) = 52.00/3.00;
2449  A(14,3) = 40.00;
2450  A(14,4) = 24.00;
2451  A(14,5) = 4.00/3.00;
2452  A(14,8) = -8.00;
2453  A(14,10) = -124.00/3.00;
2454  A(14,11) = -160.00/3.00;
2455  A(14,12) = -8.00;
2456  A(14,15) = 17.00/2.00;
2457  A(14,17) = 349.00/12.00;
2458  A(14,18) = 47.00/4.00;
2459  A(14,21) = -11.00/3.00;
2460  A(14,23) = -61.00/12.00;
2461  A(14,26) = 1.00/2.00;
2462  A(13,1) = 32.00/3.00;
2463  A(13,2) = 8.00/3.00;
2464  A(13,3) = -80.00/3.00;
2465  A(13,4) = -80.00/3.00;
2466  A(13,5) = -8.00/3.00;
2467  A(13,9) = -80.00/3.00;
2468  A(13,10) = 8.00/3.00;
2469  A(13,11) = 128.00/3.00;
2470  A(13,12) = 32.00/3.00;
2471  A(13,16) = 70.00/3.0;
2472  A(13,17) = -43.0/6.0;
2473  A(13,18) = -65.0/6.0;
2474  A(13,22) = -25.0/3.0;
2475  A(13,23) = 11.0/6.0;
2476  A(13,27) = 1.0;
2477  A(12,2) = 4.0;
2478  A(12,3) = 40.0/3.0;
2479  A(12,4) = 40.0/3.0;
2480  A(12,5) = 4.0/3.0;
2481  A(12,10) = -28.0/3.0;
2482  A(12,11) = -64.0/3.0;
2483  A(12,12) = -16.0/3.0;
2484  A(12,17) = 29.0/4.0;
2485  A(12,18) = 65.0/12.0;
2486  A(12,23) = -17.0/12.0;
2487  A(11,2) = 4.0/3.0;
2488  A(11,3) = 40.0/3.0;
2489  A(11,4) = 40.0/3.0;
2490  A(11,5) = 4.0;
2491  A(11,10) = -16.0/3.0;
2492  A(11,11) = -64.0/3.0;
2493  A(11,12) = -28.0/3.0;
2494  A(11,17) = 65.0/12.0;
2495  A(11,18) = 29.0/4.0;
2496  A(11,23) = -17.0/12.0;
2497  //------- 3
2498  A(10,2) = -8.0/3.0;
2499  A(10,3) = -80.0/3.0;
2500  A(10,4) = -80.0/3.0;
2501  A(10,5) = 8.0/3.0;
2502  A(10,6) = 32.0/3.0;
2503  A(10,10) = 32.0/3.0;
2504  A(10,11) = 128.0/3.0;
2505  A(10,12) = 8.0/3.0;
2506  A(10,13) = -80.0/3.0;
2507  A(10,17) = -65.0/6.0;
2508  A(10,18) = -43.0/6.0;
2509  A(10,19) = 70.0/3.0;
2510  A(10,23) = 11.0/6.0;
2511  A(10,24) = -25.0/3.0;
2512  A(10,28) = 1.0;
2513  A(9,2) = 4.0/3.0;
2514  A(9,3) = 24.0;
2515  A(9,4) = 40.0;
2516  A(9,5) = 52.0/3.0;
2517  A(9,7) = 8.0/3.0;
2518  A(9,10) = -8.0;
2519  A(9,11) = -160.0/3.0;
2520  A(9,12) = -124.0/3.0;
2521  A(9,14) = -8.0;
2522  A(9,17) = 47.0/4.0;
2523  A(9,18) = 349.0/12.0;
2524  A(9,20) = 17.0/2.0;
2525  A(9,23) = -61.0/12.0;
2526  A(9,25) = -11.0/3.0;
2527  A(9,29) = 1.0/2.0;
2528  A(17,0) = -8.0/3.0;
2529  A(17,2) = 56.0/3.0;
2530  A(17,3) = 80.0/3.0;
2531  A(17,4) = 32.0/3.0;
2532  A(17,8) = 32.0/3.0;
2533  A(17,10) = -40.0;
2534  A(17,11) = -32.0;
2535  A(17,12) = -8.0/3.0;
2536  A(17,15) = -33.0/2.0;
2537  A(17,17) = 51.0/2.0;
2538  A(17,18) = 19.0/3.0;
2539  A(17,21) = 73.0/6.0;
2540  A(17,23) = -25.0/6.0;
2541  A(17,26) = -25.0/6.0;
2542  A(17,30) = 1.0/2.0;
2543  A(16,1) = -32.0/3.0;
2544  A(16,2) = -160.0/3.0;
2545  A(16,3) = -320.0/3.0;
2546  A(16,4) = -320.0/3.0;
2547  A(16,5) = -160.0/3.0;
2548  A(16,6) = -32.0/3.0;
2549  A(16,9) = 112.0/3.0;
2550  A(16,10) = 448.0/3.0;
2551  A(16,11) = 224.0;
2552  A(16,12) = 448.0/3.0;
2553  A(16,13) = 112.0/3.0;
2554  A(16,16) = -50.0;
2555  A(16,17) = -150.0;
2556  A(16,18) = -150.0;
2557  A(16,19) = -50.0;
2558  A(16,22) = 95.0/3.0;
2559  A(16,23) = 190.0/3.0;
2560  A(16,24) = 95.0/3.0;
2561  A(16,27) = -28.0/3.0;
2562  A(16,28) = -28.0/3.0;
2563  A(16,31) = 1.0;
2564  A(15,3) = 32.0/3.0;
2565  A(15,4) = 80.0/3.0;
2566  A(15,5) = 56.0/3.0;
2567  A(15,7) = -8.0/3.0;
2568  A(15,10) = -8.0/3.0;
2569  A(15,11) = -32.0;
2570  A(15,12) = -40.0;
2571  A(15,14) = 32.0/3.0;
2572  A(15,17) = 19.0/3.0;
2573  A(15,18) = 51.0/2.0;
2574  A(15,20) = -33.0/2.0;
2575  A(15,23) = -25.0/6.0;
2576  A(15,25) = 73.0/6.0;
2577  A(15,29) = -25.0/6.0;
2578  A(15,32) = 1.0/2.0;
2579  A(19,3) = 256.0;
2580  A(19,4) = 768.0;
2581  A(19,5) = 768.0;
2582  A(19,6) = 256.0;
2583  A(19,10) = -64.0;
2584  A(19,11) = -896.0;
2585  A(19,12) = -1600.0;
2586  A(19,13) = -768.0;
2587  A(19,17) = 176.0;
2588  A(19,18) = 992.0;
2589  A(19,19) = 816.0;
2590  A(19,23) = -160.0;
2591  A(19,24) = -352.0;
2592  A(19,28) = 48.0;
2593  A(18,1) = 256.0;
2594  A(18,2) = 768.0;
2595  A(18,3) = 768.0;
2596  A(18,4) = 256.0;
2597  A(18,9) = -768.0;
2598  A(18,10) =-1600.0;
2599  A(18,11) = -896.0;
2600 
2601  //--------- 4
2602  A(18,12) = -64.0;
2603  A(18,16) = 816.0;
2604  A(18,17) = 992.0;
2605  A(18,18) = 176.0;
2606  A(18,22) = -352.0;
2607  A(18,23) = -160.0;
2608  A(18,27) = 48.0;
2609  A(20,3) = 128.0*sqrt(2.0);
2610  A(20,4) = 128.0*sqrt(2.0);
2611  A(20,10) = -32.0*sqrt(2.0);
2612  A(20,11) = -192.0*sqrt(2.0);
2613  A(20,12) = -32.0*sqrt(2.0);
2614  A(20,17) = 40.0*sqrt(2.0);
2615  A(20,18) = 40.0*sqrt(2.0);
2616  A(20,23) = -8.0*sqrt(2.0);
2617  A(24,3) = -65536.0/27.0;
2618  A(24,4) = -114688.0/27.0;
2619  A(24,5) = -40960.0/27.0;
2620  A(24,7) = -8192.0/27.0;
2621  A(24,10) = 16384.0/27.0;
2622  A(24,11) = 53248./9.0;
2623  A(24,12) = 38912.0/9.0;
2624  A(24,14) = 26624.0/27.0;
2625  A(24,17) = -32768.0/27.0;
2626  A(24,18) = -10240.0/3.0;
2627  A(24,20) = -10240.0/9.0;
2628  A(24,23) = 16384.0/27.0;
2629  A(24,25) = 14336.0/27.0;
2630  A(24,29) = -2048.0/27.0;
2631  A(23,2) = 53248.0/27.0;
2632  A(23,3) = 40960.0/9.0;
2633  A(23,4) = 69632.0/27.0;
2634  A(23,5) = -8192.0/27.0;
2635  A(23,7) = 8192.0/27.0;
2636  A(23,10) = -48128.0/9.0;
2637  A(23,11) = -22528.0/3.0;
2638  A(23,12) = -1024.0;
2639  A(23,14) = -10240.0/9.0;
2640  A(23,17) = 14336.0/3.0;
2641  A(23,18) = 8192.0/3.0;
2642  A(23,20) = 14336.0/9.0;
2643  A(23,23) = -37888.0/27.0;
2644  A(23,25) = -26624.0/27.0;
2645  A(23,29) = 2048.0/9.0;
2646  A(22,0) = 8192.0/27.0;
2647  A(22,2) = -8192.0/27.0;
2648  A(22,3) = 69632.0/27.0;
2649  A(22,4) = 40960.0/9.0;
2650  A(22,5) = 53248.0/27.0;
2651  A(22,8) = -10240.0/9.0;
2652  A(22,10) = -1024.0;
2653  A(22,11) = -22528.0/3.0;
2654  A(22,12) = -48128.0/9.0;
2655  A(22,15) = 14336.0/9.0;
2656  A(22,17) = 8192.0/3.0;
2657  A(22,18) = 14336.0/3.0;
2658  A(22,21) = -26624.0/27.0;
2659  A(22,23) = -37888.0/27.0;
2660  A(22,26) = 2048.0/9.0;
2661  A(21,0) = -8192.0/27.0;
2662  A(21,2) = -40960.0/27.0;
2663  A(21,3) = -114688.0/27.0;
2664  A(21,4) = -65536.0/27.0;
2665  A(21,8) = 26624.0/27.0;
2666  A(21,10) = 38912.0/9.0;
2667  A(21,11) = 53248.0/9.0;
2668  A(21,12) = 16384.0/27.0;
2669  A(21,15) = -10240.0/9.0;
2670  A(21,17) = -10240.0/3.0;
2671  A(21,18) = -32768.0/27.0;
2672  A(21,21) = 14336.0/27.0;
2673  A(21,23) = 16384.0/27.0;
2674  A(21,26) = -2048.0/27.0;
2675  A(26,2) = -71680.0/27.0;
2676  A(26,3) = -145408.0/27.0;
2677  A(26,4) = -88064.0/27.0;
2678  A(26,5) = -2048.0/9.0;
2679  A(26,10) = 150016.0/27.0;
2680  A(26,11) = 183296.0/27.0;
2681  A(26,12) = 31232.0/27.0;
2682  A(26,17) = -94208.0/27.0;
2683  A(26,18) = -40960.0/27.0;
2684  A(26,23) = 15872.0/27.0;
2685  A(25,2) = -2048.0/9.0;
2686  A(25,3) = -88064.0/27.0;
2687  A(25,4) = -145408.0/27.0;
2688  A(25,5) = -71680.0/27.0;
2689  A(25,10) = 31232.0/27.0;
2690  A(25,11) = 183296.0/27.0;
2691  A(25,12) = 150016.0/27.0;
2692  A(25,17) = -40960.0/27.0;
2693  A(25,18) = -94208.0/27.0;
2694  A(25,23) = 15872.0/27.0;
2695  A(30,4) = -2048.0/9.0;
2696  A(30,5) = -4096.0/9.0;
2697  A(30,6) = -2048.0/9.0;
2698  A(30,11) = 512.0/3.0;
2699  A(30,12) = 7168.0/9.0;
2700  A(30,13) = 5632.0/9.0;
2701  A(30,17) = -256.0/9.0;
2702  A(30,18) = -3584.0/9.0;
2703  A(30,19) = -1792.0/3.0;
2704 
2705  //-------- 5
2706  A(30,23) = 512.0/9.0;
2707  A(30,24) = 2048.0/9.0;
2708  A(30,28) = -256.0/9.0;
2709  A(29,2) = -2048.0/9.0;
2710  A(29,3) = -8192.0/9.0;
2711  A(29,4) = -4096.0/3.0;
2712  A(29,5) = -8192.0/9.0;
2713  A(29,6) = -2048.0/9.0;
2714  A(29,10) = 6656.0/9.0;
2715  A(29,11) = 6656.0/3.0;
2716  A(29,12) = 6656.0/3.0;
2717  A(29,13) = 6656.0/9.0;
2718  A(29,17) = -7936.0/9.0;
2719  A(29,18) = -15872.0/9.0;
2720  A(29,19) = -7936.0/9.0;
2721  A(29,23) = 4096.0/9.0;
2722  A(29,24) = 4096.0/9.0;
2723  A(29,28) = -256.0/3.0;
2724  A(28,1) = -2048.0/9.0;
2725  A(28,2) = -8192.0/9.0;
2726  A(28,3) = -4096.0/3.0;
2727  A(28,4) = -8192.0/9.0;
2728  A(28,5) = -2048.0/9.0;
2729  A(28,9) = 6656.0/9.0;
2730  A(28,10) = 6656.0/3.0;
2731  A(28,11) = 6656.0/3.0;
2732  A(28,12) = 6656.0/9.0;
2733  A(28,16) = -7936.0/9.0;
2734  A(28,17) = -15872.0/9.0;
2735  A(28,18) = -7936.0/9.0;
2736  A(28,22) = 4096.0/9.0;
2737  A(28,23) = 4096.0/9.0;
2738  A(28,27) = -256.0/3.0;
2739  A(27,1) = -2048.0/9.0;
2740  A(27,2) = -4096.0/9.0;
2741  A(27,3) = -2048.0/9.0;
2742  A(27,9) = 5632.0/9.0;
2743  A(27,10) = 7168.0/9.0;
2744  A(27,11) = 512.0/3.0;
2745  A(27,16) = -1792.0/3.0;
2746  A(27,17) = -3584.0/9.0;
2747  A(27,18) = -256.0/9.0;
2748  A(27,22) = 2048.0/9.0;
2749  A(27,23) = 512.0/9.0;
2750  A(27,27) = -256.0/9.0;
2751  A(32,2) = 1024.0*sqrt(2.0)/9.0;
2752  A(32,3) = 1024.0*sqrt(2.0)/9.0;
2753  A(32,10) = -1792.0*sqrt(2.0)/9.0;
2754  A(32,11) = -256.0*sqrt(2.0)/3.0;
2755  A(32,17) = 896*sqrt(2.0)/9.0;
2756  A(32,18) = 128.0*sqrt(2.0)/9.0;
2757  A(32,23) = -128.0*sqrt(2.0)/9.0;
2758  A(31,4) = 1024.0*sqrt(2.0)/9.0;
2759  A(31,5) = 1024.0*sqrt(2.0)/9.0;
2760  A(31,11) = -256.0*sqrt(2.0)/3.0;
2761  A(31,12) = -1792.0*sqrt(2.0)/9.0;
2762  A(31,17) = 128.0*sqrt(2.0)/9.0;
2763  A(31,18) = 896.0*sqrt(2.0)/9.0;
2764  A(31,23) = -128.0*sqrt(2.0)/9.0;
2765  A(34,2) = 4096.0;
2766  A(34,3) = 8192.0;
2767  A(34,4) = 4096.0;
2768  A(34,10) = -9216.0;
2769  A(34,11) = -10240.0;
2770  A(34,12) = -1024.0;
2771  A(34,17) = 6144.0;
2772  A(34,18) = 2048.0;
2773  A(34,23) = -1024.0;
2774  A(33,3) = 4096.0;
2775  A(33,4) = 8192.0;
2776  A(33,5) = 4096.0;
2777  A(33,10) = -1024.0;
2778  A(33,11) = -10240.0;
2779  A(33,12) = -9216.0;
2780  A(33,17) = 2048.0;
2781  A(33,18) = 6144.0;
2782  A(33,23) = -1024.0;
2783  A(35,2) = -4096.0;
2784  A(35,3) = -12288.0;
2785  A(35,4) = -12288.0;
2786  A(35,5) = -4096.0;
2787  A(35,10) = 11264.0;
2788  A(35,11) = 22528.0;
2789  A(35,12) = 11264.0;
2790  A(35,17) = -10240.0;
2791  A(35,18) = -10240.0;
2792  A(35,23) = 3072.0;
2793  }
2794 
2795  ///=========================================================================
2796  /// Bases of the C1-curved shape functions:
2797  /// it is a complete polynomial of degree 7
2798  ///=========================================================================
2799  void basis_curve(const Vector<double> &s, Shape &psi_curve) const
2800  {
2801  //Get the shape function and derivatives
2802  psi_curve[7] = s[0]*s[0]*s[0]*s[0]*s[0]*s[0]*s[0];
2803  psi_curve[6] = s[0]*s[0]*s[0]*s[0]*s[0]*s[0]*s[1];
2804  psi_curve[5] = s[0]*s[0]*s[0]*s[0]*s[0]*s[1]*s[1];
2805  psi_curve[4] = s[0]*s[0]*s[0]*s[0]*s[1]*s[1]*s[1];
2806  psi_curve[3] = s[0]*s[0]*s[0]*s[1]*s[1]*s[1]*s[1];
2807  psi_curve[2] = s[0]*s[0]*s[1]*s[1]*s[1]*s[1]*s[1];
2808  psi_curve[1] = s[0]*s[1]*s[1]*s[1]*s[1]*s[1]*s[1];
2809  psi_curve[0] = s[1]*s[1]*s[1]*s[1]*s[1]*s[1]*s[1];
2810  psi_curve[14] = s[0]*s[0]*s[0]*s[0]*s[0]*s[0];
2811  psi_curve[13] = s[0]*s[0]*s[0]*s[0]*s[0]*s[1];
2812  psi_curve[12] = s[0]*s[0]*s[0]*s[0]*s[1]*s[1];
2813  psi_curve[11] = s[0]*s[0]*s[0]*s[1]*s[1]*s[1];
2814  psi_curve[10] = s[0]*s[0]*s[1]*s[1]*s[1]*s[1];
2815  psi_curve[9] = s[0]*s[1]*s[1]*s[1]*s[1]*s[1];
2816  psi_curve[8] = s[1]*s[1]*s[1]*s[1]*s[1]*s[1];
2817  psi_curve[20] = s[0]*s[0]*s[0]*s[0]*s[0];
2818  psi_curve[19] = s[0]*s[0]*s[0]*s[0]*s[1];
2819  psi_curve[18] = s[0]*s[0]*s[0]*s[1]*s[1];
2820  psi_curve[17] = s[0]*s[0]*s[1]*s[1]*s[1];
2821  psi_curve[16] = s[0]*s[1]*s[1]*s[1]*s[1];
2822  psi_curve[15] = s[1]*s[1]*s[1]*s[1]*s[1];
2823  psi_curve[25] = s[0]*s[0]*s[0]*s[0];
2824  psi_curve[24] = s[0]*s[0]*s[0]*s[1];
2825  psi_curve[23] = s[0]*s[0]*s[1]*s[1];
2826  psi_curve[22] = s[0]*s[1]*s[1]*s[1];
2827  psi_curve[21] = s[1]*s[1]*s[1]*s[1];
2828  psi_curve[29] = s[0]*s[0]*s[0];
2829  psi_curve[28] = s[0]*s[0]*s[1];
2830  psi_curve[27] = s[0]*s[1]*s[1];
2831  psi_curve[26] = s[1]*s[1]*s[1];
2832  psi_curve[32] = s[0]*s[0];
2833  psi_curve[31] = s[0]*s[1];
2834  psi_curve[30] = s[1]*s[1];
2835  psi_curve[34] = s[0];
2836  psi_curve[33] = s[1];
2837  psi_curve[35] = 1.0;
2838  }
2839 
2840  ///=========================================================================
2841  /// Derivatives of bases of the C1-curved shape functions
2842  /// it is a complete polynomial of degree 7
2843  ///=========================================================================
2844  void dbasis_local_curve(const Vector<double> &s, Shape &psi_curve, DShape &dpsi_curve) const
2845  {
2846  basis_curve(s,psi_curve);
2847 
2848  //Get the shape function and derivatives
2849  dpsi_curve(7,0) = 7.0*s[0]*s[0]*s[0]*s[0]*s[0]*s[0];
2850  dpsi_curve(6,0) = 6.0*s[0]*s[0]*s[0]*s[0]*s[0]*s[1];
2851  dpsi_curve(5,0) = 5.0*s[0]*s[0]*s[0]*s[0]*s[1]*s[1];
2852  dpsi_curve(4,0) = 4.0*s[0]*s[0]*s[0]*s[1]*s[1]*s[1];
2853  dpsi_curve(3,0) = 3.0*s[0]*s[0]*s[1]*s[1]*s[1]*s[1];
2854  dpsi_curve(2,0) = 2.0*s[0]*s[1]*s[1]*s[1]*s[1]*s[1];
2855  dpsi_curve(1,0) = 1.0*s[1]*s[1]*s[1]*s[1]*s[1]*s[1];
2856  dpsi_curve(0,0) = 0.0;
2857  dpsi_curve(14,0) = 6.0*s[0]*s[0]*s[0]*s[0]*s[0];
2858  dpsi_curve(13,0) = 5.0*s[0]*s[0]*s[0]*s[0]*s[1];
2859  dpsi_curve(12,0) = 4.0*s[0]*s[0]*s[0]*s[1]*s[1];
2860  dpsi_curve(11,0) = 3.0*s[0]*s[0]*s[1]*s[1]*s[1];
2861  dpsi_curve(10,0) = 2.0*s[0]*s[1]*s[1]*s[1]*s[1];
2862  dpsi_curve(9,0) = 1.0*s[1]*s[1]*s[1]*s[1]*s[1];
2863  dpsi_curve(8,0) = 0.0;
2864  dpsi_curve(20,0) = 5.0*s[0]*s[0]*s[0]*s[0];
2865  dpsi_curve(19,0) = 4.0*s[0]*s[0]*s[0]*s[1];
2866  dpsi_curve(18,0) = 3.0*s[0]*s[0]*s[1]*s[1];
2867  dpsi_curve(17,0) = 2.0*s[0]*s[1]*s[1]*s[1];
2868  dpsi_curve(16,0) = 1.0*s[1]*s[1]*s[1]*s[1];
2869  dpsi_curve(15,0) = 0.0;
2870  dpsi_curve(25,0) = 4.0*s[0]*s[0]*s[0];
2871  dpsi_curve(24,0) = 3.0*s[0]*s[0]*s[1];
2872  dpsi_curve(23,0) = 2.0*s[0]*s[1]*s[1];
2873  dpsi_curve(22,0) = 1.0*s[1]*s[1]*s[1];
2874  dpsi_curve(21,0) = 0.0;
2875  dpsi_curve(29,0) = 3.0*s[0]*s[0];
2876  dpsi_curve(28,0) = 2.0*s[0]*s[1];
2877  dpsi_curve(27,0) = 1.0*s[1]*s[1];
2878  dpsi_curve(26,0) = 0.0;
2879  dpsi_curve(32,0) = 2.0*s[0];
2880  dpsi_curve(31,0) = 1.0*s[1];
2881  dpsi_curve(30,0) = 0.0;
2882  dpsi_curve(34,0) = 1.0;
2883  dpsi_curve(33,0) = 0.0;
2884  dpsi_curve(35,0) = 0.0;
2885 
2886  dpsi_curve(7,1) = 0.0;
2887  dpsi_curve(6,1) = s[0]*s[0]*s[0]*s[0]*s[0]*s[0]*1.0;
2888  dpsi_curve(5,1) = s[0]*s[0]*s[0]*s[0]*s[0]*s[1]*2.0;
2889  dpsi_curve(4,1) = s[0]*s[0]*s[0]*s[0]*s[1]*s[1]*3.0;
2890  dpsi_curve(3,1) = s[0]*s[0]*s[0]*s[1]*s[1]*s[1]*4.0;
2891  dpsi_curve(2,1) = s[0]*s[0]*s[1]*s[1]*s[1]*s[1]*5.0;
2892  dpsi_curve(1,1) = s[0]*s[1]*s[1]*s[1]*s[1]*s[1]*6.0;
2893  dpsi_curve(0,1) = s[1]*s[1]*s[1]*s[1]*s[1]*s[1]*7.0;
2894  dpsi_curve(14,1) = 0.0;
2895  dpsi_curve(13,1) = s[0]*s[0]*s[0]*s[0]*s[0]*1.0;
2896  dpsi_curve(12,1) = s[0]*s[0]*s[0]*s[0]*s[1]*2.0;
2897  dpsi_curve(11,1) = s[0]*s[0]*s[0]*s[1]*s[1]*3.0;
2898  dpsi_curve(10,1) = s[0]*s[0]*s[1]*s[1]*s[1]*4.0;
2899  dpsi_curve(9,1) = s[0]*s[1]*s[1]*s[1]*s[1]*5.0;
2900  dpsi_curve(8,1) = s[1]*s[1]*s[1]*s[1]*s[1]*6.0;
2901  dpsi_curve(20,1) = 0.0;
2902  dpsi_curve(19,1) = s[0]*s[0]*s[0]*s[0]*1.0;
2903  dpsi_curve(18,1) = s[0]*s[0]*s[0]*s[1]*2.0;
2904  dpsi_curve(17,1) = s[0]*s[0]*s[1]*s[1]*3.0;
2905  dpsi_curve(16,1) = s[0]*s[1]*s[1]*s[1]*4.0;
2906  dpsi_curve(15,1) = s[1]*s[1]*s[1]*s[1]*5.0;
2907  dpsi_curve(25,1) = 0.0;
2908  dpsi_curve(24,1) = s[0]*s[0]*s[0]*1.0;
2909  dpsi_curve(23,1) = s[0]*s[0]*s[1]*2.0;
2910  dpsi_curve(22,1) = s[0]*s[1]*s[1]*3.0;
2911  dpsi_curve(21,1) = s[1]*s[1]*s[1]*4.0;
2912  dpsi_curve(29,1) = 0.0;
2913  dpsi_curve(28,1) = s[0]*s[0]*1.0;
2914  dpsi_curve(27,1) = s[0]*s[1]*2.0;
2915  dpsi_curve(26,1) = s[1]*s[1]*3.0;
2916  dpsi_curve(32,1) = 0.0;
2917  dpsi_curve(31,1) = s[0]*1.0;
2918  dpsi_curve(30,1) = s[1]*2.0;
2919  dpsi_curve(34,1) = 0.0;
2920  dpsi_curve(33,1) = 1.0;
2921  dpsi_curve(35,1) = 0.0;
2922  }
2923 
2924  ///=========================================================================
2925  /// The second derivatived of bases of the C1-curved shape functions
2926  /// it is a complete polynomial of degree 7
2927  ///=========================================================================
2928  void d2basis_local_curve(const Vector<double> &s, Shape &psi_curve, DShape &dpsi_curve, DShape &d2psi_curve) const
2929  {
2930  dbasis_local_curve(s,psi_curve,dpsi_curve);
2931  //Get the shape function and derivatives
2932  d2psi_curve(7,0) = 7.0*6.0*s[0]*s[0]*s[0]*s[0]*s[0];
2933  d2psi_curve(6,0) = 6.0*5.0*s[0]*s[0]*s[0]*s[0]*s[1];
2934  d2psi_curve(5,0) = 5.0*4.0*s[0]*s[0]*s[0]*s[1]*s[1];
2935  d2psi_curve(4,0) = 4.0*3.0*s[0]*s[0]*s[1]*s[1]*s[1];
2936  d2psi_curve(3,0) = 3.0*2.0*s[0]*s[1]*s[1]*s[1]*s[1];
2937  d2psi_curve(2,0) = 2.0*1.0*s[1]*s[1]*s[1]*s[1]*s[1];
2938  d2psi_curve(1,0) = 0.0;
2939  d2psi_curve(0,0) = 0.0;
2940  d2psi_curve(14,0) = 6.0*5.0*s[0]*s[0]*s[0]*s[0];
2941  d2psi_curve(13,0) = 5.0*4.0*s[0]*s[0]*s[0]*s[1];
2942  d2psi_curve(12,0) = 4.0*3.0*s[0]*s[0]*s[1]*s[1];
2943  d2psi_curve(11,0) = 3.0*2.0*s[0]*s[1]*s[1]*s[1];
2944  d2psi_curve(10,0) = 2.0*1.0*s[1]*s[1]*s[1]*s[1];
2945  d2psi_curve(9,0) = 0.0;
2946  d2psi_curve(8,0) = 0.0;
2947  d2psi_curve(20,0) = 5.0*4.0*s[0]*s[0]*s[0];
2948  d2psi_curve(19,0) = 4.0*3.0*s[0]*s[0]*s[1];
2949  d2psi_curve(18,0) = 3.0*2.0*s[0]*s[1]*s[1];
2950  d2psi_curve(17,0) = 2.0*1.0*s[1]*s[1]*s[1];
2951  d2psi_curve(16,0) = 0.0;
2952  d2psi_curve(15,0) = 0.0;
2953  d2psi_curve(25,0) = 4.0*3.0*s[0]*s[0];
2954  d2psi_curve(24,0) = 3.0*2.0*s[0]*s[1];
2955  d2psi_curve(23,0) = 2.0*1.0*s[1]*s[1];
2956  d2psi_curve(22,0) = 0.0;
2957  d2psi_curve(21,0) = 0.0;
2958  d2psi_curve(29,0) = 3.0*2.0*s[0];
2959  d2psi_curve(28,0) = 2.0*1.0*s[1];
2960  d2psi_curve(27,0) = 0.0;
2961  d2psi_curve(26,0) = 0.0;
2962  d2psi_curve(32,0) = 2.0*1.0;
2963  d2psi_curve(31,0) = 0.0;
2964  d2psi_curve(30,0) = 0.0;
2965  d2psi_curve(34,0) = 0.0;
2966  d2psi_curve(33,0) = 0.0;
2967  d2psi_curve(35,0) = 0.0;
2968 
2969  d2psi_curve(7,1) = 0.0;
2970  d2psi_curve(6,1) = 0.0;
2971  d2psi_curve(5,1) = s[0]*s[0]*s[0]*s[0]*s[0]*1.0*2.0;
2972  d2psi_curve(4,1) = s[0]*s[0]*s[0]*s[0]*s[1]*2.0*3.0;
2973  d2psi_curve(3,1) = s[0]*s[0]*s[0]*s[1]*s[1]*3.0*4.0;
2974  d2psi_curve(2,1) = s[0]*s[0]*s[1]*s[1]*s[1]*4.0*5.0;
2975  d2psi_curve(1,1) = s[0]*s[1]*s[1]*s[1]*s[1]*5.0*6.0;
2976  d2psi_curve(0,1) = s[1]*s[1]*s[1]*s[1]*s[1]*6.0*7.0;
2977  d2psi_curve(14,1) = 0.0;
2978  d2psi_curve(13,1) = 0.0;
2979  d2psi_curve(12,1) = s[0]*s[0]*s[0]*s[0]*1.0*2.0;
2980  d2psi_curve(11,1) = s[0]*s[0]*s[0]*s[1]*2.0*3.0;
2981  d2psi_curve(10,1) = s[0]*s[0]*s[1]*s[1]*3.0*4.0;
2982  d2psi_curve(9,1) = s[0]*s[1]*s[1]*s[1]*4.0*5.0;
2983  d2psi_curve(8,1) = s[1]*s[1]*s[1]*s[1]*5.0*6.0;
2984  d2psi_curve(20,1) = 0.0;
2985  d2psi_curve(19,1) = 0.0;
2986  d2psi_curve(18,1) = s[0]*s[0]*s[0]*1.0*2.0;
2987  d2psi_curve(17,1) = s[0]*s[0]*s[1]*2.0*3.0;
2988  d2psi_curve(16,1) = s[0]*s[1]*s[1]*3.0*4.0;
2989  d2psi_curve(15,1) = s[1]*s[1]*s[1]*4.0*5.0;
2990  d2psi_curve(25,1) = 0.0;
2991  d2psi_curve(24,1) = 0.0;
2992  d2psi_curve(23,1) = s[0]*s[0]*1.0*2.0;
2993  d2psi_curve(22,1) = s[0]*s[1]*2.0*3.0;
2994  d2psi_curve(21,1) = s[1]*s[1]*3.0*4.0;
2995  d2psi_curve(29,1) = 0.0;
2996  d2psi_curve(28,1) = 0.0;
2997  d2psi_curve(27,1) = s[0]*1.0*2.0;
2998  d2psi_curve(26,1) = s[1]*2.0*3.0;
2999  d2psi_curve(32,1) = 0.0;
3000  d2psi_curve(31,1) = 0.0;
3001  d2psi_curve(30,1) = 1.0*2.0;
3002  d2psi_curve(34,1) = 0.0;
3003  d2psi_curve(33,1) = 0.0;
3004  d2psi_curve(35,1) = 0.0;
3005 
3006  d2psi_curve(7,2) = 0.0;
3007  d2psi_curve(6,2) = 6.0*s[0]*s[0]*s[0]*s[0]*s[0]*1.0;
3008  d2psi_curve(5,2) = 5.0*s[0]*s[0]*s[0]*s[0]*s[1]*2.0;
3009  d2psi_curve(4,2) = 4.0*s[0]*s[0]*s[0]*s[1]*s[1]*3.0;
3010  d2psi_curve(3,2) = 3.0*s[0]*s[0]*s[1]*s[1]*s[1]*4.0;
3011  d2psi_curve(2,2) = 2.0*s[0]*s[1]*s[1]*s[1]*s[1]*5.0;
3012  d2psi_curve(1,2) = s[1]*s[1]*s[1]*s[1]*s[1]*6.0;
3013  d2psi_curve(0,2) = 0.0;
3014  d2psi_curve(14,2) = 0.0;
3015  d2psi_curve(13,2) = 5.0*s[0]*s[0]*s[0]*s[0]*1.0;
3016  d2psi_curve(12,2) = 4.0*s[0]*s[0]*s[0]*s[1]*2.0;
3017  d2psi_curve(11,2) = 3.0*s[0]*s[0]*s[1]*s[1]*3.0;
3018  d2psi_curve(10,2) = 2.0*s[0]*s[1]*s[1]*s[1]*4.0;
3019  d2psi_curve(9,2) = s[1]*s[1]*s[1]*s[1]*5.0;
3020  d2psi_curve(8,2) = 0.0;
3021  d2psi_curve(20,2) = 0.0;
3022  d2psi_curve(19,2) = 4.0*s[0]*s[0]*s[0]*1.0;
3023  d2psi_curve(18,2) = 3.0*s[0]*s[0]*s[1]*2.0;
3024  d2psi_curve(17,2) = 2.0*s[0]*s[1]*s[1]*3.0;
3025  d2psi_curve(16,2) = s[1]*s[1]*s[1]*4.0;
3026  d2psi_curve(15,2) = 0.0;
3027  d2psi_curve(25,2) = 0.0;
3028  d2psi_curve(24,2) = 3.0*s[0]*s[0]*1.0;
3029  d2psi_curve(23,2) = 2.0*s[0]*s[1]*2.0;
3030  d2psi_curve(22,2) = s[1]*s[1]*3.0;
3031  d2psi_curve(21,2) = 0.0;
3032  d2psi_curve(29,2) = 0.0;
3033  d2psi_curve(28,2) = 2.0*s[0]*1.0;
3034  d2psi_curve(27,2) = s[1]*2.0;
3035  d2psi_curve(26,2) = 0.0;
3036  d2psi_curve(32,2) = 0.0;
3037  d2psi_curve(31,2) = 1.0;
3038  d2psi_curve(30,2) = 0.0;
3039  d2psi_curve(34,2) = 0.0;
3040  d2psi_curve(33,2) = 0.0;
3041  d2psi_curve(35,2) = 0.0;
3042  }
3043  };
3044 
3045 //========================================================================
3046 /// Empty base class for the subparametric Bellelements (created so that
3047 /// we can use dynamic_cast<>() to figure out if a an element
3048 /// is a C1Curvedelement). This element is sub-parametric which means
3049 /// the geometry will be parametrised by the linear Lagrange functions,
3050 /// while unknowns will be parametrised by two kinds of shape functions
3051 /// basis : denotes C1-interpolations for c1-variables
3052 /// basis_c0 : denotes C0-interpolations for c0-variables
3053 //========================================================================
3054 
3055 template<unsigned NNODE_1D>
3056 class BellElementBase: public virtual FiniteElement
3057 {
3058 public:
3059  ///\short Constructor: Call constructors for FiniteElement
3061 
3062 
3063  virtual void basis(const Vector<double> &s, Shape &psi) const
3064  {}
3065 
3066 
3067  virtual void dbasis_local(const Vector<double> &s, Shape &psi,
3068  DShape &dpsids) const
3069  {}
3070 
3071  virtual void d2basis_local(const Vector<double> &s,
3072  Shape &psi,
3073  DShape &dpsids,
3074  DShape &d2psids) const
3075  {}
3076 
3077  virtual void basis_c0(const Vector<double> &s, Shape &psi) const
3078  {}
3079 
3080 
3081  virtual void dbasis_c0_local(const Vector<double> &s, Shape &psi,
3082  DShape &dpsids) const
3083  {}
3084 
3085  virtual void d2basis_c0_local(const Vector<double> &s,
3086  Shape &psi,
3087  DShape &dpsids,
3088  DShape &d2psids) const
3089  {}
3090 
3091  virtual void test(const Vector<double> &s, Shape &phi) const
3092  {}
3093 
3094 
3095  virtual void dtest_local(const Vector<double> &s, Shape &phi,
3096  DShape &dphids) const
3097  {}
3098 
3099  virtual void d2test_local(const Vector<double> &s,
3100  Shape &phi,
3101  DShape &dphids,
3102  DShape &d2phids) const
3103  {}
3104 
3105 
3106  //=========================================================================
3107  /// \short Return the C1-basis function stored at the ipt-th integration
3108  /// point.
3109  //=========================================================================
3110  void basis_at_knot(const unsigned &ipt, Shape &psi) const
3111  {
3112  //Find the dimension of the element
3113  const unsigned el_dim = dim();
3114  //Storage for the local coordinates of the integration point
3115  Vector<double> s(el_dim);
3116  //Set the local coordinate
3117  for(unsigned i=0;i<el_dim;i++) {s[i] = integral_pt()->knot(ipt,i);}
3118  //Get the shape function
3119  basis(s,psi);
3120  }
3121 
3122  //=========================================================================
3123  /// \short Return the C1-basis function and its derivatives w.r.t. the global
3124  /// coordinates at the ipt-th integration point.
3125  //=========================================================================
3126  void dbasis_local_at_knot(const unsigned &ipt, Shape &psi,
3127  DShape &dpsids) const
3128  {
3129  //Find the dimension of the element
3130  const unsigned el_dim = dim();
3131  //Storage for the local coordinates of the integration point
3132  Vector<double> s(el_dim);
3133  //Set the local coordinate
3134  for(unsigned i=0;i<el_dim;i++) {s[i] = integral_pt()->knot(ipt,i);}
3135 
3136  //Get the shape function and derivatives
3137  dbasis_local(s,psi,dpsids);
3138  }
3139 
3140  //=========================================================================
3141  /// Calculate the C1-basis function and its first and second derivatives
3142  /// w.r.t. global coordinates at the ipt-th integration point.
3143  /// \n\n Numbering:
3144  //=========================================================================
3145  void d2basis_local_at_knot(const unsigned &ipt, Shape &psi,
3146  DShape &dpsids, DShape &d2psids)
3147  const
3148  {
3149  //Find the dimension of the element
3150  const unsigned el_dim = dim();
3151  //Storage for the local coordinates of the integration point
3152  Vector<double> s(el_dim);
3153  //Set the local coordinate
3154  for(unsigned i=0;i<el_dim;i++) {s[i] = integral_pt()->knot(ipt,i);}
3155 
3156  //Get the shape function and first and second derivatives
3157  d2basis_local(s,psi,dpsids,d2psids);
3158  }
3159 
3160  //=========================================================================
3161  /// \short Return the C0-basis function stored at the ipt-th integration
3162  /// point.
3163  //=========================================================================
3164  void basis_c0_at_knot(const unsigned &ipt, Shape &psi) const
3165  {
3166  //Find the dimension of the element
3167  const unsigned el_dim = dim();
3168  //Storage for the local coordinates of the integration point
3169  Vector<double> s(el_dim);
3170  //Set the local coordinate
3171  for(unsigned i=0;i<el_dim;i++) {s[i] = integral_pt()->knot(ipt,i);}
3172  //Get the shape function
3173  basis_c0(s,psi);
3174  }
3175 
3176  //=========================================================================
3177  /// \short Return the C0-basis function and its derivatives w.r.t. the local
3178  /// coordinates at the ipt-th integration point.
3179  //=========================================================================
3180  void dbasis_c0_local_at_knot(const unsigned &ipt, Shape &psi,
3181  DShape &dpsids) const
3182  {
3183  //Find the dimension of the element
3184  const unsigned el_dim = dim();
3185  //Storage for the local coordinates of the integration point
3186  Vector<double> s(el_dim);
3187  //Set the local coordinate
3188  for(unsigned i=0;i<el_dim;i++) {s[i] = integral_pt()->knot(ipt,i);}
3189  //Get the shape function and derivatives
3190 
3191  dbasis_c0_local(s,psi,dpsids);
3192 
3193  }
3194 
3195  //=========================================================================
3196  /// Calculate the C0-basis function and its first and second derivatives
3197  /// w.r.t. local coordinates at the ipt-th integration point.
3198  /// \n\n Numbering:
3199  //=========================================================================
3200  void d2basis_c0_local_at_knot(const unsigned &ipt, Shape &psi,
3201  DShape &dpsids, DShape &d2psids)
3202  const
3203  {
3204  //Find the dimension of the element
3205  const unsigned el_dim = dim();
3206  //Storage for the local coordinates of the integration point
3207  Vector<double> s(el_dim);
3208  //Set the local coordinate
3209  for(unsigned i=0;i<el_dim;i++) {s[i] = integral_pt()->knot(ipt,i);}
3210  //Get the shape function and first and second derivatives
3211  d2basis_c0_local(s,psi,dpsids,d2psids);
3212 
3213  }
3214 
3215  //=========================================================================
3216  /// \short Return the test function stored at the ipt-th integration
3217  /// point.
3218  //=========================================================================
3219  void test_at_knot(const unsigned &ipt, Shape &phi) const
3220  {
3221  //Find the dimension of the element
3222  const unsigned el_dim = dim();
3223  //Storage for the local coordinates of the integration point
3224  Vector<double> s(el_dim);
3225  //Set the local coordinate
3226  for(unsigned i=0;i<el_dim;i++) {s[i] = integral_pt()->knot(ipt,i);}
3227  //Get the shape function
3228  test(s,phi);
3229  }
3230 
3231  //=========================================================================
3232  /// \short Return the test function and its derivatives w.r.t. the local
3233  /// coordinates at the ipt-th integration point.
3234  //=========================================================================
3235  void dtest_local_at_knot(const unsigned &ipt, Shape &phi,
3236  DShape &dphids) const
3237  {
3238  //Find the dimension of the element
3239  const unsigned el_dim = dim();
3240  //Storage for the local coordinates of the integration point
3241  Vector<double> s(el_dim);
3242  //Set the local coordinate
3243  for(unsigned i=0;i<el_dim;i++) {s[i] = integral_pt()->knot(ipt,i);}
3244  //Get the shape function and derivatives
3245  dtest_local(s,phi,dphids);
3246  }
3247 
3248  //=========================================================================
3249  /// Calculate the test function and its first and second derivatives
3250  /// w.r.t. local coordinates at the ipt-th integration point.
3251  /// \n\n Numbering:
3252  //=========================================================================
3253  void d2test_local_at_knot(const unsigned &ipt, Shape &phi,
3254  DShape &dphids, DShape &d2phids)
3255  const
3256  {
3257  //Find the dimension of the element
3258  const unsigned el_dim = dim();
3259  //Storage for the local coordinates of the integration point
3260  Vector<double> s(el_dim);
3261  //Set the local coordinate
3262  for(unsigned i=0;i<el_dim;i++) {s[i] = integral_pt()->knot(ipt,i);}
3263  //Get the shape function and first and second derivatives
3264  d2test_local(s,phi,dphids,d2phids);
3265  }
3266 
3267  //=========================================================================
3268  /// \short Compute the curved-element shape functions and also
3269  /// first derivatives w.r.t. local coordinates at local coordinate s;
3270  /// Returns Jacobian of mapping from global to local coordinates.
3271  /// Most general form of the function, but may be over-loaded, if desired
3272  //=========================================================================
3274  Shape &psi,
3275  DShape &dpsi) const
3276  {
3277  //Find the element dimension
3278  const unsigned el_dim = dim();
3279  //Get the values of the shape functions and their local derivatives
3280  //Temporarily stored in dpsi
3281  dbasis_c0_local(s,psi,dpsi);
3282 
3283  // assign shape functions for geometry
3284  unsigned n_node = 3;
3285  Shape psi_x(n_node);
3286  DShape dpsi_x(n_node,2);
3287  DShape d2psi_x(n_node,3);
3288 
3289  d2shape_local(s,psi_x,dpsi_x,d2psi_x);
3290 
3291  //Allocate memory for the jacobian and inverse jacobian
3292  DenseMatrix<double> jacobian(el_dim), inverse_jacobian(el_dim);
3293 
3294  //Calculate the jacobian and inverse jacobian
3295  const double det = this->local_to_eulerian_mapping2(dpsi_x,jacobian,inverse_jacobian);
3296 
3297  //Now set the values of the derivatives to be dpsidx
3298  transform_derivatives(inverse_jacobian,dpsi);
3299 
3300  //Return the determinant of the jacobian
3301  return det;
3302  }
3303 
3304  //===========================================================================
3305  /// \short Compute the c0-basis functions and also first
3306  /// and second derivatives w.r.t. local coordinates at ipt-th integration
3307  /// point
3308  //===========================================================================
3310  DShape &dpsi,
3311  DShape &d2psi) const
3312  {
3313  //Find the element dimension
3314  const unsigned el_dim = dim();
3315  //Find the number of second derivatives required
3316  const unsigned n_deriv = N2deriv[el_dim];
3317  //Get the values of the shape function and local derivatives for unknowns
3318  d2basis_c0_local(s,psi,dpsi,d2psi);
3319 
3320  // assign shape functions for geometry
3321  unsigned n_node = 3;
3322  Shape psi_x(n_node);
3323  DShape dpsi_x(n_node,2);
3324  DShape d2psi_x(n_node,3);
3325 
3326  d2shape_local(s,psi_x,dpsi_x,d2psi_x);
3327 
3328  //Allocate memory for the jacobian and inverse jacobian
3329  DenseMatrix<double> jacobian(el_dim), inverse_jacobian(el_dim);
3330 
3331  //Calculate the jacobian and inverse jacobian
3332  const double det = local_to_eulerian_mapping2(dpsi_x,jacobian,inverse_jacobian);
3333 
3334  //Allocate memory for the jacobian of second derivatives
3335  DenseMatrix<double> jacobian2(n_deriv,el_dim,0.0);
3336 
3337  //Assemble the jacobian of second derivatives
3338  myassemble_local_to_eulerian_jacobian2(d2psi_x,jacobian2);
3339 
3340  //Now set the value of the derivatives
3341  transform_second_derivatives(jacobian,inverse_jacobian,jacobian2,dpsi,d2psi);
3342 
3343  //Return the determinant of the jacobian
3344  return det;
3345  }
3346 
3347  //=========================================================================
3348  /// \short Compute the c1-basis functions and also
3349  /// first derivatives w.r.t. global coordinates at local coordinate s;
3350  /// Returns Jacobian of mapping from global to local coordinates.
3351  /// Most general form of the function, but may be over-loaded, if desired
3352  //=========================================================================
3354  Shape &psi,
3355  DShape &dpsi) const
3356  {
3357  //Find the element dimension
3358  const unsigned el_dim = dim();
3359  //Get the values of the shape functions and their local derivatives
3360  //Temporarily stored in dpsi
3361  dbasis_local(s,psi,dpsi);
3362 
3363  // assign shape functions for geometry
3364  unsigned n_node = 3;
3365  Shape psi_x(n_node);
3366  DShape dpsi_x(n_node,2);
3367  DShape d2psi_x(n_node,3);
3368 
3369  d2shape_local(s,psi_x,dpsi_x,d2psi_x);
3370 
3371  //Allocate memory for the jacobian and inverse jacobian
3372  DenseMatrix<double> jacobian(el_dim), inverse_jacobian(el_dim);
3373 
3374  //Calculate the jacobian and inverse jacobian
3375  const double det = this->local_to_eulerian_mapping2(dpsi_x,jacobian,inverse_jacobian);
3376 
3377  //Return the determinant of the jacobian
3378  return det;
3379  }
3380 
3381  //===========================================================================
3382  /// \short Compute the c1-basis functions and also first
3383  /// and second derivatives w.r.t. global coordinates at ipt-th integration
3384  /// point
3385  //===========================================================================
3386  double d2basis_eulerian(const Vector<double> &s, Shape &psi,
3387  DShape &dpsi,
3388  DShape &d2psi) const
3389  {
3390  //Find the element dimension
3391  const unsigned el_dim = dim();
3392  //Find the number of second derivatives required
3393  //const unsigned n_deriv = N2deriv[el_dim];
3394  //Get the values of the shape function and local derivatives for unknowns
3395  d2basis_local(s,psi,dpsi,d2psi);
3396 
3397  // assign shape functions for geometry
3398  unsigned n_node = 3;
3399  Shape psi_x(n_node);
3400  DShape dpsi_x(n_node,2);
3401  DShape d2psi_x(n_node,3);
3402 
3403  d2shape_local(s,psi_x,dpsi_x,d2psi_x);
3404 
3405  //Allocate memory for the jacobian and inverse jacobian
3406  DenseMatrix<double> jacobian(el_dim), inverse_jacobian(el_dim);
3407 
3408  //Calculate the jacobian and inverse jacobian
3409  const double det = local_to_eulerian_mapping2(dpsi_x,jacobian,inverse_jacobian);
3410 
3411  //Return the determinant of the jacobian
3412  return det;
3413  }
3414 
3415  //=========================================================================
3416  /// Calculate the c0-shape function and its first-order derivatives
3417  /// w.r.t. local coordinates at the ipt-th integration point.
3418  /// \n\n Numbering:
3419  //=========================================================================
3420 
3421  double dshape_and_dtest_eulerian_at_knot(const unsigned &ipt, Shape &psi, DShape &dpsi, Shape &test, DShape &dtest)
3422  const
3423  {
3424  //Find the element dimension
3425  const unsigned el_dim = dim();
3426 
3427  //Get the values of the c0-shape function for c0-unknowns
3428  //and local derivatives
3429  //Temporarily store it in dpsi
3430  dbasis_c0_local_at_knot(ipt,psi,dpsi);
3431 
3432  // assign shape functions for geometry -> linear Lagrange
3433  unsigned n_node = 3;
3434  Shape psi_x(n_node);
3435  DShape dpsi_x(n_node,2);
3436  dshape_local_at_knot(ipt,psi_x,dpsi_x);
3437 
3438  // assign test function
3439  dtest_local_at_knot(ipt,test,dtest);
3440 
3441  //Allocate memory for the inverse jacobian
3442  DenseMatrix<double> inverse_jacobian(el_dim);
3443  //Now calculate the inverse jacobian
3444  const double det = local_to_eulerian_mapping2(dpsi_x,inverse_jacobian);
3445 
3446  //Now set the values of the derivatives to dpsidx
3447  transform_derivatives(inverse_jacobian,dpsi);
3448 
3449  //Return the determinant of the jacobian
3450  return det;
3451  }
3452 
3453  //===========================================================================
3454  /// \short Compute the c1-shape functions and also first and second
3455  /// derivatives w.r.t. global coordinates at ipt-th integration points
3456  /// Returns Jacobian of mapping from global to local coordinates.
3457  //===========================================================================
3458  double d2shape_and_d2test_eulerian_at_knot(const unsigned &ipt,
3459  Shape &psi,
3460  DShape &dpsi,
3461  DShape &d2psi,
3462  Shape &test,
3463  DShape &dtest,
3464  DShape &d2test) const
3465  {
3466  //Find the element dimension
3467  const unsigned el_dim = dim();
3468 
3469  //Get the values of the shape function and local derivatives for unknowns
3470  d2basis_local_at_knot(ipt,psi,dpsi,d2psi);
3471 
3472  // assign shape functions for geometry
3473  unsigned n_node = nnode();
3474  Shape psi_x(n_node);
3475  DShape dpsi_x(n_node,2);
3476  DShape d2psi_x(n_node,3);
3477  dshape_local_at_knot(ipt,psi_x,dpsi_x);
3478 
3479  // assign for test function
3480  d2test_local_at_knot(ipt,test,dtest,d2test);
3481 
3482  //Allocate memory for the jacobian and inverse jacobian
3483  DenseMatrix<double> jacobian(el_dim), inverse_jacobian(el_dim);
3484 
3485  //Calculate the jacobian and inverse jacobian
3486  const double det = local_to_eulerian_mapping2(dpsi_x,jacobian,inverse_jacobian);
3487 
3488  //Return the determinant of the mapping
3489  return det;
3490  }
3491 
3492  //===========================================================================
3493  /// \short Calculate the mapping from local to Eulerian coordinates,
3494  /// given the derivatives of the shape functions w.r.t. local coordinates,
3495  /// Return only the determinant of the jacobian and the inverse of the
3496  /// mapping (ds/dx).
3497  //===========================================================================
3498  double local_to_eulerian_mapping2(const DShape &dpsids,
3499  DenseMatrix<double> &inverse_jacobian) const
3500  {
3501  //Find the dimension of the element
3502  const unsigned el_dim = dim();
3503  //Assign memory for the jacobian
3504  DenseMatrix<double> jacobian(el_dim);
3505  //Calculate the jacobian and inverse
3506  return local_to_eulerian_mapping2(dpsids,jacobian,inverse_jacobian);
3507  }
3508 
3509  ///////////////////////////////////////////////////////////////
3510  virtual double local_to_eulerian_mapping2(const DShape &dpsids,
3511  DenseMatrix<double> &jacobian,
3512  DenseMatrix<double> &inverse_jacobian) const
3513  {
3514  //Assemble the jacobian
3515  //Locally cache the elemental dimension
3516  const unsigned el_dim = dim();
3517  //The number of shape functions must be equal to the number
3518  //of nodes (by definition)
3519  const unsigned n_shape = 3;
3520  //The number of shape function types must be equal to the number
3521  //of nodal position types (by definition)
3522  const unsigned n_shape_type = 1;
3523 
3524  //Loop over the rows of the jacobian
3525  for(unsigned i=0;i<el_dim;i++)
3526  {
3527  //Loop over the columns of the jacobian
3528  for(unsigned j=0;j<el_dim;j++)
3529  {
3530  //Zero the entry
3531  jacobian(i,j) = 0.0;
3532  //Loop over the shape functions
3533  for(unsigned l=0;l<n_shape;l++)
3534  {
3535  for(unsigned k=0;k<n_shape_type;k++)
3536  {
3537  //Jacobian is dx_j/ds_i, which is represented by the sum
3538  //over the dpsi/ds_i of the nodal points X j
3539  //Call the Non-hanging version of positions
3540  //This is overloaded in refineable elements
3541  jacobian(i,j) += raw_nodal_position_gen(l,k,j)*dpsids(l,k,i);
3542  }
3543  }
3544  }
3545  }
3546 
3547  //Invert the jacobian (use the template-free interface)
3548  return invert_jacobian_mapping(jacobian,inverse_jacobian);
3549  }
3550 
3551  //========================================================================
3552  /// \short Calculate the Jacobian of the mapping between local and global
3553  /// coordinates at the position s
3554  //========================================================================
3555  double J_eulerian1(const Vector<double> &s) const
3556  {
3557  //Find the number of nodes and position types
3558  const unsigned n_node = 3;
3559  const unsigned n_position_type = 1;
3560  //Find the dimension of the node and element
3561  const unsigned n_dim_node = nodal_dimension();
3562  const unsigned n_dim_element = dim();
3563 
3564 
3565  //Set up dummy memory for the shape functions
3566  Shape psi(n_node,n_position_type);
3567  DShape dpsids(n_node,n_position_type,n_dim_element);
3568  //Get the shape functions and local derivatives
3569  this->dshape_local(s,psi,dpsids);
3570 
3571  //Right calculate the base vectors
3572  DenseMatrix<double> interpolated_G(n_dim_element,n_dim_node);
3573 
3574  //Loop over the dimensions and compute the entries of the
3575  //base vector matrix
3576  for(unsigned i=0;i<n_dim_element;i++)
3577  {
3578  for(unsigned j=0;j<n_dim_node;j++)
3579  {
3580  //Initialise the j-th component of the i-th base vector to zero
3581  interpolated_G(i,j) = 0.0;
3582  for(unsigned l=0;l<n_node;l++)
3583  {
3584  for(unsigned k=0;k<n_position_type;k++)
3585  {
3586  interpolated_G(i,j) += raw_nodal_position_gen(l,k,j)*dpsids(l,k,i);
3587  }
3588  }
3589  }
3590  }
3591 
3592  //Calculate the metric tensor of the element
3593  DenseMatrix<double> G(n_dim_element);
3594  for(unsigned i=0;i<n_dim_element;i++)
3595  {
3596  for(unsigned j=0;j<n_dim_element;j++)
3597  {
3598  //Initialise to zero
3599  G(i,j) = 0.0;
3600  for(unsigned k=0;k<n_dim_node;k++)
3601  {
3602  G(i,j) += interpolated_G(i,k)*interpolated_G(j,k);
3603  }
3604  }
3605  }
3606 
3607  //Calculate the determinant of the metric tensor
3608  double det = 0.0;
3609  switch(n_dim_element)
3610  {
3611  case 0:
3612  throw OomphLibError("Cannot calculate J_eulerian() for point element\n",
3613  "FiniteElement::J_eulerian()",
3614  OOMPH_EXCEPTION_LOCATION);
3615  break;
3616  case 1:
3617  det = G(0,0);
3618  break;
3619  case 2:
3620  det = G(0,0)*G(1,1) - G(0,1)*G(1,0);
3621  break;
3622  case 3:
3623  det = G(0,0)*G(1,1)*G(2,2) + G(0,1)*G(1,2)*G(2,0) + G(0,2)*G(1,0)*G(2,1)
3624  - G(0,0)*G(1,2)*G(2,1) - G(0,1)*G(1,0)*G(2,2) - G(0,2)*G(1,1)*G(2,0);
3625  break;
3626  default:
3627  oomph_info << "More than 3 dimensions in J_eulerian()" << std::endl;
3628  break;
3629  }
3630 
3631 #ifdef PARANOID
3632  check_jacobian(det);
3633 #endif
3634 
3635  //Return the Jacobian (square-root of the determinant of the metric tensor)
3636  return sqrt(det);
3637 
3638  }
3639 
3640  //=========================================================================
3641  /// Internal function that is used to assemble the jacobian of second
3642  /// derivatives of the the mapping from local coordinates (s) to the
3643  /// eulerian coordinates (x), given the second derivatives of the
3644  /// shape functions.
3645  //=========================================================================
3647  DenseMatrix<double> &jacobian2) const
3648  {
3649  //Find the the dimension of the element
3650  const unsigned el_dim = dim();
3651  //Find the number of shape functions and shape functions types
3652  //Must be equal to the number of nodes and their position types
3653  //by the definition of the shape function.
3654  const unsigned n_shape = 3;
3655  unsigned n_shape_type = 1;
3656  //Find the number of second derivatives
3657  const unsigned n_row = N2deriv[el_dim];
3658  //Assemble the "jacobian" (d^2 x_j/ds_i^2) for second derivatives of
3659  //shape functions
3660  //Loop over the rows (number of second derivatives)
3661  for(unsigned i=0;i<n_row;i++)
3662  {
3663  //Loop over the columns (element dimension
3664  for(unsigned j=0;j<el_dim;j++)
3665  {
3666  //Zero the entry
3667  jacobian2(i,j) = 0.0;
3668  //Loop over the shape functions
3669  for(unsigned l=0;l<n_shape;l++)
3670  {
3671  //Loop over the shape function types
3672  for(unsigned k=0;k<n_shape_type;k++)
3673  {
3674  //Add the terms to the jacobian entry
3675  //Call the Non-hanging version of positions
3676  //This is overloaded in refineable elements
3677  jacobian2(i,j) += raw_nodal_position_gen(l,k,j)*d2psids(l,k,i);
3678  }
3679  }
3680  }
3681  }
3682  }
3683 
3684  //=======================================================================
3685  /// Return FE interpolated position x[] at local coordinate s as Vector
3686  // (using linear Lagrange interpolation)
3687  //=======================================================================
3689  const
3690  {
3691  //Find the number of nodes
3692  const unsigned n_node = 3;
3693  //Find the number of positional types
3694  const unsigned n_position_type = 1;
3695 
3696  //Find the dimension stored in the node
3697  const unsigned nodal_dim = nodal_dimension();
3698 
3699  //Assign storage for the local shape function
3700  Shape psi(n_node);
3701  //Find the values of shape function
3702  shape(s,psi);
3703 
3704  //Loop over the dimensions
3705  for(unsigned i=0;i<nodal_dim;i++)
3706  {
3707  //Initilialise value of x[i] to zero
3708  x[i] = 0.0;
3709  //Loop over the local nodes
3710  for(unsigned l=0;l<n_node;l++)
3711  {
3712  for(unsigned k=0;k<n_position_type;k++)
3713  {
3714  x[i] += nodal_position_gen(l,k,i)*psi[l];
3715  }
3716  }
3717  }
3718  }
3719 };
3720 
3721 /////////////////////////////////////////////////////////////////////////////
3722 /// General BellElement class ///
3723 /// Empty, just establishes the template parameters
3724 /////////////////////////////////////////////////////////////////////
3725 template<unsigned DIM, unsigned NNODE_1D>
3726  class BellElement : public virtual BellElementBase<NNODE_1D>, public virtual TElement<DIM,NNODE_1D>, public virtual BellElementShape<DIM>, public virtual LinearTElement<DIM>
3727 {
3728  public :
3729 
3730  ///\short Constructor: Call constructors for BellElement
3731  BellElement() : BellElementBase<NNODE_1D>(), TElement<DIM,NNODE_1D>(), BellElementShape<DIM>(), LinearTElement<DIM>()
3732  {
3733  //Set the number of types required to interpolate the coordinate
3734  this->set_nnodal_position_type(6);
3735  TGauss<2,4>* new_integral_pt = new TGauss<2,4>;
3736  this->set_integration_scheme(new_integral_pt);
3737  }
3738 
3739  /// Broken copy constructor
3741  {
3742  BrokenCopy::broken_copy("BellElement");
3743  }
3744 
3745  /// Broken assignment operator
3746  void operator=(const BellElement&)
3747  {
3748  BrokenCopy::broken_assign("BellElement");
3749  }
3750 
3751  /// Calculate the geometric shape functions at local coordinate s
3752  inline void shape(const Vector<double> &s, Shape &psi) const
3753  {
3755  }
3756 
3757  /// \short Compute the geometric shape functions and
3758  /// derivatives w.r.t. local coordinates at local coordinate s
3759  inline void dshape_local(const Vector<double> &s, Shape &psi,
3760  DShape &dpsids) const
3761  {
3762  LinearTElement<2>::dLshape_local(s,psi,dpsids);
3763  }
3764 
3765  /// \short Computer the geometric shape functions, derivatives and
3766  /// second derivatives w.r.t local coordinates at local coordinate s \n
3767  /// d2psids(i,0) = \f$ \partial^2 \psi_j / \partial s_0^2 \f$ \n
3768  /// d2psids(i,1) = \f$ \partial^2 \psi_j / \partial s_1^2 \f$ \n
3769  /// d2psids(i,2) = \f$ \partial^2 \psi_j / \partial s_0 \partial s_1 \f$ \n
3770  inline void d2shape_local(const Vector<double> &s, Shape &psi,
3771  DShape &dpsids, DShape &d2psids) const
3772  {
3773  LinearTElement<2>::d2Lshape_local(s,psi,dpsids,d2psids);
3774  }
3775 
3776  /// Calculate the c1-basis functions at local coordinate s
3777  inline void basis(const Vector<double> &s, Shape &psi) const
3778  {
3779  /// Number of nodes along each element edge
3780  unsigned n_node = 3;
3781 
3782  DenseMatrix<double> node_position(n_node,DIM);
3783  for(unsigned l=0;l<n_node;l++)
3784  {
3785  for(unsigned k=0;k<1;k++)
3786  {
3787  for(unsigned j=0;j<DIM;j++)
3788  {
3789  node_position(l,j) = this->raw_nodal_position_gen(l,k,j);
3790  }
3791  }
3792  }
3793  BellElementShape<2>::Bshape(s,psi,node_position);
3794  }
3795 
3796  /// \short Compute the c1-basis functions and
3797  /// derivatives w.r.t. global coordinates at local coordinate s
3798  inline void dbasis_local(const Vector<double> &s, Shape &psi,
3799  DShape &dpsids) const
3800  {
3801  /// Number of nodes along each element edge
3802  unsigned n_node = 3;
3803 
3804  DenseMatrix<double> node_position(3,DIM);
3805 
3806  for(unsigned l=0;l<n_node;l++)
3807  {
3808  for(unsigned k=0;k<1;k++)
3809  {
3810  for(unsigned j=0;j<DIM;j++)
3811  {
3812  node_position(l,j) = this->raw_nodal_position_gen(l,k,j);
3813  }
3814  }
3815  }
3816  BellElementShape<2>::dBshape_local(s,psi,dpsids,node_position);
3817  }
3818 
3819  /// \short Compute the c1-basis functions and
3820  /// derivatives w.r.t. global coordinates at local coordinate s
3821  inline void d2basis_local(const Vector<double> &s, Shape &psi,
3822  DShape &dpsids, DShape &d2psids) const
3823  {
3824  /// Number of nodes along each element edge
3825  unsigned n_node = 3;
3826  DenseMatrix<double> node_position(3,DIM);
3827 
3828  for(unsigned l=0;l<n_node;l++)
3829  {
3830  for(unsigned k=0;k<1;k++)
3831  {
3832  for(unsigned j=0;j<DIM;j++)
3833  {
3834  node_position(l,j) = this->raw_nodal_position_gen(l,k,j);
3835  }
3836  }
3837  }
3838  BellElementShape<2>::d2Bshape_local(s,psi,dpsids,d2psids,node_position);
3839  }
3840 
3841  /// Calculate the c0-basis functions at local coordinate s
3842  inline void basis_c0(const Vector<double> &s, Shape &psi) const
3843  {
3845  }
3846 
3847  /// \short Compute the c0-basis functions and
3848  /// derivatives w.r.t. local coordinates at local coordinate s
3849  inline void dbasis_c0_local(const Vector<double> &s, Shape &psi,
3850  DShape &dpsids) const
3851  {
3853  }
3854 
3855  /// \short Computer the c0-basis functions, derivatives and
3856  /// second derivatives w.r.t local coordinates at local coordinate s \n
3857  /// d2psids(i,0) = \f$ \partial^2 \psi_j / \partial s_0^2 \f$ \n
3858  /// d2psids(i,1) = \f$ \partial^2 \psi_j / \partial s_1^2 \f$ \n
3859  /// d2psids(i,2) = \f$ \partial^2 \psi_j / \partial s_0 \partial s_1 \f$ \n
3860  inline void d2basis_c0_local(const Vector<double> &s, Shape &psi,
3861  DShape &dpsids, DShape &d2psids) const
3862  {
3863  TElementShape<2,NNODE_1D>::d2shape_local(s,psi,dpsids,d2psids);
3864  }
3865 
3866  /// Calculate the test functions at local coordinate s
3867  inline void test(const Vector<double> &s, Shape &psi) const
3868  {
3870  }
3871 
3872  /// \short Compute the test functions and
3873  /// derivatives w.r.t. local coordinates at local coordinate s
3874  inline void dtest_local(const Vector<double> &s, Shape &psi,
3875  DShape &dpsids) const
3876  {
3878  }
3879 
3880  /// \short Computer the test functions, derivatives and
3881  /// second derivatives w.r.t local coordinates at local coordinate s \n
3882  /// d2psids(i,0) = \f$ \partial^2 \psi_j / \partial s_0^2 \f$ \n
3883  /// d2psids(i,1) = \f$ \partial^2 \psi_j / \partial s_1^2 \f$ \n
3884  /// d2psids(i,2) = \f$ \partial^2 \psi_j / \partial s_0 \partial s_1 \f$ \n
3885  inline void d2test_local(const Vector<double> &s, Shape &psi,
3886  DShape &dpsids, DShape &d2psids) const
3887  {
3888  TElementShape<2,NNODE_1D>::d2shape_local(s,psi,dpsids,d2psids);
3889  }
3890 
3891 };
3892 
3893 
3894 //========================================================================
3895 /// Empty base class for C1Curvedelements (created so that
3896 /// we can use dynamic_cast<>() to figure out if a an element
3897 /// is a C1Curvedelement). This element is sup-parametric
3898 /// Note that this type of element carries three kinds of shape functions
3899 /// shape_straight : denotes C1-shape functions for straight-edged triangle
3900 /// shape_curve : denotes C1-shape functions for curve-edged triangle
3901 /// shape_geom : denotes C0-shape functions for geometry
3902 //========================================================================
3903 template<unsigned NNODE_1D>
3904 class C1CurvedElementBase: public virtual FiniteElement
3905 {
3906 public:
3907  ///\short Constructor: Call constructors for FiniteElement
3910  unsigned &bd_element, DenseMatrix<double> &bd_node_position, Vector<double> &x) const
3911  {}
3912 
3913  virtual void classify_boundary_node(DenseMatrix<double> &node_position,unsigned &bd_element,
3914  DenseMatrix<double> &bd_node_position, Vector<double> &x) const
3915  {}
3916 
3917  virtual void basis_straight(const Vector<double> &s, Shape &psi) const
3918  {}
3919 
3920 
3921  virtual void dbasis_local_straight(const Vector<double> &s, Shape &psi,
3922  DShape &dpsids) const
3923  {}
3924 
3926  Shape &psi,
3927  DShape &dpsids,
3928  DShape &d2psids) const
3929  {}
3930 
3931  virtual void shape_geom(const Vector<double> &s, Shape &psi, Shape &phi) const
3932  {}
3933 
3934 
3935  virtual void dshape_local_geom(const Vector<double> &s, Shape &psi,
3936  DShape &dpsids, Shape &phi,
3937  DShape &dphids) const
3938  {}
3939 
3940  virtual void d2shape_local_geom(const Vector<double> &s,
3941  Shape &psi,
3942  DShape &dpsids,
3943  DShape &d2psids,
3944  Shape &phi,
3945  DShape &dphids,
3946  DShape &d2phids) const
3947  {}
3948 
3949  virtual void basis_curve(const Vector<double> &s, Shape &psi) const
3950  {}
3951 
3952 
3953  virtual void dbasis_local_curve(const Vector<double> &s, Shape &psi,
3954  DShape &dpsids) const
3955  {}
3956 
3957  virtual void d2basis_local_curve(const Vector<double> &s,
3958  Shape &psi,
3959  DShape &dpsids,
3960  DShape &d2psids) const
3961  {}
3962 
3963  virtual void basis_c0(const Vector<double> &s, Shape &psi) const
3964  {}
3965 
3966 
3967  virtual void dbasis_c0_local(const Vector<double> &s, Shape &psi,
3968  DShape &dpsids) const
3969  {}
3970 
3971  virtual void d2basis_c0_local(const Vector<double> &s,
3972  Shape &psi,
3973  DShape &dpsids,
3974  DShape &d2psids) const
3975  {}
3976 
3977 
3978  virtual void test(const Vector<double> &s, Shape &phi) const
3979  {}
3980 
3981 
3982  virtual void dtest_local(const Vector<double> &s, Shape &phi,
3983  DShape &dphids) const
3984  {}
3985 
3986  virtual void d2test_local(const Vector<double> &s,
3987  Shape &phi,
3988  DShape &dphids,
3989  DShape &d2phids) const
3990  {}
3991 
3992 
3993  //=========================================================================
3994  /// \short Return the c1-shape function associated with a straight-sided
3995  /// boundary stored at the ipt-th integration point.
3996  //=========================================================================
3997  void basis_at_knot_straight(const unsigned &ipt, Shape &psi) const
3998  {
3999  //Find the dimension of the element
4000  const unsigned el_dim = dim();
4001  //Storage for the local coordinates of the integration point
4002  Vector<double> s(el_dim);
4003  //Set the local coordinate
4004  for(unsigned i=0;i<el_dim;i++) {s[i] = integral_pt()->knot(ipt,i);}
4005  //Get the shape function
4006  basis_straight(s,psi);
4007  }
4008 
4009  //=========================================================================
4010  /// \short Return the c1-shape function associated with a straight-sided
4011  /// boundary and its derivatives w.r.t. the global
4012  /// coordinates at the ipt-th integration point.
4013  //=========================================================================
4014  void dbasis_local_at_knot_straight(const unsigned &ipt, Shape &psi,
4015  DShape &dpsids) const
4016  {
4017  //Find the dimension of the element
4018  const unsigned el_dim = dim();
4019  //Storage for the local coordinates of the integration point
4020  Vector<double> s(el_dim);
4021  //Set the local coordinate
4022  for(unsigned i=0;i<el_dim;i++) {s[i] = integral_pt()->knot(ipt,i);}
4023  //Get the shape function and derivatives
4024  dbasis_local_straight(s,psi,dpsids);
4025 
4026  }
4027 
4028  //=========================================================================
4029  /// Calculate the c1-shape function associated with a straight-sided
4030  /// boundary and its first and second derivatives
4031  /// w.r.t. global coordinates at the ipt-th integration point.
4032  /// \n\n Numbering:
4033  //=========================================================================
4034  void d2basis_local_at_knot_straight(const unsigned &ipt, Shape &psi,
4035  DShape &dpsids, DShape &d2psids)
4036  const
4037  {
4038  //Find the dimension of the element
4039  const unsigned el_dim = dim();
4040  //Storage for the local coordinates of the integration point
4041  Vector<double> s(el_dim);
4042  //Set the local coordinate
4043  for(unsigned i=0;i<el_dim;i++) {s[i] = integral_pt()->knot(ipt,i);}
4044  //Get the shape function and first and second derivatives
4045  d2basis_local_straight(s,psi,dpsids,d2psids);
4046 
4047  }
4048 
4049  //=========================================================================
4050  /// \short Return the c1-shape function associated with a curvilinear
4051  /// boundary stored at the ipt-th integration point.
4052  //=========================================================================
4053  void basis_at_knot_curve(const unsigned &ipt, Shape &psi) const
4054  {
4055  //Find the dimension of the element
4056  const unsigned el_dim = dim();
4057  //Storage for the local coordinates of the integration point
4058  Vector<double> s(el_dim);
4059  //Set the local coordinate
4060  for(unsigned i=0;i<el_dim;i++) {s[i] = integral_pt()->knot(ipt,i);}
4061  //Get the shape function
4062  basis_curve(s,psi);
4063  }
4064 
4065  //=========================================================================
4066  /// Return the c1-shape function associated with a curvilinear boundary
4067  /// and its derivatives w.r.t. the local coordinates at the ipt-th
4068  /// integration point.
4069  //=========================================================================
4070  void dbasis_local_at_knot_curve(const unsigned &ipt, Shape &psi,
4071  DShape &dpsids) const
4072  {
4073  //Find the dimension of the element
4074  const unsigned el_dim = dim();
4075  //Storage for the local coordinates of the integration point
4076  Vector<double> s(el_dim);
4077  //Set the local coordinate
4078  for(unsigned i=0;i<el_dim;i++) {s[i] = integral_pt()->knot(ipt,i);}
4079  //Get the shape function and derivatives
4080  dbasis_local_curve(s,psi,dpsids);
4081  }
4082 
4083  //=========================================================================
4084  /// Calculate the c1-shape function associated with a curvilinear boundary
4085  /// and its first and second derivatives w.r.t. local coordinates at the
4086  /// ipt-th integration point.
4087  /// \n\n Numbering:
4088  //=========================================================================
4089  void d2basis_local_at_knot_curve(const unsigned &ipt, Shape &psi,
4090  DShape &dpsids, DShape &d2psids)
4091  const
4092  {
4093  //Find the dimension of the element
4094  const unsigned el_dim = dim();
4095  //Storage for the local coordinates of the integration point
4096  Vector<double> s(el_dim);
4097  //Set the local coordinate
4098  for(unsigned i=0;i<el_dim;i++) {s[i] = integral_pt()->knot(ipt,i);}
4099  //Get the shape function and first and second derivatives
4100  d2basis_local_curve(s,psi,dpsids,d2psids);
4101  }
4102 
4103  //=========================================================================
4104  /// \short Return the c0-shape function stored at the ipt-th integration
4105  /// point.
4106  //=========================================================================
4107  void basis_c0_at_knot(const unsigned &ipt, Shape &psi) const
4108  {
4109  //Find the dimension of the element
4110  const unsigned el_dim = dim();
4111  //Storage for the local coordinates of the integration point
4112  Vector<double> s(el_dim);
4113  //Set the local coordinate
4114  for(unsigned i=0;i<el_dim;i++) {s[i] = integral_pt()->knot(ipt,i);}
4115  //Get the shape function
4116  basis_c0(s,psi);
4117  }
4118 
4119  //=========================================================================
4120  /// \short Return the c0-shape function and its derivatives w.r.t. the local
4121  /// coordinates at the ipt-th integration point.
4122  //=========================================================================
4123  void dbasis_c0_local_at_knot(const unsigned &ipt, Shape &psi,
4124  DShape &dpsids) const
4125  {
4126  //Find the dimension of the element
4127  const unsigned el_dim = dim();
4128  //Storage for the local coordinates of the integration point
4129  Vector<double> s(el_dim);
4130  //Set the local coordinate
4131  for(unsigned i=0;i<el_dim;i++) {s[i] = integral_pt()->knot(ipt,i);}
4132  //Get the shape function and derivatives
4133  dbasis_c0_local(s,psi,dpsids);
4134  }
4135 
4136  //=========================================================================
4137  /// Calculate the c0-shape function and its first and second derivatives
4138  /// w.r.t. local coordinates at the ipt-th integration point.
4139  /// \n\n Numbering:
4140  //=========================================================================
4141  void d2basis_c0_local_at_knot(const unsigned &ipt, Shape &psi,
4142  DShape &dpsids, DShape &d2psids)
4143  const
4144  {
4145  //Find the dimension of the element
4146  const unsigned el_dim = dim();
4147  //Storage for the local coordinates of the integration point
4148  Vector<double> s(el_dim);
4149  //Set the local coordinate
4150  for(unsigned i=0;i<el_dim;i++) {s[i] = integral_pt()->knot(ipt,i);}
4151  //Get the shape function and first and second derivatives
4152  d2basis_c0_local(s,psi,dpsids,d2psids);
4153  }
4154 
4155  //=========================================================================
4156  /// \short Return the geometric shape function stored at the ipt-th integration
4157  /// point.
4158  //=========================================================================
4159  void shape_at_knot_geom(const unsigned &ipt, Shape &psi, Shape &phi) const
4160  {
4161  //Find the dimension of the element
4162  const unsigned el_dim = dim();
4163  //Storage for the local coordinates of the integration point
4164  Vector<double> s(el_dim);
4165  //Set the local coordinate
4166  for(unsigned i=0;i<el_dim;i++) {s[i] = integral_pt()->knot(ipt,i);}
4167  //Get the shape function
4168  shape_geom(s,psi,phi);
4169  }
4170 
4171  //=========================================================================
4172  /// \short Return the geometric shape function and its derivatives w.r.t. the local
4173  /// coordinates at the ipt-th integration point.
4174  //=========================================================================
4175  void dshape_local_at_knot_geom(const unsigned &ipt, Shape &psi,
4176  DShape &dpsids, Shape &phi,
4177  DShape &dphids) const
4178  {
4179  //Find the dimension of the element
4180  const unsigned el_dim = dim();
4181  //Storage for the local coordinates of the integration point
4182  Vector<double> s(el_dim);
4183  //Set the local coordinate
4184  for(unsigned i=0;i<el_dim;i++) {s[i] = integral_pt()->knot(ipt,i);}
4185  //Get the shape function and derivatives
4186 
4187  dshape_local_geom(s,psi,dpsids,phi,dphids);
4188  }
4189 
4190  //=========================================================================
4191  /// Calculate the geometric shape function and its first and second derivatives
4192  /// w.r.t. local coordinates at the ipt-th integration point.
4193  /// \n\n Numbering:
4194  //=========================================================================
4195  void d2shape_local_at_knot_geom(const unsigned &ipt, Shape &psi,
4196  DShape &dpsids, DShape &d2psids, Shape &phi,
4197  DShape &dphids, DShape &d2phids)
4198  const
4199  {
4200  //Find the dimension of the element
4201  const unsigned el_dim = dim();
4202  //Storage for the local coordinates of the integration point
4203  Vector<double> s(el_dim);
4204  //Set the local coordinate
4205  for(unsigned i=0;i<el_dim;i++) {s[i] = integral_pt()->knot(ipt,i);}
4206  //Get the shape function and first and second derivatives
4207  d2shape_local_geom(s,psi,dpsids,d2psids,phi,dphids,d2phids);
4208  }
4209 
4210  //=========================================================================
4211  /// \short Return the test function stored at the ipt-th integration
4212  /// point.
4213  //=========================================================================
4214  void test_at_knot(const unsigned &ipt, Shape &phi) const
4215  {
4216  //Find the dimension of the element
4217  const unsigned el_dim = dim();
4218  //Storage for the local coordinates of the integration point
4219  Vector<double> s(el_dim);
4220  //Set the local coordinate
4221  for(unsigned i=0;i<el_dim;i++) {s[i] = integral_pt()->knot(ipt,i);}
4222  //Get the shape function
4223  test(s,phi);
4224  }
4225 
4226  //=========================================================================
4227  /// \short Return the test function and its derivatives w.r.t. the local
4228  /// coordinates at the ipt-th integration point.
4229  //=========================================================================
4230  void dtest_local_at_knot(const unsigned &ipt, Shape &phi,
4231  DShape &dphids) const
4232  {
4233  //Find the dimension of the element
4234  const unsigned el_dim = dim();
4235  //Storage for the local coordinates of the integration point
4236  Vector<double> s(el_dim);
4237  //Set the local coordinate
4238  for(unsigned i=0;i<el_dim;i++) {s[i] = integral_pt()->knot(ipt,i);}
4239  //Get the shape function and derivatives
4240  dtest_local(s,phi,dphids);
4241  }
4242 
4243  //=========================================================================
4244  /// Calculate the test function and its first and second derivatives
4245  /// w.r.t. local coordinates at the ipt-th integration point.
4246  /// \n\n Numbering:
4247  //=========================================================================
4248  void d2test_local_at_knot(const unsigned &ipt, Shape &phi,
4249  DShape &dphids, DShape &d2phids)
4250  const
4251  {
4252  //Find the dimension of the element
4253  const unsigned el_dim = dim();
4254  //Storage for the local coordinates of the integration point
4255  Vector<double> s(el_dim);
4256  //Set the local coordinate
4257  for(unsigned i=0;i<el_dim;i++) {s[i] = integral_pt()->knot(ipt,i);}
4258  //Get the shape function and first and second derivatives
4259  d2test_local(s,phi,dphids,d2phids);
4260  }
4261 
4262  //=========================================================================
4263  /// Calculate the shape function and its first and second derivatives
4264  /// w.r.t. local coordinates at the ipt-th integration point.
4265  /// \n\n Numbering:
4266  //=========================================================================
4267  double dshape_and_dtest_eulerian_at_knot(const unsigned &ipt, Shape &psi, DShape &dpsi, Shape &test, DShape &dtest)
4268  const
4269  {
4270 
4271  //Find the element dimension
4272  const unsigned el_dim = dim();
4273  //Get the values of the shape function and local derivatives
4274  //Temporarily store it in dpsi
4275  // assign shape functions for unknowns
4276  dshape_local_at_knot(ipt,psi,dpsi);
4277 
4278  // assign shape functions for geometry -> Lagrange family
4279  unsigned n_node = 3;
4280  Shape psi_x(n_node);
4281  DShape dpsi_x(n_node,2);
4282  Shape phi(2);
4283  DShape dphi(2,2);
4284 
4285  // assign 'linear' shape function to geometry
4286  dshape_local_at_knot_geom(ipt,psi_x,dpsi_x,phi,dphi);
4287 
4288  // assign test function
4289  dtest_local_at_knot(ipt,test,dtest);
4290 
4291  //Allocate memory for the inverse jacobian
4292  DenseMatrix<double> jacobian(el_dim), inverse_jacobian(el_dim);
4293 
4294  //Now calculate the inverse jacobian
4295  const double det = local_to_eulerian_mapping2(dpsi_x,dphi,jacobian,inverse_jacobian);
4296 
4297  //Now set the values of the derivatives to dpsidx
4298  transform_derivatives(inverse_jacobian,dpsi);
4299 
4300  //Return the determinant of the jacobian
4301  return det;
4302  }
4303 
4304  //===========================================================================
4305  /// \short Compute the c1-shape functions that associated with the straight-
4306  /// boundary element and also first and second derivatives w.r.t. global
4307  /// coordinates at ipt-th integration point
4308  /// Returns Jacobian of mapping from global to local coordinates.
4309  //===========================================================================
4310  double d2shape_and_d2test_eulerian_at_knot(const unsigned &ipt,
4311  Shape &psi,
4312  DShape &dpsi,
4313  DShape &d2psi,
4314  Shape &test,
4315  DShape &dtest,
4316  DShape &d2test) const
4317  {
4318  //Find the values of the indices of the shape functions
4319  //Locally cached
4320  //Find the element dimension
4321  const unsigned el_dim = dim();
4322  //Get the values of the shape function and local derivatives for unknowns
4323  d2basis_local_at_knot_straight(ipt,psi,dpsi,d2psi);
4324 
4325  // assign shape functions for geometry
4326  unsigned n_node = 3;
4327  Shape psi_x(n_node);
4328  DShape dpsi_x(n_node,2);
4329  DShape d2psi_x(n_node,3);
4330  Shape phi(2);
4331  DShape dphi(2,2);
4332  DShape d2phi(2,3);
4333  d2shape_local_at_knot_geom(ipt,psi_x,dpsi_x,d2psi_x,phi,dphi,d2phi);
4334 
4335  // assign for test function
4336  d2test_local_at_knot(ipt,test,dtest,d2test);
4337 
4338  //Allocate memory for the jacobian and inverse jacobian
4339  DenseMatrix<double> jacobian(el_dim), inverse_jacobian(el_dim);
4340 
4341  //Calculate the jacobian and inverse jacobian
4342  const double det = local_to_eulerian_mapping2(dpsi_x,dphi,jacobian,inverse_jacobian);
4343 
4344  //Return the determinant of the mapping
4345  return det;
4346  }
4347 
4348  //===========================================================================
4349  /// \short Calculate the mapping from local to Eulerian coordinates,
4350  /// given the derivatives of the shape functions w.r.t. local coordinates,
4351  /// Return only the determinant of the jacobian and the inverse of the
4352  /// mapping (ds/dx).
4353  //===========================================================================
4354  double local_to_eulerian_mapping2(const DShape &dpsids, DShape &dphids,
4355  DenseMatrix<double> &inverse_jacobian) const
4356  {
4357  //Find the dimension of the element
4358  const unsigned el_dim = dim();
4359  //Assign memory for the jacobian
4360  DenseMatrix<double> jacobian(el_dim);
4361  //Calculate the jacobian and inverse
4362  return local_to_eulerian_mapping2(dpsids,dphids,jacobian,inverse_jacobian);
4363  }
4364 
4365  ///////////////////////////////////////////////////////////////
4366  virtual double local_to_eulerian_mapping2(const DShape &dpsids,
4367  DShape &dphids,
4368  DenseMatrix<double> &jacobian,
4369  DenseMatrix<double> &inverse_jacobian) const
4370  {
4371  //Assemble the jacobian
4372  //Locally cache the elemental dimension
4373  const unsigned el_dim = dim();
4374 
4375  //Loop over the rows of the jacobian
4376  for(unsigned i=0;i<el_dim;i++)
4377  {
4378  //Loop over the columns of the jacobian
4379  for(unsigned j=0;j<el_dim;j++)
4380  {
4381  //Zero the entry
4382  jacobian(i,j) = 0.0;
4383  jacobian(i,j) = dphids(j,i);
4384  }
4385  }
4386  //Invert the jacobian (use the template-free interface)
4387  return invert_jacobian_mapping(jacobian,inverse_jacobian);
4388  }
4389 
4390  //=========================================================================
4391  /// Internal function that is used to assemble the jacobian of second
4392  /// derivatives of the the mapping from local coordinates (s) to the
4393  /// eulerian coordinates (x), given the second derivatives of the
4394  /// shape functions.
4395  //=========================================================================
4397  DenseMatrix<double> &jacobian2) const
4398  {
4399  //Find the the dimension of the element
4400  const unsigned el_dim = dim();
4401  //Find the number of second derivatives
4402  const unsigned n_row = N2deriv[el_dim];
4403  //Assemble the "jacobian" (d^2 x_j/ds_i^2) for second derivatives of
4404  //shape functions
4405  //Loop over the rows (number of second derivatives)
4406  for(unsigned i=0;i<n_row;i++)
4407  {
4408  //Loop over the columns (element dimension
4409  for(unsigned j=0;j<el_dim;j++)
4410  {
4411  //Zero the entry
4412  jacobian2(i,j) = 0.0;
4413  jacobian2(i,j) = d2psids(j,i);
4414  }
4415  }
4416  }
4417 
4418  //=======================================================================
4419  /// Return FE interpolated position x[] at local coordinate s as Vector
4420  // (using Hermite interpolation)
4421  //=======================================================================
4423  const
4424  {
4425  //Find the number of nodes
4426  const unsigned n_node = 3;
4427  //Assign storage for the local shape function
4428  Shape psi(n_node);
4429  Shape phi(2);
4430  //Find the values of shape function
4431  shape_geom(s,psi,phi);
4432 
4433  x[0] = phi[0];
4434  x[1] = phi[1];
4435  }
4436 
4437  //========================================================================
4438  /// \short Calculate the Jacobian of the mapping between local and global
4439  /// coordinates at the position s
4440  //========================================================================
4441  double J_eulerian1(const Vector<double> &s) const
4442  {
4443  //Find the number of nodes and position types
4444  const unsigned n_node = 3;
4445  //Find the dimension of the node and element
4446  const unsigned n_dim_node = this->nodal_dimension();
4447  const unsigned n_dim_element = this->dim();
4448 
4449  //Set up dummy memory for the shape functions
4450  // compute the jacobian of mapping matrix
4451  Shape psi(n_node), phi(2);
4452  DShape dpsids(n_node,n_dim_element), dphi(2,2);
4453  //Get the shape functions and local derivatives for geometry
4454  this->dshape_local_geom(s,psi,dpsids,phi,dphi);
4455 
4456  //Right calculate the base vectors
4457  DenseMatrix<double> interpolated_G(n_dim_element,n_dim_node);
4458 
4459  //Loop over the dimensions and compute the entries of the
4460  //base vector matrix
4461  for(unsigned i=0;i<n_dim_element;i++)
4462  {
4463  for(unsigned j=0;j<n_dim_node;j++)
4464  {
4465  interpolated_G(i,j) = dphi(j,i);
4466  }
4467  }
4468 
4469  //Calculate the metric tensor of the element
4470  DenseMatrix<double> G(n_dim_element);
4471  for(unsigned i=0;i<n_dim_element;i++)
4472  {
4473  for(unsigned j=0;j<n_dim_element;j++)
4474  {
4475  //Initialise to zero
4476  G(i,j) = 0.0;
4477  for(unsigned k=0;k<n_dim_node;k++)
4478  {
4479  G(i,j) += interpolated_G(i,k)*interpolated_G(j,k);
4480  }
4481  }
4482  }
4483 
4484  //Calculate the determinant of the metric tensor
4485  double det = 0.0;
4486  switch(n_dim_element)
4487  {
4488  case 0:
4489  throw OomphLibError("Cannot calculate J_eulerian() for point element\n",
4490  "FiniteElement::J_eulerian()",
4491  OOMPH_EXCEPTION_LOCATION);
4492  break;
4493  case 1:
4494  det = G(0,0);
4495  break;
4496  case 2:
4497  det = G(0,0)*G(1,1) - G(0,1)*G(1,0);
4498  break;
4499  case 3:
4500  det = G(0,0)*G(1,1)*G(2,2) + G(0,1)*G(1,2)*G(2,0) + G(0,2)*G(1,0)*G(2,1)
4501  - G(0,0)*G(1,2)*G(2,1) - G(0,1)*G(1,0)*G(2,2) - G(0,2)*G(1,1)*G(2,0);
4502  break;
4503  default:
4504  oomph_info << "More than 3 dimensions in J_eulerian()" << std::endl;
4505  break;
4506  }
4507 
4508 #ifdef PARANOID
4509  this->check_jacobian(det);
4510 #endif
4511 
4512  //Return the Jacobian (square-root of the determinant of the metric tensor)
4513  return det;
4514  }
4515 
4516  // =======================================================================
4517  // Check whether this element is a boundary element or not
4518  //========================================================================
4519  unsigned is_boundary_element()const
4520  {
4521  unsigned n_node = 3;
4522  int count=0;
4523  // check whether this element is on boundary or not
4524  for(unsigned i=0;i<n_node;i++)
4525  {
4526  // check whether this node is on 1st boundary (curve boundary)
4527  bool bd_node1 = node_pt(i)->is_on_boundary(1);
4528  if(bd_node1==1)
4529  {
4530  count += 1;
4531  }
4532  }
4533  unsigned bd_element;
4534  if(count == 2)
4535  {
4536  bd_element = 1;
4537  }
4538  else
4539  {
4540  bd_element = 0;
4541  }
4542  return bd_element;
4543  }
4544 
4545  //=========================================================================
4546  /// \short Compute the c0-shape functions and also
4547  /// first derivatives w.r.t. global coordinates at local coordinate s;
4548  /// Returns Jacobian of mapping from global to local coordinates.
4549  /// Most general form of the function, but may be over-loaded, if desired
4550  //=========================================================================
4552  Shape &psi,
4553  DShape &dpsi) const
4554  {
4555  //Find the element dimension
4556  const unsigned el_dim = dim();
4557  //Get the values of the shape functions and their local derivatives
4558  //Temporarily stored in dpsi
4559  dbasis_c0_local(s,psi,dpsi);
4560 
4561  // assign shape functions for geometry
4562  unsigned n_node = 3;
4563  Shape psi_x(n_node);
4564  DShape dpsi_x(n_node,2);
4565  DShape d2psi_x(n_node,3);
4566  Shape phi(2);
4567  DShape dphi(2,2);
4568  DShape d2phi(2,3);
4569  d2shape_local_geom(s,psi_x,dpsi_x,d2psi_x,phi,dphi,d2phi);
4570 
4571  //Allocate memory for the jacobian and inverse jacobian
4572  DenseMatrix<double> jacobian(el_dim), inverse_jacobian(el_dim);
4573  //Calculate the jacobian and inverse jacobian
4574  const double det = this->local_to_eulerian_mapping2(dpsi_x,dphi,jacobian,inverse_jacobian);
4575  //Now set the values of the derivatives to be dpsidx
4576  transform_derivatives(inverse_jacobian,dpsi);
4577  //Return the determinant of the jacobian
4578  return det;
4579  }
4580 
4581  //=========================================================================
4582  /// \short Compute the c0-shape functions and also the first and the
4583  /// second derivatives w.r.t.global coordinates at local coordinate s;
4584  /// Returns Jacobian of mapping from global to local coordinates.
4585  /// Most general form of the function, but may be over-loaded, if desired
4586  //=========================================================================
4588  Shape &psi,
4589  DShape &dpsi,
4590  DShape &d2psi) const
4591  {
4592  //Find the element dimension
4593  const unsigned el_dim = dim();
4594  //Find the number of second derivatives required
4595  const unsigned n_deriv = N2deriv[el_dim];
4596  //Get the values of the shape function and local derivatives for unknowns
4597  d2basis_c0_local(s,psi,dpsi,d2psi);
4598 
4599  // assign shape functions for geometry
4600  unsigned n_node = 3;
4601  Shape psi_x(n_node);
4602  DShape dpsi_x(n_node,2);
4603  DShape d2psi_x(n_node,3);
4604  Shape phi(2);
4605  DShape dphi(2,2);
4606  DShape d2phi(2,3);
4607  d2shape_local_geom(s,psi_x,dpsi_x,d2psi_x,phi,dphi,d2phi);
4608 
4609  //Allocate memory for the jacobian and inverse jacobian
4610  DenseMatrix<double> jacobian(el_dim), inverse_jacobian(el_dim);
4611  //Calculate the jacobian and inverse jacobian
4612  const double det = local_to_eulerian_mapping2(dpsi_x,dphi,jacobian,inverse_jacobian);
4613  //Allocate memory for the jacobian of second derivatives
4614  DenseMatrix<double> jacobian2(n_deriv,el_dim,0.0);
4615  //Assemble the jacobian of second derivatives
4616  myassemble_local_to_eulerian_jacobian2(d2phi,jacobian2);
4617  //Now set the value of the derivatives
4618  transform_second_derivatives(jacobian,inverse_jacobian,jacobian2,dpsi,d2psi);
4619  //Return the determinant of the jacobian
4620  return det;
4621  }
4622 
4623  //=========================================================================
4624  /// \short Compute the curved-element shape functions and also
4625  /// first derivatives w.r.t. global coordinates at local coordinate s;
4626  /// Returns Jacobian of mapping from global to local coordinates.
4627  /// Most general form of the function, but may be over-loaded, if desired
4628  //=========================================================================
4630  Shape &psi,
4631  DShape &dpsi) const
4632  {
4633  //Find the element dimension
4634  const unsigned el_dim = dim();
4635  //Get the values of the shape functions and their local derivatives
4636  //Temporarily stored in dpsi
4637  dbasis_local_curve(s,psi,dpsi);
4638 
4639  // assign shape functions for geometry
4640  unsigned n_node = 3;
4641  Shape psi_x(n_node);
4642  DShape dpsi_x(n_node,2);
4643  DShape d2psi_x(n_node,3);
4644  Shape phi(2);
4645  DShape dphi(2,2);
4646  DShape d2phi(2,3);
4647  d2shape_local_geom(s,psi_x,dpsi_x,d2psi_x,phi,dphi,d2phi);
4648 
4649  //Allocate memory for the jacobian and inverse jacobian
4650  DenseMatrix<double> jacobian(el_dim), inverse_jacobian(el_dim);
4651  //Calculate the jacobian and inverse jacobian
4652  const double det = this->local_to_eulerian_mapping2(dpsi_x,dphi,jacobian,inverse_jacobian);
4653  //Now set the values of the derivatives to be dpsidx
4654  transform_derivatives(inverse_jacobian,dpsi);
4655  //Return the determinant of the jacobian
4656  return det;
4657  }
4658 
4659  //===========================================================================
4660  /// \short Compute the cuved-element shape functions and also first
4661  /// and second derivatives w.r.t. global coordinates at ipt-th integration
4662  /// point
4663  //===========================================================================
4665  DShape &dpsi,
4666  DShape &d2psi) const
4667  {
4668  //Find the element dimension
4669  const unsigned el_dim = dim();
4670  //Find the number of second derivatives required
4671  const unsigned n_deriv = N2deriv[el_dim];
4672  //Get the values of the shape function and local derivatives for unknowns
4673  d2basis_local_curve(s,psi,dpsi,d2psi);
4674 
4675  // assign shape functions for geometry
4676  unsigned n_node = 3;
4677  Shape psi_x(n_node);
4678  DShape dpsi_x(n_node,2);
4679  DShape d2psi_x(n_node,3);
4680  Shape phi(2);
4681  DShape dphi(2,2);
4682  DShape d2phi(2,3);
4683  d2shape_local_geom(s,psi_x,dpsi_x,d2psi_x,phi,dphi,d2phi);
4684 
4685  //Allocate memory for the jacobian and inverse jacobian
4686  DenseMatrix<double> jacobian(el_dim), inverse_jacobian(el_dim);
4687  //Calculate the jacobian and inverse jacobian
4688  const double det = local_to_eulerian_mapping2(dpsi_x,dphi,jacobian,inverse_jacobian);
4689  //Allocate memory for the jacobian of second derivatives
4690  DenseMatrix<double> jacobian2(n_deriv,el_dim,0.0);
4691  //Assemble the jacobian of second derivatives
4692  myassemble_local_to_eulerian_jacobian2(d2phi,jacobian2);
4693  //Now set the value of the derivatives
4694  transform_second_derivatives(jacobian,inverse_jacobian,jacobian2,dpsi,d2psi);
4695  //Return the determinant of the jacobian
4696  return det;
4697  }
4698 
4699  //=======================================================================
4700  /// Return raw nodal value for nodes specified on the reference triangle
4701  //=======================================================================
4703  {
4704  // assign degrees of freedom to the reference element
4705  DenseMatrix<double> D(21,21), B(21,36);
4706  Vector<double> temp(21,0.0);
4707  DenseMatrix<double> position(3,2);
4708  unsigned bd_element;
4709  DenseMatrix<double> bd_position(20,2);
4710  Vector<double> x(2);
4711 
4712  // Get the nodal values of the unknown
4713  Vector<double> value(21);
4714 
4715  value[0] = raw_nodal_value(0,0);
4716  value[1] = raw_nodal_value(1,0);
4717  value[2] = raw_nodal_value(2,0);
4718  value[3] = raw_nodal_value(0,1);
4719  value[4] = raw_nodal_value(0,2);
4720  value[5] = raw_nodal_value(1,1);
4721  value[6] = raw_nodal_value(1,2);
4722  value[7] = raw_nodal_value(2,1);
4723  value[8] = raw_nodal_value(2,2);
4724  value[9] = raw_nodal_value(0,3);
4725  value[10] = raw_nodal_value(0,5);
4726  value[11] = raw_nodal_value(0,4);
4727  value[12] = raw_nodal_value(1,3);
4728  value[13] = raw_nodal_value(1,5);
4729  value[14] = raw_nodal_value(1,4);
4730  value[15] = raw_nodal_value(2,3);
4731  value[16] = raw_nodal_value(2,5);
4732  value[17] = raw_nodal_value(2,4);
4733  value[18] = raw_nodal_value(3,0);
4734  value[19] = raw_nodal_value(4,0);
4735  value[20] = raw_nodal_value(5,0);
4736 
4737  // Transformation metrix associating nodal values between the reference
4738  // and the physical curved triangle
4739  get_value_transform_matrix(D,B,position,bd_element,bd_position,x);
4740 
4741  for(unsigned i=0;i<21;i++)
4742  {
4743  for(unsigned j=0;j<36;j++)
4744  {
4745  for(unsigned k=0;k<21;k++)
4746  {
4747  M(i,j) += D(i,k)*B(k,j);
4748  }
4749  }
4750  }
4751 
4752  for(unsigned i=0;i<21;i++)
4753  {
4754  for(unsigned j=0;j<21;j++)
4755  {
4756  // get values wrt local coordinates
4757  temp[i] += value[j]*D(j,i);
4758  }
4759  }
4760 
4761  for(unsigned i=0;i<36;i++)
4762  {
4763  for(unsigned j=0;j<21;j++)
4764  {
4765  u_value[i] += temp[j]*B(j,i);
4766  }
4767  }
4768  }
4769 
4770  //=======================================================================
4771  /// Return raw nodal equations for nodes specified on the curved triangle
4772  /// This function will be employed for the post-permutation as
4773  /// the nodal values defined on the element doesn't match with the defined
4774  /// shape functions
4775  //=======================================================================
4777  {
4778  // assign degrees of freedom to the reference element
4779  DenseMatrix<double> D(21,21), B(21,36);
4780  DenseMatrix<double> position(3,2);
4781  unsigned bd_element;
4782  DenseMatrix<double> bd_position(20,2);
4783  Vector<double> x(2);
4784  unsigned n_position_type = 6;
4785 
4786  // Get nodal values at nodes on the reference element
4787  get_value_transform_matrix(D,B,position,bd_element,bd_position,x);
4788 
4789  double angle_1 = atan(bd_position(0,1)/bd_position(0,0));
4790  double angle_2 = atan(bd_position(1,1)/bd_position(1,0));
4791  if(angle_1 > angle_2)
4792  {
4793  for(unsigned k=0;k<n_position_type;k++)
4794  {
4795  unsigned i = 2+k;
4796  nodal_eqn(0,k) = nodal_local_eqn(2,i);
4797  nodal_eqn(1,k) = nodal_local_eqn(0,i);
4798  nodal_eqn(2,k) = nodal_local_eqn(1,i);
4799  nodal_eqn(3,k) = nodal_local_eqn(5,i);
4800  nodal_eqn(4,k) = nodal_local_eqn(3,i);
4801  nodal_eqn(5,k) = nodal_local_eqn(4,i);
4802  nodal_eqn(nnode()-3,k) = nodal_local_eqn(nnode()-3,i);
4803  nodal_eqn(nnode()-2,k) = nodal_local_eqn(nnode()-2,i);
4804  nodal_eqn(nnode()-1,k) = nodal_local_eqn(nnode()-1,i);
4805  }
4806  }
4807  else if(angle_1 < angle_2)
4808  {
4809  if(position(0,0)==bd_position(0,0) && position(0,1)==bd_position(0,1))
4810  {
4811  for(unsigned k=0;k<n_position_type;k++)
4812  {
4813  nodal_eqn(0,k) = nodal_local_eqn(0,2+k);
4814  nodal_eqn(1,k) = nodal_local_eqn(1,2+k);
4815  nodal_eqn(2,k) = nodal_local_eqn(2,2+k);
4816  nodal_eqn(3,k) = nodal_local_eqn(3,2+k);
4817  nodal_eqn(4,k) = nodal_local_eqn(4,2+k);
4818  nodal_eqn(5,k) = nodal_local_eqn(5,2+k);
4819  nodal_eqn(nnode()-3,k) = nodal_local_eqn(nnode()-2,2+k);
4820  nodal_eqn(nnode()-2,k) = nodal_local_eqn(nnode()-1,2+k);
4821  nodal_eqn(nnode()-1,k) = nodal_local_eqn(nnode()-3,2+k);
4822  }
4823  }
4824  else
4825  {
4826  for(unsigned k=0;k<n_position_type;k++)
4827  {
4828  nodal_eqn(0,k) = nodal_local_eqn(1,2+k);
4829  nodal_eqn(1,k) = nodal_local_eqn(2,2+k);
4830  nodal_eqn(2,k) = nodal_local_eqn(0,2+k);
4831  nodal_eqn(3,k) = nodal_local_eqn(4,2+k);
4832  nodal_eqn(4,k) = nodal_local_eqn(5,2+k);
4833  nodal_eqn(5,k) = nodal_local_eqn(3,2+k);
4834  nodal_eqn(nnode()-3,k) = nodal_local_eqn(nnode()-1,2+k);
4835  nodal_eqn(nnode()-2,k) = nodal_local_eqn(nnode()-3,2+k);
4836  nodal_eqn(nnode()-1,k) = nodal_local_eqn(nnode()-2,2+k);
4837  }
4838  }
4839  }
4840  }
4841 
4842  //=======================================================================
4843  /// Return FE interpolated value u[] at local coordinate s as Vector
4844  /// using Bell interpolations for the straight-edges triangle
4845  /// using C1-curved interpolations for the curve-edges triangle
4846  // This one is for the pre-permutation
4847  //=======================================================================
4848  void my_interpolated_u_normal1(const Vector<double> s, Vector<double> &interpolated_u, DenseMatrix<double> &interpolated_dudxi, DenseMatrix<double> &interpolated_d2udxi, DenseMatrix<double> &M)
4849  {
4850  // To check whether this element is on the boundary
4851  unsigned bd_element = is_boundary_element();
4852  //Find the number of positional types
4853  const unsigned n_position_type = nnodal_position_type();
4854  if(bd_element==0)
4855  {
4856  //Assign storage for the local shape function
4857  Shape psi(3,6);
4858  DShape dpsi(3,6,2), d2psi(3,6,3);
4859 
4860  //Assign shape functions and their derivatives
4861  d2basis_local_straight(s,psi,dpsi,d2psi);
4862 
4863  // Loop over nodes
4864  for(unsigned l=0;l<3;l++)
4865  {
4866  for(unsigned k=0;k<n_position_type;k++)
4867  {
4868  //Get the nodal value of the unknown
4869  double u_val = raw_nodal_value(l,k);
4870  interpolated_u[0] += u_val*psi(l,k);
4871 
4872  // Loop over directions
4873  for(unsigned j=0;j<2;j++)
4874  {
4875  interpolated_dudxi(0,j) += u_val*dpsi(l,k,j);
4876  }
4877  for(unsigned j=0;j<3;j++)
4878  {
4879  interpolated_d2udxi(0,j) += u_val*d2psi(l,k,j);
4880  }
4881  }
4882  }
4883  }
4884  // if it is the boundary element
4885  else if(bd_element==1)
4886  {
4887  Vector<double> u_value(36,0.0);
4888  // Get nodal values at nodes on the reference element
4889  get_nodal_value_curve1(u_value,M);
4890 
4891  // Assign storage for the local shape functio to a curved element
4892  Shape psi_curve(36),basis(36);
4893  DShape dpsi_curve(36,2), d2psi_curve(36,3), dbasis(36,2), d2basis(36,3);
4894 
4895  // derivative have to be wrt global coor.
4896  d2basis_eulerian_curve(s,psi_curve,dpsi_curve,d2psi_curve);
4897  for(unsigned i=0;i<36;i++)
4898  {
4899  interpolated_u[0] += u_value[i]*psi_curve[i];
4900  // Loop over directions
4901  for(unsigned j=0;j<2;j++)
4902  {
4903  interpolated_dudxi(0,j) += u_value[i]*dpsi_curve(i,j);
4904  }
4905  for(unsigned j=0;j<3;j++)
4906  {
4907  interpolated_d2udxi(0,j) += u_value[i]*d2psi_curve(i,j);
4908  }
4909  }
4910  }
4911  }
4912 
4913  //=======================================================================
4914  /// Return FE interpolated value u[] at local coordinate s as Vector
4915  /// using Bell interpolations for the straight-edges triangle
4916  /// using C1-curved interpolations for the curve-edges triangle
4917  // This one is for post-permutation
4918  //=======================================================================
4919  void my_interpolated_u_normal(const Vector<double> s, Vector<double> &interpolated_u, DenseMatrix<double> &interpolated_dudxi, DenseMatrix<double> &interpolated_d2udxi)
4920  const
4921  {
4922  // To check whether this element is on the boundary
4923  unsigned bd_element = is_boundary_element();
4924 
4925  //Find the number of positional types
4926  const unsigned n_position_type = nnodal_position_type();
4927 
4928  if(bd_element==0)
4929  {
4930  //Assign storage for the local shape function
4931  Shape psi(3,6);
4932  DShape dpsi(3,6,2), d2psi(3,6,3);
4933  //Assign shape functions and their derivatives
4934  d2basis_local_straight(s,psi,dpsi,d2psi);
4935 
4936  // Loop over nodes
4937  for(unsigned l=0;l<3;l++)
4938  {
4939  for(unsigned k=0;k<n_position_type;k++)
4940  {
4941  //Get the nodal value of the poisson unknown
4942  double u_val = raw_nodal_value(l,2+k);
4943  interpolated_u[0] += u_val*psi(l,k);
4944  // Loop over directions
4945  for(unsigned j=0;j<2;j++)
4946  {
4947  interpolated_dudxi(0,j) += u_val*dpsi(l,k,j);
4948  }
4949  for(unsigned j=0;j<3;j++)
4950  {
4951  interpolated_d2udxi(0,j) += u_val*d2psi(l,k,j);
4952  }
4953  }
4954  }
4955  }
4956  // if it is the boundary element
4957  else if(bd_element==1)
4958  {
4959  // assign degrees of freedom to the reference element
4960  DenseMatrix<double> D(21,21), B(21,36);
4961  Vector<double> temp(21,0.0);
4962  Vector<double> u_value(36,0.0);
4963  DenseMatrix<double> position(3,2);
4964  unsigned bd_element;
4965  DenseMatrix<double> bd_position(20,2);
4966  Vector<double> x(2);
4967  // Get nodal values at nodes on the reference element
4968  get_value_transform_matrix(D,B,position,bd_element,bd_position,x);
4969 
4970  Vector<double> value(21);
4971 
4972  double angle_1 = atan(bd_position(0,1)/bd_position(0,0));
4973  double angle_2 = atan(bd_position(1,1)/bd_position(1,0));
4974  if(angle_1 > angle_2)
4975  {
4976  DenseMatrix<double> nodal_value(3,n_position_type);
4977  for(unsigned k=0;k<n_position_type;k++)
4978  {
4979  nodal_value(0,k) = raw_nodal_value(2,2+k);
4980  nodal_value(1,k) = raw_nodal_value(0,2+k);
4981  nodal_value(2,k) = raw_nodal_value(1,2+k);
4982  }
4983  value[0] = nodal_value(0,0);
4984  value[1] = nodal_value(1,0);
4985  value[2] = nodal_value(2,0);
4986  value[3] = nodal_value(0,1);
4987  value[4] = nodal_value(0,2);
4988  value[5] = nodal_value(1,1);
4989  value[6] = nodal_value(1,2);
4990  value[7] = nodal_value(2,1);
4991  value[8] = nodal_value(2,2);
4992  value[9] = nodal_value(0,3);
4993  value[10] = nodal_value(0,5);
4994  value[11] = nodal_value(0,4);
4995  value[12] = nodal_value(1,3);
4996  value[13] = nodal_value(1,5);
4997  value[14] = nodal_value(1,4);
4998  value[15] = nodal_value(2,3);
4999  value[16] = nodal_value(2,5);
5000  value[17] = nodal_value(2,4);
5001  value[18] = raw_nodal_value(nnode()-3,2+0);
5002  value[19] = raw_nodal_value(nnode()-2,2+0);
5003  value[20] = raw_nodal_value(nnode()-1,2+0);
5004  }
5005  else if(angle_1 < angle_2)
5006  {
5007  if(position(0,0)==bd_position(0,0) && position(0,1)==bd_position(0,1))
5008  {
5009  value[0] = raw_nodal_value(0,2+0);
5010  value[1] = raw_nodal_value(1,2+0);
5011  value[2] = raw_nodal_value(2,2+0);
5012  value[3] = raw_nodal_value(0,2+1);
5013  value[4] = raw_nodal_value(0,2+2);
5014  value[5] = raw_nodal_value(1,2+1);
5015  value[6] = raw_nodal_value(1,2+2);
5016  value[7] = raw_nodal_value(2,2+1);
5017  value[8] = raw_nodal_value(2,2+2);
5018  value[9] = raw_nodal_value(0,2+3);
5019  value[10] = raw_nodal_value(0,2+5);
5020  value[11] = raw_nodal_value(0,2+4);
5021  value[12] = raw_nodal_value(1,2+3);
5022  value[13] = raw_nodal_value(1,2+5);
5023  value[14] = raw_nodal_value(1,2+4);
5024  value[15] = raw_nodal_value(2,2+3);
5025  value[16] = raw_nodal_value(2,2+5);
5026  value[17] = raw_nodal_value(2,2+4);
5027  value[18] = raw_nodal_value(nnode()-2,2+0);
5028  value[19] = raw_nodal_value(nnode()-1,2+0);
5029  value[20] = raw_nodal_value(nnode()-3,2+0);
5030  }
5031  else
5032  {
5033  DenseMatrix<double> nodal_value(3,n_position_type);
5034  for(unsigned k=0;k<n_position_type;k++)
5035  {
5036  nodal_value(2,k) = raw_nodal_value(0,2+k);
5037  nodal_value(0,k) = raw_nodal_value(1,2+k);
5038  nodal_value(1,k) = raw_nodal_value(2,2+k);
5039  }
5040  value[0] = nodal_value(0,0);
5041  value[1] = nodal_value(1,0);
5042  value[2] = nodal_value(2,0);
5043  value[3] = nodal_value(0,1);
5044  value[4] = nodal_value(0,2);
5045  value[5] = nodal_value(1,1);
5046  value[6] = nodal_value(1,2);
5047  value[7] = nodal_value(2,1);
5048  value[8] = nodal_value(2,2);
5049  value[9] = nodal_value(0,3);
5050  value[10] = nodal_value(0,5);
5051  value[11] = nodal_value(0,4);
5052  value[12] = nodal_value(1,3);
5053  value[13] = nodal_value(1,5);
5054  value[14] = nodal_value(1,4);
5055  value[15] = nodal_value(2,3);
5056  value[16] = nodal_value(2,5);
5057  value[17] = nodal_value(2,4);
5058  value[18] = raw_nodal_value(nnode()-1,2+0);
5059  value[19] = raw_nodal_value(nnode()-3,2+0);
5060  value[20] = raw_nodal_value(nnode()-2,2+0);
5061  }
5062  }
5063 
5064  for(unsigned i=0;i<21;i++)
5065  {
5066  for(unsigned j=0;j<21;j++)
5067  {
5068  // get values wrt local coordinates
5069  temp[i] += value[j]*D(j,i);
5070  }
5071  }
5072 
5073  for(unsigned i=0;i<36;i++)
5074  {
5075  for(unsigned j=0;j<21;j++)
5076  {
5077  u_value[i] += temp[j]*B(j,i);
5078  }
5079  }
5080 
5081  // Assign storage for the local shape functio to a curved element
5082  Shape psi_curve(36),basis(36);
5083  DShape dpsi_curve(36,2), d2psi_curve(36,3), dbasis(36,2), d2basis(36,3);
5084  // derivative have to be wrt global coor.
5085  d2basis_eulerian_curve(s,psi_curve,dpsi_curve,d2psi_curve);
5086 
5087  for(unsigned i=0;i<36;i++)
5088  {
5089  interpolated_u[0] += u_value[i]*psi_curve[i];
5090  // Loop over directions
5091  for(unsigned j=0;j<2;j++)
5092  {
5093  interpolated_dudxi(0,j) += u_value[i]*dpsi_curve(i,j);
5094  }
5095  for(unsigned j=0;j<3;j++)
5096  {
5097  interpolated_d2udxi(0,j) += u_value[i]*d2psi_curve(i,j);
5098  }
5099  }
5100  }
5101  }
5102 
5103  //=======================================================================
5104  /// Return FE interpolated value u[] at local coordinate s as Vector
5105  // (using Lagrange interpolations)
5106  //=======================================================================
5107  void my_interpolated_u_tangential(const Vector<double> s, Vector<double> &interpolated_u, DenseMatrix<double> &interpolated_dudxi)
5108  const
5109  {
5110  unsigned n_node = nnode()-3;
5111 
5112  //Local shape function
5113  Shape psi(n_node);
5114  DShape dpsi(n_node,2);
5115  this->dbasis_c0_eulerian(s,psi,dpsi);
5116 
5117  //Interpolated in tangential direction
5118  for(unsigned l=0;l<n_node;l++)
5119  {
5120  interpolated_u[0] += this->raw_nodal_value(l,0)*psi[l];
5121  interpolated_u[1] += this->raw_nodal_value(l,1)*psi[l];
5122  // Loop over directions
5123  for(unsigned j=0;j<2;j++)
5124  {
5125  interpolated_dudxi(0,j) += this->raw_nodal_value(l,0)*dpsi(l,j);
5126  interpolated_dudxi(1,j) += this->raw_nodal_value(l,1)*dpsi(l,j);
5127  }
5128  }
5129  }
5130 
5131 };
5132 
5133 /////////////////////////////////////////////////////////////////////////////
5134 /// General C1CurvedElement class ///
5135 /// Empty, just establishes the template parameters
5136 /////////////////////////////////////////////////////////////////////
5137 template<unsigned DIM, unsigned NNODE_1D>
5139 
5140 //=======================================================================
5141 /// C1CurvedElement elements, specialised to two spatial dimensions
5142 //=======================================================================
5143 template<unsigned NNODE_1D>
5144 class C1CurvedElement<2,NNODE_1D> : public virtual C1CurvedElementBase<NNODE_1D>, public virtual TElement<2,NNODE_1D>, public virtual GeometricTElement<2>, public virtual C1CurvedElementShape<2,NNODE_1D>, public virtual BellElementShape<2>
5145 {
5146  private:
5147  /// Nodal translation scheme for use when generating face elements
5148  static const unsigned NodeOnFace[3][NNODE_1D];
5149 
5150  public :
5151 
5152  ///\short Constructor: Call constructors for C1CurvedElement
5153  C1CurvedElement() : C1CurvedElementBase<NNODE_1D>(), TElement<2,NNODE_1D>(),
5155  {
5156  // Number of nodes
5157  switch (NNODE_1D)
5158  {
5159  case 2:
5160  case 3:
5161  break;
5162 
5163  default:
5164  std::string error_message =
5165  "Triangles are currently only implemented for\n";
5166  error_message +=
5167  "three vertices and three internal nodes, i.e. NNODE_1D=2,3 only\n";
5168 
5169  throw OomphLibError(error_message,
5170  "CurvedTElement::CurvedTElement()",
5171  OOMPH_EXCEPTION_LOCATION);
5172  }
5173 
5174  // Set the number of nodes
5175  unsigned n_node = (NNODE_1D*(NNODE_1D+1))/2 + 3;
5176  this->set_n_node(n_node);
5177  // Set the elemental and nodal dimension
5178  this->set_dimension(2);
5179  //Set the number of types required to interpolate the coordinate
5180  this->set_nnodal_position_type(6);
5181  TGauss<2,5>* new_integral_pt = new TGauss<2,5>;
5182  this->set_integration_scheme(new_integral_pt);
5183  }
5184 
5185  /// Broken copy constructor
5187  {
5188  BrokenCopy::broken_copy("C1CurvedElement");
5189  }
5190 
5191  /// Broken assignment operator
5193  {
5194  BrokenCopy::broken_assign("C1CurvedElement");
5195  }
5196  /// Destructor
5198 
5199  /// Number of nodes along each element edge
5200  unsigned nnode_1d() const {return NNODE_1D;}
5201 
5202  /// \short Number of vertex nodes in the element: One more
5203  /// than spatial dimension
5204  unsigned nvertex_node() const {return 3;}
5205 
5206  /// Number of internal nodes
5207  unsigned ninternal_node() const {return 3;}
5208 
5209  /// \short Pointer to the j-th vertex node in the element
5210  Node* vertex_node_pt(const unsigned& j) const
5211  {
5212  // Vertex nodes come first:
5213 #ifdef PARANOID
5214  if (j>2)
5215  {
5216  std::ostringstream error_message;
5217  error_message
5218  << "Element only has three vertex nodes; called with node number "
5219  << j << std::endl;
5220  throw OomphLibError(error_message.str(),
5221  "TElement::vertex_node_pt()",
5222  OOMPH_EXCEPTION_LOCATION);
5223  }
5224 #endif
5225  return this->node_pt(j);
5226  }
5227 
5228  // Classify nodes on the element: boundary nodes and non-boundary nodes
5229  inline void classify_boundary_node(DenseMatrix<double> &node_position,
5230  unsigned &bd_element, DenseMatrix<double> &bd_node_position, Vector<double> &x) const
5231  {
5232  /// Number of nodes along each element edge: Just for the three vertices not the internal points
5233  unsigned n_node = 3;
5234  /// Loop over vertices
5235  for(unsigned l=0;l<n_node;l++)
5236  {
5237  for(unsigned k=0;k<1;k++)
5238  {
5239  for(unsigned j=0;j<2;j++)
5240  {
5241  node_position(l,j) = this->raw_nodal_position_gen(l,k,j);
5242  }
5243  }
5244  }
5245 
5246  int count=0;
5247 
5248  // check whether this element is on boundary or not
5249  for(unsigned i=0;i<n_node;i++)
5250  {
5251  // check whether this node is on 1st boundary (curve boundary)
5252  bool bd_node1 = this->node_pt(i)->is_on_boundary(1);
5253  if(bd_node1==1)
5254  {
5255  count += 1;
5256  for(unsigned k=0;k<1;k++)
5257  {
5258  for(unsigned j=0;j<2;j++)
5259  {
5260  bd_node_position(count-1,j) = this->raw_nodal_position_gen(i,k,j);
5261  }
5262  }
5263  }
5264  else
5265  {
5266  for(unsigned k=0;k<1;k++)
5267  {
5268  for(unsigned j=0;j<2;j++)
5269  {
5270  x[j] = this->raw_nodal_position_gen(i,k,j);
5271  }
5272  }
5273  }
5274  }
5275  if(count == 2)// this case is a boundary element
5276  {
5277  bd_element = 1;
5278  }
5279  else
5280  {
5281  bd_element = 0;
5282  }
5283  }
5284 
5285  // assign the set of value for a curved element
5287  unsigned &bd_element, DenseMatrix<double> &bd_node_position, Vector<double> &x) const
5288  {
5289  /// classify nodes in the element
5290  classify_boundary_node(node_position,bd_element,bd_node_position,x);
5291  /// compute the set of value of degree of freedom
5292  C1CurvedElementShape<2,NNODE_1D>::set_of_value(D,B,node_position,bd_element,bd_node_position,x);
5293  }
5294 
5295  /// Return local coordinates of node j
5296  inline void local_coordinate_of_node(const unsigned& j,Vector<double>& s) const
5298 
5299  /// Calculate the c1-shape functions associated with a straight-sided
5300  /// boundary at local coordinate s
5301  inline void basis_straight(const Vector<double> &s, Shape &psi) const
5302  {
5303  /// classify nodes in the element
5304  DenseMatrix<double> node_position(3,2);
5305  DenseMatrix<double> bd_node_position(20,2);
5306  Vector<double> x(2);
5307  unsigned bd_element;
5308  classify_boundary_node(node_position,bd_element,bd_node_position,x);
5309  BellElementShape<2>::Bshape(s,psi,node_position);
5310  }
5311 
5312  /// \short Compute the c1-shape functions associated with a straight-sided
5313  /// boundary and derivatives w.r.t. global coordinates at local coordinate s
5314  inline void dbasis_local_straight(const Vector<double> &s, Shape &psi,
5315  DShape &dpsids) const
5316  {
5317  /// classify nodes in the element
5318  DenseMatrix<double> node_position(3,2);
5319  DenseMatrix<double> bd_node_position(20,2);
5320  Vector<double> x(2);
5321  unsigned bd_element;
5322  classify_boundary_node(node_position,bd_element,bd_node_position,x);
5323  BellElementShape<2>::dBshape_local(s,psi,dpsids,node_position);
5324  }
5325 
5326  /// \short Compute the c1-shape functions associated with a straight-sided
5327  /// boundary and derivatives w.r.t. global coordinates at local coordinate s
5328  inline void d2basis_local_straight(const Vector<double> &s, Shape &psi,
5329  DShape &dpsids, DShape &d2psids) const
5330  {
5331  /// classify nodes in the element
5332  DenseMatrix<double> node_position(3,2);
5333  DenseMatrix<double> bd_node_position(20,2);
5334  Vector<double> x(2);
5335  unsigned bd_element;
5336  classify_boundary_node(node_position,bd_element,bd_node_position,x);
5337  BellElementShape<2>::d2Bshape_local(s,psi,dpsids,d2psids,node_position);
5338  }
5339 
5340  /// Calculate the c1-shape functions associated with a curved-sided
5341  /// boundary at local coordinate s
5342  inline void basis_curve(const Vector<double> &s, Shape &psi) const
5343  {
5345  }
5346 
5347  /// \short Compute the c1-shape functions associated with a curved-sided
5348  /// boundary and derivatives w.r.t. local coordinates at local coordinate s
5349  inline void dbasis_local_curve(const Vector<double> &s, Shape &psi,
5350  DShape &dpsids) const
5351  {
5353  }
5354 
5355  /// \short Compute the c1-shape functions associated with a curved-sided
5356  /// boundary and derivatives w.r.t. local coordinates at local coordinate s
5357  inline void d2basis_local_curve(const Vector<double> &s, Shape &psi,
5358  DShape &dpsids, DShape &d2psids) const
5359  {
5361  }
5362 
5363  /// Calculate the linear shape functions at local coordinate s
5364  inline void shape_geom(const Vector<double> &s, Shape &psi, Shape &phi) const
5365  {
5366  /// classify nodes in the element
5367  DenseMatrix<double> node_position(3,2);
5368  DenseMatrix<double> bd_node_position(20,2);
5369  Vector<double> x(2);
5370  unsigned bd_element;
5371  classify_boundary_node(node_position,bd_element,bd_node_position,x);
5372  // Calculate the geometric shape functions at local coordinate s
5373  GeometricTElement<2>::Lshape(s,psi,phi,node_position,bd_element,bd_node_position,x);
5374  }
5375 
5376  /// \short Compute the linear functions and
5377  /// derivatives w.r.t. local coordinates at local coordinate s
5378  inline void dshape_local_geom(const Vector<double> &s, Shape &psi,
5379  DShape &dpsids, Shape &phi,
5380  DShape &dphids) const
5381  {
5382  /// classify nodes in the element
5383  DenseMatrix<double> node_position(3,2);
5384  DenseMatrix<double> bd_node_position(20,2);
5385  Vector<double> x(2);
5386  unsigned bd_element;
5387  classify_boundary_node(node_position,bd_element,bd_node_position,x);
5388  GeometricTElement<2>::dLshape_local(s,psi,dpsids,phi,dphids,node_position,bd_element,bd_node_position,x);
5389  }
5390 
5391  /// \short Compute the linear functions and
5392  /// derivatives w.r.t. local coordinates at local coordinate s
5393  inline void d2shape_local_geom(const Vector<double> &s, Shape &psi,
5394  DShape &dpsids, DShape &d2psids, Shape &phi,
5395  DShape &dphids, DShape &d2phids) const
5396  {
5397  /// classify nodes in the element
5398  DenseMatrix<double> node_position(3,2);
5399  DenseMatrix<double> bd_node_position(20,2);
5400  Vector<double> x(2);
5401  unsigned bd_element;
5402  classify_boundary_node(node_position,bd_element,bd_node_position,x);
5403  GeometricTElement<2>::d2Lshape_local(s,psi,dpsids,d2psids,phi,dphids,d2phids,node_position,bd_element,bd_node_position,x);
5404  }
5405 
5406  /// Calculate the c0-shape functions at local coordinate s
5407  inline void basis_c0(const Vector<double> &s, Shape &psi) const
5408  {
5410  }
5411 
5412  /// \short Compute the c0-shape functions and
5413  /// derivatives w.r.t. local coordinates at local coordinate s
5414  inline void dbasis_c0_local(const Vector<double> &s, Shape &psi,
5415  DShape &dpsids) const
5416  {
5418  }
5419 
5420  /// \short Computer the c0-shape functions, derivatives and
5421  /// second derivatives w.r.t local coordinates at local coordinate s \n
5422  /// d2psids(i,0) = \f$ \partial^2 \psi_j / \partial s_0^2 \f$ \n
5423  /// d2psids(i,1) = \f$ \partial^2 \psi_j / \partial s_1^2 \f$ \n
5424  /// d2psids(i,2) = \f$ \partial^2 \psi_j / \partial s_0 \partial s_1 \f$ \n
5425  inline void d2basis_c0_local(const Vector<double> &s, Shape &psi,
5426  DShape &dpsids, DShape &d2psids) const
5427  {
5428  TElementShape<2,NNODE_1D>::d2shape_local(s,psi,dpsids,d2psids);
5429  }
5430 
5431  /// Calculate the test functions at local coordinate s
5432  inline void test(const Vector<double> &s, Shape &psi) const
5433  {
5435  }
5436 
5437  /// \short Compute the test functions and
5438  /// derivatives w.r.t. local coordinates at local coordinate s
5439  inline void dtest_local(const Vector<double> &s, Shape &psi,
5440  DShape &dpsids) const
5441  {
5443  }
5444 
5445  /// \short Computer the geometric shape functions, derivatives and
5446  /// second derivatives w.r.t local coordinates at local coordinate s \n
5447  /// d2psids(i,0) = \f$ \partial^2 \psi_j / \partial s_0^2 \f$ \n
5448  /// d2psids(i,1) = \f$ \partial^2 \psi_j / \partial s_1^2 \f$ \n
5449  /// d2psids(i,2) = \f$ \partial^2 \psi_j / \partial s_0 \partial s_1 \f$ \n
5450  inline void d2test_local(const Vector<double> &s, Shape &psi,
5451  DShape &dpsids, DShape &d2psids) const
5452  {
5453  TElementShape<2,NNODE_1D>::d2shape_local(s,psi,dpsids,d2psids);
5454  }
5455 
5456  /// \short Build the lower-dimensional FaceElement (an element of type
5457  /// SolidTElement<1,NNODE_1D>). The face index takes three possible values:
5458  /// 0 (Left) s[0] = 0.0
5459  /// 1 (Bottom) s[1] = 0.0
5460  /// 2 (Sloping face) s[0] = 1.0 - s[1]
5461  void build_face_element(const int &face_index,
5462  FaceElement* face_element_pt);
5463 
5464 };
5465 
5466 //===========================================================
5467 /// Function to setup geometrical information for lower-dimensional
5468 /// FaceElements (which are of type TElement<1,NNODE_1D>).
5469 //===========================================================
5470 template<unsigned NNODE_1D>
5472 build_face_element(const int &face_index, FaceElement *face_element_pt)
5473 {
5474  //Build the standard non-solid FaceElement
5475  TElement<2,NNODE_1D>::build_face_element(face_index,face_element_pt);
5476 }
5477 
5478 //=======================================================================
5479 /// Face geometry for the 2D C1CurvedElement elements is exactly
5480 /// the same as for the corresponding TElement. The spatial
5481 /// dimension of the face elements is one lower than that of the
5482 /// bulk element but they have the same number of points
5483 /// along their 1D edges.
5484 //=======================================================================
5485 template<unsigned NNODE_1D>
5486 class FaceGeometry<C1CurvedElement<2,NNODE_1D> >:
5487 public virtual TElement<1,NNODE_1D>
5488 {
5489 
5490  public:
5491 
5492  /// \short Constructor: Call the constructor for the
5493  /// appropriate lower-dimensional QElement
5494  FaceGeometry() : TElement<1,NNODE_1D>() {}
5495 
5496 };
5497 
5498 
5499 }
5500 #endif
void local_coordinate_of_node(const unsigned &j, Vector< double > &s) const
Return local coordinates of node j.
void myassemble_local_to_eulerian_jacobian2(const DShape &d2psids, DenseMatrix< double > &jacobian2) const
void my_interpolated_x(const Vector< double > &s, Vector< double > &x) const
Return FE interpolated position x[] at local coordinate s as Vector.
void broken_copy(const std::string &class_name)
Issue error message and terminate execution.
void dbasis_c0_local_at_knot(const unsigned &ipt, Shape &psi, DShape &dpsids) const
Return the C0-basis function and its derivatives w.r.t. the local coordinates at the ipt-th integrati...
void d2basis_local_curve(const Vector< double > &s, Shape &psi_curve, DShape &dpsi_curve, DShape &d2psi_curve) const
double local_to_eulerian_mapping2(const DShape &dpsids, DShape &dphids, DenseMatrix< double > &inverse_jacobian) const
Calculate the mapping from local to Eulerian coordinates, given the derivatives of the shape function...
void get_nodal_value_curve1(Vector< double > &u_value, DenseMatrix< double > &M)
Return raw nodal value for nodes specified on the reference triangle.
void local_coordinate_of_node(const unsigned &j, Vector< double > &s) const
Return local coordinates of node j.
void my_interpolated_u_normal1(const Vector< double > s, Vector< double > &interpolated_u, DenseMatrix< double > &interpolated_dudxi, DenseMatrix< double > &interpolated_d2udxi, DenseMatrix< double > &M)
virtual double local_to_eulerian_mapping2(const DShape &dpsids, DenseMatrix< double > &jacobian, DenseMatrix< double > &inverse_jacobian) const
void Cshape(const Vector< double > &s, Shape &psi_curve) const
void d2shape_local_at_knot_geom(const unsigned &ipt, Shape &psi, DShape &dpsids, DShape &d2psids, Shape &phi, DShape &dphids, DShape &d2phids) const
virtual void basis_curve(const Vector< double > &s, Shape &psi) const
void Bshape(const Vector< double > &s, Shape &psi, DenseMatrix< double > &position) const
unsigned nnode_1d() const
Number of nodes along each element edge.
void basis_c0(const Vector< double > &s, Shape &psi) const
Calculate the c0-basis functions at local coordinate s.
double dbasis_eulerian(const Vector< double > &s, Shape &psi, DShape &dpsi) const
Compute the c1-basis functions and also first derivatives w.r.t. global coordinates at local coordina...
virtual void dbasis_local_curve(const Vector< double > &s, Shape &psi, DShape &dpsids) const
virtual void d2test_local(const Vector< double > &s, Shape &phi, DShape &dphids, DShape &d2phids) const
void d2basis_c0_local_at_knot(const unsigned &ipt, Shape &psi, DShape &dpsids, DShape &d2psids) const
cstr elem_len * i
Definition: cfortran.h:607
void dtest_local(const Vector< double > &s, Shape &psi, DShape &dpsids) const
Compute the test functions and derivatives w.r.t. local coordinates at local coordinate s...
virtual void basis(const Vector< double > &s, Shape &psi) const
virtual void d2basis_local_straight(const Vector< double > &s, Shape &psi, DShape &dpsids, DShape &d2psids) const
void d2test_local(const Vector< double > &s, Shape &psi, DShape &dpsids, DShape &d2psids) const
Computer the geometric shape functions, derivatives and second derivatives w.r.t local coordinates at...
void d2basis_local(const Vector< double > &s, Shape &psi, DShape &dpsids, DShape &d2psids) const
Compute the c1-basis functions and.
virtual void shape_geom(const Vector< double > &s, Shape &psi, Shape &phi) const
double dshape_and_dtest_eulerian_at_knot(const unsigned &ipt, Shape &psi, DShape &dpsi, Shape &test, DShape &dtest) const
void d2basis_c0_local_at_knot(const unsigned &ipt, Shape &psi, DShape &dpsids, DShape &d2psids) const
FaceGeometry()
Constructor: Call the constructor for the appropriate lower-dimensional QElement. ...
void dbasis_c0_local_at_knot(const unsigned &ipt, Shape &psi, DShape &dpsids) const
Return the c0-shape function and its derivatives w.r.t. the local coordinates at the ipt-th integrati...
double d2basis_c0_eulerian(const Vector< double > &s, Shape &psi, DShape &dpsi, DShape &d2psi) const
Compute the c0-shape functions and also the first and the second derivatives w.r.t.global coordinates at local coordinate s; Returns Jacobian of mapping from global to local coordinates. Most general form of the function, but may be over-loaded, if desired.
double dbasis_c0_eulerian(const Vector< double > &s, Shape &psi, DShape &dpsi) const
Compute the curved-element shape functions and also first derivatives w.r.t. local coordinates at loc...
void basis(const Vector< double > &s, Shape &psi) const
Calculate the c1-basis functions at local coordinate s.
A general Finite Element class.
Definition: elements.h:1274
void dbasis_local_at_knot_straight(const unsigned &ipt, Shape &psi, DShape &dpsids) const
Return the c1-shape function associated with a straight-sided boundary and its derivatives w...
void dshape_local(const Vector< double > &s, Shape &psi, DShape &dpsids) const
Compute the geometric shape functions and derivatives w.r.t. local coordinates at local coordinate s...
char t
Definition: cfortran.h:572
virtual double local_to_eulerian_mapping2(const DShape &dpsids, DShape &dphids, DenseMatrix< double > &jacobian, DenseMatrix< double > &inverse_jacobian) const
void dBshape_local(const Vector< double > &s, Shape &psi, DShape &dpsids, DenseMatrix< double > &position) const
void operator=(const BellElement &)
Broken assignment operator.
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
Definition: nodes.h:852
void basis_c0_at_knot(const unsigned &ipt, Shape &psi) const
Return the C0-basis function stored at the ipt-th integration point.
void dbasis_c0_local(const Vector< double > &s, Shape &psi, DShape &dpsids) const
Compute the c0-basis functions and derivatives w.r.t. local coordinates at local coordinate s...
void d2basis_local_straight(const Vector< double > &s, Shape &psi, DShape &dpsids, DShape &d2psids) const
Compute the c1-shape functions associated with a straight-sided.
OomphInfo oomph_info
virtual void classify_boundary_node(DenseMatrix< double > &node_position, unsigned &bd_element, DenseMatrix< double > &bd_node_position, Vector< double > &x) const
void d2basis_local_at_knot_straight(const unsigned &ipt, Shape &psi, DShape &dpsids, DShape &d2psids) const
void d2shape_local(const Vector< double > &s, Shape &psi, DShape &dpsids, DShape &d2psids) const
Computer the geometric shape functions, derivatives and second derivatives w.r.t local coordinates at...
BellElementBase()
Constructor: Call constructors for FiniteElement.
void dbasis_local_straight(const Vector< double > &s, Shape &psi, DShape &dpsids) const
Compute the c1-shape functions associated with a straight-sided boundary and derivatives w...
double d2basis_eulerian(const Vector< double > &s, Shape &psi, DShape &dpsi, DShape &d2psi) const
Compute the c1-basis functions and also first and second derivatives w.r.t. global coordinates at ipt...
void local_coordinate_of_node(const unsigned &j, Vector< double > &s) const
Return local coordinates of node j.
virtual void get_value_transform_matrix(DenseMatrix< double > &D, DenseMatrix< double > &B, DenseMatrix< double > &node_position, unsigned &bd_element, DenseMatrix< double > &bd_node_position, Vector< double > &x) const
void dLshape_local(const Vector< double > &s, Shape &psi, DShape &dpsids) const
Derivatives of shape functions for specific TElement<2,2>
void basis_c0(const Vector< double > &s, Shape &psi) const
Calculate the c0-shape functions at local coordinate s.
double J_eulerian1(const Vector< double > &s) const
Calculate the Jacobian of the mapping between local and global coordinates at the position s...
void basis_curve(const Vector< double > &s, Shape &psi_curve) const
virtual void d2basis_local(const Vector< double > &s, Shape &psi, DShape &dpsids, DShape &d2psids) const
void dLshape_local(const Vector< double > &s, Shape &psi, DShape &dpsids, Shape &phi, DShape &dphids, DenseMatrix< double > &position, unsigned &bd_element, DenseMatrix< double > &bd_position, Vector< double > &x) const
void test(const Vector< double > &s, Shape &psi) const
Calculate the test functions at local coordinate s.
void myassemble_local_to_eulerian_jacobian2(const DShape &d2psids, DenseMatrix< double > &jacobian2) const
void dbasis_local_curve(const Vector< double > &s, Shape &psi, DShape &dpsids) const
Compute the c1-shape functions associated with a curved-sided boundary and derivatives w...
void shape_geom(const Vector< double > &s, Shape &psi, Shape &phi) const
Calculate the linear shape functions at local coordinate s.
virtual void basis_c0(const Vector< double > &s, Shape &psi) const
void get_coefficient(DenseMatrix< double > &A) const
void d2shape_local_geom(const Vector< double > &s, Shape &psi, DShape &dpsids, DShape &d2psids, Shape &phi, DShape &dphids, DShape &d2phids) const
Compute the linear functions and derivatives w.r.t. local coordinates at local coordinate s...
void set_of_value(DenseMatrix< double > &D, DenseMatrix< double > &B, DenseMatrix< double > &position, unsigned &bd_element, DenseMatrix< double > &bd_position, Vector< double > &x) const
C1CurvedElement()
Constructor: Call constructors for C1CurvedElement.
void Lshape(const Vector< double > &s, Shape &psi, Shape &phi, DenseMatrix< double > &position, unsigned &bd_element, DenseMatrix< double > &bd_position, Vector< double > &x) const
void my_interpolated_x(const Vector< double > &s, Vector< double > &x) const
Return FE interpolated position x[] at local coordinate s as Vector.
void d2Bshape_local(const Vector< double > &s, Shape &psi, DShape &dpsids, DShape &d2psids, DenseMatrix< double > &position) const
void basis_c0_at_knot(const unsigned &ipt, Shape &psi) const
Return the c0-shape function stored at the ipt-th integration.
virtual void dtest_local(const Vector< double > &s, Shape &phi, DShape &dphids) const
void d2test_local_at_knot(const unsigned &ipt, Shape &phi, DShape &dphids, DShape &d2phids) const
void d2Lshape_local(const Vector< double > &s, Shape &psi, DShape &dpsids, DShape &d2psids, Shape &phi, DShape &dphids, DShape &d2phids, DenseMatrix< double > &position, unsigned &bd_element, DenseMatrix< double > &bd_position, Vector< double > &x) const
virtual void dbasis_c0_local(const Vector< double > &s, Shape &psi, DShape &dpsids) const
void get_nodal_eqn_curve(DenseMatrix< int > &nodal_eqn)
void dshape_local_geom(const Vector< double > &s, Shape &psi, DShape &dpsids, Shape &phi, DShape &dphids) const
Compute the linear functions and derivatives w.r.t. local coordinates at local coordinate s...
static char t char * s
Definition: cfortran.h:572
virtual void basis_c0(const Vector< double > &s, Shape &psi) const
virtual void d2shape_local_geom(const Vector< double > &s, Shape &psi, DShape &dpsids, DShape &d2psids, Shape &phi, DShape &dphids, DShape &d2phids) const
void dbasis_local_curve(const Vector< double > &s, Shape &psi_curve, DShape &dpsi_curve) const
virtual void dbasis_local(const Vector< double > &s, Shape &psi, DShape &dpsids) const
double magnitude(const Vector< double > &a)
Get the magnitude of a vector.
Definition: Vector.h:301
Node * vertex_node_pt(const unsigned &j) const
Pointer to the j-th vertex node in the element.
double dshape_and_dtest_eulerian_at_knot(const unsigned &ipt, Shape &psi, DShape &dpsi, Shape &test, DShape &dtest) const
void dtest_local_at_knot(const unsigned &ipt, Shape &phi, DShape &dphids) const
Return the test function and its derivatives w.r.t. the local coordinates at the ipt-th integration p...
C1CurvedElementBase()
Constructor: Call constructors for FiniteElement.
BellElement(const BellElement &)
Broken copy constructor.
void get_value_transform_matrix(DenseMatrix< double > &D, DenseMatrix< double > &B, DenseMatrix< double > &node_position, unsigned &bd_element, DenseMatrix< double > &bd_node_position, Vector< double > &x) const
virtual void basis_straight(const Vector< double > &s, Shape &psi) const
void dtest_local_at_knot(const unsigned &ipt, Shape &phi, DShape &dphids) const
Return the test function and its derivatives w.r.t. the local coordinates at the ipt-th integration p...
void shape(const Vector< double > &s, Shape &psi) const
Calculate the geometric shape functions at local coordinate s.
void basis_straight(const Vector< double > &s, Shape &psi) const
void basis_at_knot_straight(const unsigned &ipt, Shape &psi) const
Return the c1-shape function associated with a straight-sided.
virtual void d2basis_local_curve(const Vector< double > &s, Shape &psi, DShape &dpsids, DShape &d2psids) const
void Lshape(const Vector< double > &s, Shape &psi) const
Shape function for specific TElement<2,2>
virtual void d2basis_c0_local(const Vector< double > &s, Shape &psi, DShape &dpsids, DShape &d2psids) const
void shape(const double &s, double *Psi)
Definition for 1D Lagrange shape functions. The value of all the shape functions at the local coordin...
Definition: shape.h:549
virtual void dshape_local_geom(const Vector< double > &s, Shape &psi, DShape &dpsids, Shape &phi, DShape &dphids) const
double d2basis_c0_eulerian(const Vector< double > &s, Shape &psi, DShape &dpsi, DShape &d2psi) const
Compute the c0-basis functions and also first and second derivatives w.r.t. local coordinates at ipt-...
BellElement()
Constructor: Call constructors for BellElement.
void dbasis_c0_local(const Vector< double > &s, Shape &psi, DShape &dpsids) const
Compute the c0-shape functions and derivatives w.r.t. local coordinates at local coordinate s...
double d2shape_and_d2test_eulerian_at_knot(const unsigned &ipt, Shape &psi, DShape &dpsi, DShape &d2psi, Shape &test, DShape &dtest, DShape &d2test) const
Compute the c1-shape functions that associated with the straight- boundary element and also first and...
void operator=(const C1CurvedElement &)
Broken assignment operator.
double dbasis_c0_eulerian(const Vector< double > &s, Shape &psi, DShape &dpsi) const
Compute the c0-shape functions and also first derivatives w.r.t. global coordinates at local coordina...
void dbasis_local(const Vector< double > &s, Shape &psi, DShape &dpsids) const
Compute the c1-basis functions and derivatives w.r.t. global coordinates at local coordinate s...
void dshape_local_at_knot_geom(const unsigned &ipt, Shape &psi, DShape &dpsids, Shape &phi, DShape &dphids) const
Return the geometric shape function and its derivatives w.r.t. the local coordinates at the ipt-th in...
void d2basis_local_curve(const Vector< double > &s, Shape &psi, DShape &dpsids, DShape &d2psids) const
Compute the c1-shape functions associated with a curved-sided.
void shape_at_knot_geom(const unsigned &ipt, Shape &psi, Shape &phi) const
Return the geometric shape function stored at the ipt-th integration point.
void my_interpolated_u_tangential(const Vector< double > s, Vector< double > &interpolated_u, DenseMatrix< double > &interpolated_dudxi) const
Return FE interpolated value u[] at local coordinate s as Vector.
void basis_at_knot(const unsigned &ipt, Shape &psi) const
Return the C1-basis function stored at the ipt-th integration point.
void dbasis_local_at_knot_curve(const unsigned &ipt, Shape &psi, DShape &dpsids) const
void my_interpolated_u_normal(const Vector< double > s, Vector< double > &interpolated_u, DenseMatrix< double > &interpolated_dudxi, DenseMatrix< double > &interpolated_d2udxi) const
void broken_assign(const std::string &class_name)
Issue error message and terminate execution.
void d2basis_c0_local(const Vector< double > &s, Shape &psi, DShape &dpsids, DShape &d2psids) const
Computer the c0-shape functions, derivatives and second derivatives w.r.t local coordinates at local ...
void test(const Vector< double > &s, Shape &psi) const
Calculate the test functions at local coordinate s.
void d2basis_local_at_knot_curve(const unsigned &ipt, Shape &psi, DShape &dpsids, DShape &d2psids) const
void basis_curve(const Vector< double > &s, Shape &psi) const
void local_coordinate_of_node(const unsigned &j, Vector< double > &s) const
Return local coordinates of node j.
void d2test_local_at_knot(const unsigned &ipt, Shape &phi, DShape &dphids, DShape &d2phids) const
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn&#39;t been defined.
A class for Linear triangular shape function with 3 vertex nodes.
virtual void d2basis_c0_local(const Vector< double > &s, Shape &psi, DShape &dpsids, DShape &d2psids) const
double d2basis_eulerian_curve(const Vector< double > &s, Shape &psi, DShape &dpsi, DShape &d2psi) const
Compute the cuved-element shape functions and also first and second derivatives w.r.t. global coordinates at ipt-th integration point.
void local_coordinate_of_node(const unsigned &j, Vector< double > &s) const
Return local coordinates of node j.
double dbasis_eulerian_curve(const Vector< double > &s, Shape &psi, DShape &dpsi) const
Compute the curved-element shape functions and also first derivatives w.r.t. global coordinates at lo...
double d2shape_and_d2test_eulerian_at_knot(const unsigned &ipt, Shape &psi, DShape &dpsi, DShape &d2psi, Shape &test, DShape &dtest, DShape &d2test) const
Compute the c1-shape functions and also first and second derivatives w.r.t. global coordinates at ipt...
void d2Cshape_local(const Vector< double > &s, Shape &psi_curve, DShape &dpsi_curve, DShape &d2psi_curve) const
double J_eulerian1(const Vector< double > &s) const
Calculate the Jacobian of the mapping between local and global coordinates at the position s...
virtual void dbasis_local_straight(const Vector< double > &s, Shape &psi, DShape &dpsids) const
void dtest_local(const Vector< double > &s, Shape &psi, DShape &dpsids) const
Compute the test functions and derivatives w.r.t. local coordinates at local coordinate s...
void d2test_local(const Vector< double > &s, Shape &psi, DShape &dpsids, DShape &d2psids) const
Computer the test functions, derivatives and second derivatives w.r.t local coordinates at local coor...
void test_at_knot(const unsigned &ipt, Shape &phi) const
Return the test function stored at the ipt-th integration point.
void d2basis_c0_local(const Vector< double > &s, Shape &psi, DShape &dpsids, DShape &d2psids) const
Computer the c0-basis functions, derivatives and second derivatives w.r.t local coordinates at local ...
void d2Lshape_local(const Vector< double > &s, Shape &psi, DShape &dpsids, DShape &d2psids) const
unsigned nvertex_node() const
Number of vertex nodes in the element: One more than spatial dimension.
void d2basis_local_at_knot(const unsigned &ipt, Shape &psi, DShape &dpsids, DShape &d2psids) const
virtual void dbasis_c0_local(const Vector< double > &s, Shape &psi, DShape &dpsids) const
virtual void d2test_local(const Vector< double > &s, Shape &phi, DShape &dphids, DShape &d2phids) const
virtual void test(const Vector< double > &s, Shape &phi) const
void basis_at_knot_curve(const unsigned &ipt, Shape &psi) const
Return the c1-shape function associated with a curvilinear boundary stored at the ipt-th integration ...
void dCshape_local(const Vector< double > &s, Shape &psi_curve, DShape &dpsi_curve) const
void classify_boundary_node(DenseMatrix< double > &node_position, unsigned &bd_element, DenseMatrix< double > &bd_node_position, Vector< double > &x) const
void test_at_knot(const unsigned &ipt, Shape &phi) const
Return the test function stored at the ipt-th integration point.
C1CurvedElement(const C1CurvedElement &)
Broken copy constructor.
virtual void dtest_local(const Vector< double > &s, Shape &phi, DShape &dphids) const
double local_to_eulerian_mapping2(const DShape &dpsids, DenseMatrix< double > &inverse_jacobian) const
Calculate the mapping from local to Eulerian coordinates, given the derivatives of the shape function...
void dbasis_local_at_knot(const unsigned &ipt, Shape &psi, DShape &dpsids) const
Return the C1-basis function and its derivatives w.r.t. the global coordinates at the ipt-th integrat...
virtual void test(const Vector< double > &s, Shape &phi) const
unsigned ninternal_node() const
Number of internal nodes.