43 (BoundaryFctPt north_pt, BoundaryFctPt east_pt,BoundaryFctPt south_pt, 
    44  BoundaryFctPt west_pt)
    47  Macro_element_pt.resize(1);
    50  Macro_element_pt[0] = 
new QMacroElement<2>(
this,0);
    53  North_boundary_fn_pt = north_pt;
    54  East_boundary_fn_pt = east_pt;
    55  South_boundary_fn_pt = south_pt;
    56  West_boundary_fn_pt = west_pt;
    59  dNorth_boundary_fn_pt = 0;
    60  dEast_boundary_fn_pt = 0;
    61  dSouth_boundary_fn_pt = 0;
    62  dWest_boundary_fn_pt = 0;
    65  d2North_boundary_fn_pt = 0;
    66  d2East_boundary_fn_pt = 0;
    67  d2South_boundary_fn_pt = 0;
    68  d2West_boundary_fn_pt = 0;
    73  std::ostringstream error_message;
    74  bool error_flag = 
false;
    77   Vector<double> x_N(2);
    78   (*North_boundary_fn_pt)(1.0,x_N);
    79   Vector<double> x_E(2);
    80   (*East_boundary_fn_pt)(1.0,x_E);
    81   if (x_N[0] != x_E[0] || x_N[1] != x_E[1])
    83     error_message << 
"North and East Boundaries do not meet at the "    84                   << 
"North East Corner.\n"    85                   << 
"North Boundary : x[0] = " << x_N[0] << 
"\n"    86                   << 
"                 x[1] = " << x_N[1] << 
"\n"    87                   << 
"East Boundary : x[0] = " << x_E[0] << 
"\n"    88                   << 
"                x[1] = " << x_E[1] << 
"\n\n";
    94   Vector<double> x_S(2);
    95   (*South_boundary_fn_pt)(1.0,x_S);
    96   Vector<double> x_E(2);
    97   (*East_boundary_fn_pt)(-1.0,x_E);
    98   if (x_S[0] != x_E[0] || x_S[1] != x_E[1])
   100     error_message << 
"South and East Boundaries do not meet at the "   101                   << 
"South East Corner.\n"   102                   << 
"South Boundary : x[0] = " << x_S[0] << 
"\n"   103                   << 
"                 x[1] = " << x_S[1] << 
"\n"   104                   << 
"East Boundary : x[0] = " << x_E[0] << 
"\n"   105                   << 
"                x[1] = " << x_E[1] << 
"\n\n";
   111   Vector<double> x_S(2);
   112   (*South_boundary_fn_pt)(-1.0,x_S);
   113   Vector<double> x_W(2);
   114   (*West_boundary_fn_pt)(-1.0,x_W);
   115   if (x_S[0] != x_W[0] || x_S[1] != x_W[1])
   117     error_message << 
"South and West Boundaries do not meet at the "   118                   << 
"South West Corner.\n"   119                   << 
"South Boundary : x[0] = " << x_S[0] << 
"\n"   120                   << 
"                 x[1] = " << x_S[1] << 
"\n"   121                   << 
"West Boundary : x[0] = " << x_W[0] << 
"\n"   122                   << 
"                x[1] = " << x_W[1] << 
"\n\n";
   128   Vector<double> x_N(2);
   129   (*North_boundary_fn_pt)(-1.0,x_N);
   130   Vector<double> x_W(2);
   131   (*West_boundary_fn_pt)(1.0,x_W);
   132   if (x_N[0] != x_W[0] || x_N[1] != x_W[1])
   134     error_message << 
"North and West Boundaries do not meet at the "   135                   << 
"North West Corner.\n"   136                   << 
"North Boundary : x[0] = " << x_N[0] << 
"\n"   137                   << 
"                 x[1] = " << x_N[1] << 
"\n"   138                   << 
"West Boundary : x[0] = " << x_W[0] << 
"\n"   139                   << 
"                x[1] = " << x_W[1] << 
"\n\n";
   148      OOMPH_CURRENT_FUNCTION,
   149      OOMPH_EXCEPTION_LOCATION
   161 (
const double& l_x, 
const double& l_y)
   164  Macro_element_pt.resize(1);
   167  Macro_element_pt[0] = 
new QMacroElement<2>(
this,0);
   170  North_boundary_fn_pt = 0;
   171  East_boundary_fn_pt = 0;
   172  South_boundary_fn_pt = 0;
   173  West_boundary_fn_pt = 0;
   176  x_south_west.resize(2);
   177  x_north_east.resize(2);
   180  x_south_west[0] = 0.0;
   181  x_south_west[1] = 0.0;
   184  x_north_east[0] = l_x;
   185  x_north_east[1] = l_y;
   188  dNorth_boundary_fn_pt = 0;
   189  dEast_boundary_fn_pt = 0;
   190  dSouth_boundary_fn_pt = 0;
   191  dWest_boundary_fn_pt = 0;
   194  d2North_boundary_fn_pt = 0;
   195  d2East_boundary_fn_pt = 0;
   196  d2South_boundary_fn_pt = 0;
   197  d2West_boundary_fn_pt = 0;
   205 (
const double& x_min, 
const double& x_max, 
const double& y_min, 
   209  Macro_element_pt.resize(1);
   212  Macro_element_pt[0] = 
new QMacroElement<2>(
this,0);
   215  North_boundary_fn_pt = 0;
   216  East_boundary_fn_pt = 0;
   217  South_boundary_fn_pt = 0;
   218  West_boundary_fn_pt = 0;
   221  x_south_west.resize(2);
   222  x_north_east.resize(2);
   225  x_south_west[0] = x_min;
   226  x_south_west[1] = y_min;
   227  x_north_east[0] = x_max;
   228  x_north_east[1] = y_max;
   231  dNorth_boundary_fn_pt = 0;
   232  dEast_boundary_fn_pt = 0;
   233  dSouth_boundary_fn_pt = 0;
   234  dWest_boundary_fn_pt = 0;
   237  d2North_boundary_fn_pt = 0;
   238  d2East_boundary_fn_pt = 0;
   239  d2South_boundary_fn_pt = 0;
   240  d2West_boundary_fn_pt = 0;
   255 (BoundaryFctPt d_north_pt,BoundaryFctPt d_east_pt,BoundaryFctPt d_south_pt, 
   256  BoundaryFctPt d_west_pt)
   259  dNorth_boundary_fn_pt = d_north_pt;
   260  dEast_boundary_fn_pt = d_east_pt;
   261  dSouth_boundary_fn_pt = d_south_pt;
   262  dWest_boundary_fn_pt = d_west_pt;
   279 (BoundaryFctPt d2_north_pt,BoundaryFctPt d2_east_pt,BoundaryFctPt d2_south_pt, 
   280  BoundaryFctPt d2_west_pt)
   283  d2North_boundary_fn_pt = d2_north_pt;
   284  d2East_boundary_fn_pt = d2_east_pt;
   285  d2South_boundary_fn_pt = d2_south_pt;
   286  d2West_boundary_fn_pt = d2_west_pt;
   295 (
const unsigned& t, 
const unsigned& i_macro, 
const unsigned& i_direct, 
   296  const Vector<double>& s, Vector<double>& f)
   299  using namespace QuadTreeNames;
   301 #ifdef WARN_ABOUT_SUBTLY_CHANGED_OOMPH_INTERFACES   304     "Order of function arguments has changed between versions 0.8 and 0.85",
   305     "TopologicallyRectangularDomain::macro_element_boundary(...)",
   306     OOMPH_EXCEPTION_LOCATION);
   313  else if (i_direct==E)
   316  else if (i_direct==S)
   319  else if (i_direct==W)
   329 (
const unsigned& t, 
const unsigned& i_macro, 
const unsigned& i_direct,
   330  const Vector<double>& s,Vector<double>& f)
   333  using namespace QuadTreeNames;
   335 #ifdef WARN_ABOUT_SUBTLY_CHANGED_OOMPH_INTERFACES   338     "Order of function arguments has changed between versions 0.8 and 0.85",
   339     "TopologicallyRectangularDomain::dmacro_element_boundary(...)",
   340     OOMPH_EXCEPTION_LOCATION);
   347  else if (i_direct==E)
   350  else if (i_direct==S)
   353  else if (i_direct==W)
   363 (
const unsigned& t, 
const unsigned& i_macro, 
const unsigned& i_direct,
   364  const Vector<double>& s,Vector<double>& f)
   367  using namespace QuadTreeNames;
   370 #ifdef WARN_ABOUT_SUBTLY_CHANGED_OOMPH_INTERFACES   373     "Order of function arguments has changed between versions 0.8 and 0.85",
   374     "TopologicallyRectangularDomain::d2macro_element_boundary(...)",
   375     OOMPH_EXCEPTION_LOCATION);
   382  else if (i_direct==E)
   385  else if (i_direct==S)
   388  else if (i_direct==W)
   399  if (North_boundary_fn_pt != 0)
   401    (*North_boundary_fn_pt)(s[0],f);
   405    f[0] = x_south_west[0] + (s[0]+1)/2*(x_north_east[0]-x_south_west[0]);
   406    f[1] = x_north_east[1];
   417  if (East_boundary_fn_pt != 0)
   419    (*East_boundary_fn_pt)(s[0],f);
   423    f[0] = x_north_east[0];
   424    f[1] = x_south_west[1] + (s[0]+1)/2*(x_north_east[1]-x_south_west[1]);
   435  if (South_boundary_fn_pt != 0)
   437    (*South_boundary_fn_pt)(s[0],f);  
   441    f[0] = x_south_west[0] + (s[0]+1)/2*(x_north_east[0]-x_south_west[0]);
   442    f[1] = x_south_west[1];
   454  if (West_boundary_fn_pt != 0)
   456    (*West_boundary_fn_pt)(s[0],f);
   460    f[0] = x_south_west[0];
   461    f[1] = x_south_west[1] + (s[0]+1)/2*(x_north_east[1]-x_south_west[1]);
   474  if (North_boundary_fn_pt != 0)
   477    if (dNorth_boundary_fn_pt !=0)
   479      (*dNorth_boundary_fn_pt)(s[0],dr);
   484      const double h = 10e-8;
   485      Vector<double> x_N_left(2);
   486      (*North_boundary_fn_pt)(s[0]-0.5*h,x_N_left);
   487      Vector<double> x_N_right(2);
   488      (*North_boundary_fn_pt)(s[0]+0.5*h,x_N_right);
   489      dr[0] = (x_N_right[0]-x_N_left[0])/h;
   490      dr[1] = (x_N_right[1]-x_N_left[1])/h;
   496    dr[0] = (x_north_east[0]-x_south_west[0])/2; 
   510  if (East_boundary_fn_pt != 0)
   513    if (dEast_boundary_fn_pt !=0)
   515      (*dEast_boundary_fn_pt)(s[0],dr);
   520      const double h = 10e-8;
   521      Vector<double> x_E_down(2);
   522      (*East_boundary_fn_pt)(s[0]-0.5*h,x_E_down);
   523      Vector<double> x_E_up(2);
   524      (*East_boundary_fn_pt)(s[0]+0.5*h,x_E_up);
   525      dr[0] = (x_E_up[0]-x_E_down[0])/h;
   526      dr[1] = (x_E_up[1]-x_E_down[1])/h;
   533    dr[1] = (x_north_east[1]-x_south_west[1])/2;  
   546  if (South_boundary_fn_pt != 0)
   549    if (dSouth_boundary_fn_pt !=0)
   551      (*dSouth_boundary_fn_pt)(s[0],dr);
   556      const double h = 10e-8;
   557      Vector<double> x_N_left(2);
   558      (*South_boundary_fn_pt)(s[0]-0.5*h,x_N_left);
   559      Vector<double> x_N_right(2);
   560      (*South_boundary_fn_pt)(s[0]+0.5*h,x_N_right);
   561      dr[0] = (x_N_right[0]-x_N_left[0])/h;
   562      dr[1] = (x_N_right[1]-x_N_left[1])/h;
   568    dr[0] = (x_north_east[0]-x_south_west[0])/2; 
   582  if (West_boundary_fn_pt != 0)
   585    if (dWest_boundary_fn_pt !=0)
   587      (*dWest_boundary_fn_pt)(s[0],dr);
   592      const double h = 10e-8;
   593      Vector<double> x_W_down(2);
   594      (*West_boundary_fn_pt)(s[0]-0.5*h,x_W_down);
   595      Vector<double> x_W_up(2);
   596      (*West_boundary_fn_pt)(s[0]+0.5*h,x_W_up);
   597      dr[0] = (x_W_up[0]-x_W_down[0])/h;
   598      dr[1] = (x_W_up[1]-x_W_down[1])/h;
   605    dr[1] = (x_north_east[1]-x_south_west[1])/2;  
   618  if (North_boundary_fn_pt != 0)
   621    if (d2North_boundary_fn_pt !=0)
   623      (*d2North_boundary_fn_pt)(s[0],d2r);
   629      if (dNorth_boundary_fn_pt !=0)
   631        const double h = 10e-8;
   632        Vector<double> dx_N_left(2);
   633        (*dNorth_boundary_fn_pt)(s[0]-0.5*h,dx_N_left);
   634        Vector<double> dx_N_right(2);
   635        (*dNorth_boundary_fn_pt)(s[0]+0.5*h,dx_N_right);
   636        d2r[0] = (dx_N_right[0]-dx_N_left[0])/h;
   637        d2r[1] = (dx_N_right[1]-dx_N_left[1])/h;
   642        const double h = 10e-8;
   643        Vector<double> N_left(2);
   644        (*North_boundary_fn_pt)(s[0]-h,N_left);
   645        Vector<double> N_right(2);
   646        (*North_boundary_fn_pt)(s[0]+h,N_right);
   647        Vector<double> N_centre(2);
   648        (*North_boundary_fn_pt)(s[0],N_centre);         
   649        d2r[0] = (N_right[0]+N_left[0]-2*N_centre[0])/(h*h);
   650        d2r[1] = (N_right[1]+N_left[1]-2*N_centre[1])/(h*h);
   671  if (East_boundary_fn_pt != 0)
   674    if (d2East_boundary_fn_pt !=0)
   676      (*d2East_boundary_fn_pt)(s[0],d2r);
   682      if (dEast_boundary_fn_pt !=0)
   684        const double h = 10e-8;
   685        Vector<double> dx_E_lower(2);
   686        (*dEast_boundary_fn_pt)(s[0]-0.5*h,dx_E_lower);
   687        Vector<double> dx_E_upper(2);
   688        (*dEast_boundary_fn_pt)(s[0]+0.5*h,dx_E_upper);
   689        d2r[0] = (dx_E_upper[0]-dx_E_lower[0])/h;
   690        d2r[1] = (dx_E_upper[1]-dx_E_lower[1])/h;
   695        const double h = 10e-8;
   696        Vector<double> E_left(2);
   697        (*East_boundary_fn_pt)(s[0]-h,E_left);
   698        Vector<double> E_right(2);
   699        (*East_boundary_fn_pt)(s[0]+h,E_right);
   700        Vector<double> E_centre(2);
   701        (*East_boundary_fn_pt)(s[0],E_centre);         
   702        d2r[0] = (E_right[0]+E_left[0]-2*E_centre[0])/(h*h);
   703        d2r[1] = (E_right[1]+E_left[1]-2*E_centre[1])/(h*h);
   724  if (South_boundary_fn_pt != 0)
   727    if (d2South_boundary_fn_pt !=0)
   729      (*d2South_boundary_fn_pt)(s[0],d2r);
   735      if (dSouth_boundary_fn_pt !=0)
   737        const double h = 10e-8;
   738        Vector<double> dx_S_left(2);
   739        (*dSouth_boundary_fn_pt)(s[0]-0.5*h,dx_S_left);
   740        Vector<double> dx_S_right(2);
   741        (*dSouth_boundary_fn_pt)(s[0]+0.5*h,dx_S_right);
   742        d2r[0] = (dx_S_right[0]-dx_S_left[0])/h;
   743        d2r[1] = (dx_S_right[1]-dx_S_left[1])/h;
   748        const double h = 10e-8;
   749        Vector<double> S_left(2);
   750        (*South_boundary_fn_pt)(s[0]-h,S_left);
   751        Vector<double> S_right(2);
   752        (*South_boundary_fn_pt)(s[0]+h,S_right);
   753        Vector<double> S_centre(2);
   754        (*South_boundary_fn_pt)(s[0],S_centre);         
   755        d2r[0] = (S_right[0]+S_left[0]-2*S_centre[0])/(h*h);
   756        d2r[1] = (S_right[1]+S_left[1]-2*S_centre[1])/(h*h);
   777  if (West_boundary_fn_pt != 0)
   780    if (d2West_boundary_fn_pt !=0)
   782      (*d2West_boundary_fn_pt)(s[0],d2r);
   788      if (dWest_boundary_fn_pt !=0)
   790        const double h = 10e-8;
   791        Vector<double> dx_W_lower(2);
   792        (*dWest_boundary_fn_pt)(s[0]-0.5*h,dx_W_lower);
   793        Vector<double> dx_W_upper(2);
   794        (*dWest_boundary_fn_pt)(s[0]+0.5*h,dx_W_upper);
   795        d2r[0] = (dx_W_upper[0]-dx_W_lower[0])/h;
   796        d2r[1] = (dx_W_upper[1]-dx_W_lower[1])/h;
   801        const double h = 10e-8;
   802        Vector<double> W_left(2);
   803        (*West_boundary_fn_pt)(s[0]-h,W_left);
   804        Vector<double> W_right(2);
   805        (*West_boundary_fn_pt)(s[0]+h,W_right);
   806        Vector<double> W_centre(2);
   807        (*West_boundary_fn_pt)(s[0],W_centre);         
   808        d2r[0] = (W_right[0]+W_left[0]-2*W_centre[0])/(h*h);
   809        d2r[1] = (W_right[1]+W_left[1]-2*W_centre[1])/(h*h);
 void d2r_S(const Vector< double > &s, Vector< double > &d2r)
takes the macro element coordinate position along the south boundary and returns the second derivates...
 
void set_boundary_derivative_functions(BoundaryFctPt d_north_pt, BoundaryFctPt d_east_pt, BoundaryFctPt d_south_pt, BoundaryFctPt d_west_pt)
allows the boundary derivate function pointers to be set. To compute the derivatives of the problem d...
 
void dr_E(const Vector< double > &s, Vector< double > &dr)
takes the macro element coordinate position along the E boundary and returns the derivates of the glo...
 
void dr_W(const Vector< double > &s, Vector< double > &dr)
takes the macro element coordinate position along the W boundary and returns the derivates of the glo...
 
void dmacro_element_boundary(const unsigned &t, const unsigned &i_macro, const unsigned &i_direct, const Vector< double > &s, Vector< double > &f)
 
void dr_S(const Vector< double > &s, Vector< double > &dr)
takes the macro element coordinate position along the south boundary and returns the derivates of the...
 
void d2r_W(const Vector< double > &s, Vector< double > &d2r)
takes the macro element coordinate position along the west boundary and returns the second derivates ...
 
void r_W(const Vector< double > &s, Vector< double > &f)
takes the macro element coordinate position along the west boundary and returns the global coordinate...
 
TopologicallyRectangularDomain(BoundaryFctPt north_pt, BoundaryFctPt east_pt, BoundaryFctPt south_pt, BoundaryFctPt west_pt)
Constructor - domain boundaries are described with four boundary function pointers describing the top...
 
void r_S(const Vector< double > &s, Vector< double > &f)
takes the macro element coordinate position along the south boundary and returns the global coordinat...
 
void set_boundary_second_derivative_functions(BoundaryFctPt d2_north_pt, BoundaryFctPt d2_east_pt, BoundaryFctPt d2_south_pt, BoundaryFctPt d2_west_pt)
allows the boundary second derivate function pointers to be set. To compute the second derivatives of...
 
void d2r_E(const Vector< double > &s, Vector< double > &d2r)
takes the macro element coordinate position along the east boundary and returns the second derivates ...
 
void r_N(const Vector< double > &s, Vector< double > &f)
takes the macro element coordinate position along the north boundary and returns the global coordinat...
 
void macro_element_boundary(const unsigned &t, const unsigned &i_macro, const unsigned &i_direct, const Vector< double > &s, Vector< double > &f)
 
void d2r_N(const Vector< double > &s, Vector< double > &d2r)
takes the macro element coordinate position along the north boundary and returns the second derivates...
 
void d2macro_element_boundary(const unsigned &t, const unsigned &i_macro, const unsigned &i_direct, const Vector< double > &s, Vector< double > &f)
 
void dr_N(const Vector< double > &s, Vector< double > &dr)
takes the macro element coordinate position along the north boundary and returns the derivates of the...
 
void r_E(const Vector< double > &s, Vector< double > &f)
takes the macro element coordinate position along the east boundary and returns the global coordinate...