54 outfile <<
"ZONE I=2, J=2, K=2 C=" << colour << std::endl;
60 outfile << corner[0] <<
" " << corner[1] <<
" " << corner[2]
61 <<
" " <<
Number << std::endl;
67 outfile << corner[0] <<
" " << corner[1] <<
" " << corner[2]
68 <<
" " <<
Number << std::endl;
74 outfile << corner[0] <<
" " << corner[1] <<
" " << corner[2]
75 <<
" " <<
Number << std::endl;
81 outfile << corner[0] <<
" " << corner[1] <<
" " << corner[2]
82 <<
" " <<
Number << std::endl;
91 outfile << corner[0] <<
" " << corner[1] <<
" " << corner[2]
92 <<
" " <<
Number << std::endl;
98 outfile << corner[0] <<
" " << corner[1] <<
" " << corner[2]
99 <<
" " <<
Number << std::endl;
105 outfile << corner[0] <<
" " << corner[1] <<
" " << corner[2]
106 <<
" " <<
Number << std::endl;
112 outfile << corner[0] <<
" " << corner[1] <<
" " << corner[2]
113 <<
" " <<
Number << std::endl;
138 using namespace OcTreeNames;
141 unsigned n_p = nnode_1d();
144 Father_bound[n_p].resize(n_p*n_p*n_p,8);
147 for(
unsigned n=0;n<n_p*n_p*n_p;n++)
148 {
for(
unsigned ison=0;ison<8;ison++) {Father_bound[n_p](n,ison)=
Tree::OMEGA;}}
150 for(
int i_son=
LDB;i_son<=
RUF;i_son++)
157 for(
unsigned i0=0;i0<n_p;i0++)
159 for(
unsigned i1=0;i1<n_p;i1++)
161 for(
unsigned i2=0;i2<n_p;i2++)
164 for(
unsigned i=0;
i<3;
i++)
166 vect_bound[
i]=-vect_son[
i];
173 if(i0==0) {vect_bound[0]=-1;}
174 if(i0==n_p-1) {vect_bound[0]=1;}
175 if(i1==0) {vect_bound[1]=-1;}
176 if(i1==n_p-1) {vect_bound[1]=1;}
177 if(i2==0) {vect_bound[2]=-1;}
178 if(i2==n_p-1) {vect_bound[2]=1;}
193 vect_bound[
i]=(vect_bound[
i]+vect_son[
i])/2;
197 Father_bound[n_p](i0+n_p*i1+n_p*n_p*i2,i_son)=
229 using namespace OcTreeNames;
232 unsigned nvalue=ncont_interpolated_values();
234 Vector<int> bound_cons1(nvalue), bound_cons2(nvalue);
252 notzero.push_back(
i);
260 get_face_bcs(bound,bound_cons);
266 for(
unsigned i=0;
i<3;
i++)
268 vect1[
i]=0; vect2[
i]=0;
271 vect1[notzero[0]]=vect_elem[notzero[0]];
272 vect2[notzero[1]]=vect_elem[notzero[1]];
277 for(
unsigned k=0;k<nvalue;k++)
279 bound_cons[k]=(bound_cons1[k]||bound_cons2[k]);
286 for(
unsigned i=0;
i<3;
i++)
288 vect1[
i]=0; vect2[
i]=0; vect3[
i]=0;
291 vect1[0]=vect_elem[0];
292 vect2[1]=vect_elem[1];
293 vect3[2]=vect_elem[2];
301 for(
unsigned k=0;k<nvalue;k++)
303 bound_cons[k]=(bound_cons1[k]||bound_cons2[k]||
309 throw OomphLibError(
"Make sure you are not giving OMEGA as bound",
310 OOMPH_CURRENT_FUNCTION,
311 OOMPH_EXCEPTION_LOCATION);
327 using namespace OcTreeNames;
330 unsigned n_p = nnode_1d();
332 unsigned node1, node2, node3, node4;
338 node1 = n_p*n_p*n_p-1;
341 node4 = n_p*(n_p*n_p - 1);
347 node3 = (n_p*n_p+1)*(n_p-1);
348 node4 = n_p*n_p*(n_p-1);
353 node2 = (n_p*n_p+1)*(n_p-1);
354 node3 = n_p*n_p*n_p-1;
360 node2 = n_p*(n_p - 1);
361 node3 = n_p*(n_p*n_p-1);
362 node4 = n_p*n_p*(n_p-1);
369 node4 = n_p*(n_p -1);
373 node1 = n_p*n_p*n_p-1;
374 node2 = n_p*(n_p*n_p-1);
375 node3 = n_p*n_p*(n_p-1);
376 node4 = (n_p-1)*(n_p*n_p+1);
380 std::ostringstream error_stream;
381 error_stream <<
"Wrong edge " << face <<
" passed\n";
384 OOMPH_CURRENT_FUNCTION,
385 OOMPH_EXCEPTION_LOCATION);
389 unsigned maxnvalue=ncont_interpolated_values();
394 for(
unsigned k=0;k<maxnvalue;k++)
397 node_pt(node1)->is_pinned(k)*node_pt(node2)->is_pinned(k)*
398 node_pt(node3)->is_pinned(k)*node_pt(node4)->is_pinned(k);
413 std::set<unsigned>& boundary)
const 415 using namespace OcTreeNames;
418 unsigned n_p = nnode_1d();
433 int one_d_node_number[3]={0,0,0};
448 if(vect_face[
i]==1) {one_d_node_number[
i] = n_p-1;}
456 node[0] = one_d_node_number[0] + n_p*one_d_node_number[1] +
457 n_p*n_p*one_d_node_number[2];
467 node[0] = (n_p-1) + n_p*one_d_node_number[1] +
468 n_p*n_p*one_d_node_number[2];
469 node[1] = n_p*one_d_node_number[1] + n_p*n_p*one_d_node_number[2];
474 node[0] = n_p*(n_p-1) + one_d_node_number[0] +
475 n_p*n_p*one_d_node_number[2];
476 node[1] = one_d_node_number[0] + n_p*n_p*one_d_node_number[2];
481 node[0] = one_d_node_number[0] + n_p*one_d_node_number[1]
483 node[1] = one_d_node_number[0] + n_p*one_d_node_number[1];
493 node[0] = one_d_node_number[0] + n_p*n_p*(n_p-1) + n_p*(n_p-1);
494 node[1] = one_d_node_number[0] + n_p*(n_p-1);
495 node[2] = one_d_node_number[0] + n_p*n_p*(n_p-1);
496 node[3] = one_d_node_number[0];
501 node[0]=n_p*one_d_node_number[1] + n_p*n_p*(n_p-1)+(n_p-1);
502 node[1]=n_p*one_d_node_number[1] + (n_p-1);
503 node[2]=n_p*one_d_node_number[1] + n_p*n_p*(n_p-1);
504 node[3]=n_p*one_d_node_number[1];
510 node[0]=n_p*n_p*one_d_node_number[2] + n_p*(n_p-1)+(n_p-1);
511 node[1]=n_p*n_p*one_d_node_number[2] + (n_p-1);
512 node[2]=n_p*n_p*one_d_node_number[2] + n_p*(n_p-1);
513 node[3]=n_p*n_p*one_d_node_number[2];
518 throw OomphLibError(
"Make sure you are not giving OMEGA as boundary",
519 OOMPH_CURRENT_FUNCTION,
520 OOMPH_EXCEPTION_LOCATION);
531 for(
unsigned i=0;
i<4;
i++)
533 node_pt(node[
i])->get_boundaries_pt(node_boundaries_pt[i]);
540 for(
unsigned i=0;
i<2;
i++)
543 if((node_boundaries_pt[2*
i]!=0) && (node_boundaries_pt[2*
i+1]!=0))
546 std::set_intersection(node_boundaries_pt[2*
i]->begin(),
547 node_boundaries_pt[2*
i]->end(),
548 node_boundaries_pt[2*
i+1]->begin(),
549 node_boundaries_pt[2*
i+1]->end(),
550 inserter(boundary_aux[
i],
551 boundary_aux[i].begin()));
556 set_intersection(boundary_aux[0].begin(),boundary_aux[0].end(),
557 boundary_aux[1].begin(),boundary_aux[1].end(),
558 inserter(boundary,boundary.begin()));
571 using namespace OcTreeNames;
574 unsigned nnodes_1d = nnode_1d();
577 unsigned nnodes_2d = nnodes_1d*nnodes_1d;
580 unsigned nnodes_3d = nnode();
583 Shape psi(nnodes_3d);
590 unsigned start=0, increment1=1, increment2=1;
602 std::ostringstream error_stream;
603 error_stream<<
"Coordinate " << s[0] <<
" " << s[1] <<
" " << s[2]
604 <<
" is not on Left face\n";
607 OOMPH_CURRENT_FUNCTION,
608 OOMPH_EXCEPTION_LOCATION);
612 increment1 = nnodes_1d;
621 std::ostringstream error_stream;
622 error_stream<<
"Coordinate " << s[0] <<
" " << s[1] <<
" " << s[2]
623 <<
" is not on Right face\n";
626 OOMPH_CURRENT_FUNCTION,
627 OOMPH_EXCEPTION_LOCATION);
632 increment1 = nnodes_1d;
641 std::ostringstream error_stream;
642 error_stream<<
"Coordinate " << s[0] <<
" " << s[1] <<
" " << s[2]
643 <<
" is not on Bottom face\n";
646 OOMPH_CURRENT_FUNCTION,
647 OOMPH_EXCEPTION_LOCATION);
651 increment2 = nnodes_2d-nnodes_1d;
659 std::ostringstream error_stream;
660 error_stream<<
"Coordinate " << s[0] <<
" " << s[1] <<
" " << s[2]
661 <<
" is not on Upper face\n";
664 OOMPH_CURRENT_FUNCTION,
665 OOMPH_EXCEPTION_LOCATION);
669 start = nnodes_2d-nnodes_1d;
678 std::ostringstream error_stream;
679 error_stream<<
"Coordinate " << s[0] <<
" " << s[1] <<
" " << s[2]
680 <<
" is not on Back face\n";
683 OOMPH_CURRENT_FUNCTION,
684 OOMPH_EXCEPTION_LOCATION);
696 std::ostringstream error_stream;
697 error_stream<<
"Coordinate " << s[0] <<
" " << s[1] <<
" " << s[2]
698 <<
" is not on Front face\n";
701 OOMPH_CURRENT_FUNCTION,
702 OOMPH_EXCEPTION_LOCATION);
706 start = nnodes_3d-nnodes_2d;
713 if ( (s[0] != -1.0) || (s[2] != 1.0) )
715 std::ostringstream error_stream;
716 error_stream<<
"Coordinate " << s[0] <<
" " << s[1] <<
" " << s[2]
717 <<
" is not on Front-Left edge\n";
720 OOMPH_CURRENT_FUNCTION,
721 OOMPH_EXCEPTION_LOCATION);
724 start = nnodes_3d-nnodes_2d;
725 increment1=nnodes_1d;
730 if ( (s[0] != -1.0) || (s[1] != -1.0) )
732 std::ostringstream error_stream;
733 error_stream<<
"Coordinate " << s[0] <<
" " << s[1] <<
" " << s[2]
734 <<
" is not on Bottom-Left edge\n";
737 OOMPH_CURRENT_FUNCTION,
738 OOMPH_EXCEPTION_LOCATION);
741 increment1=nnodes_2d;
746 if ( (s[0] != -1.0) || (s[1] != 1.0) )
748 std::ostringstream error_stream;
749 error_stream<<
"Coordinate " << s[0] <<
" " << s[1] <<
" " << s[2]
750 <<
" is not on Upper-Left edge\n";
753 OOMPH_CURRENT_FUNCTION,
754 OOMPH_EXCEPTION_LOCATION);
757 start = nnodes_2d-nnodes_1d;
758 increment1=nnodes_2d;
763 if ( (s[0] != -1.0) || (s[2] != -1.0) )
765 std::ostringstream error_stream;
766 error_stream<<
"Coordinate " << s[0] <<
" " << s[1] <<
" " << s[2]
767 <<
" is not on Back-Left edge\n";
770 OOMPH_CURRENT_FUNCTION,
771 OOMPH_EXCEPTION_LOCATION);
774 increment1=nnodes_1d;
779 if ( (s[0] != 1.0) || (s[2] != 1.0) )
781 std::ostringstream error_stream;
782 error_stream<<
"Coordinate " << s[0] <<
" " << s[1] <<
" " << s[2]
783 <<
" is not on Front-Right edge\n";
786 OOMPH_CURRENT_FUNCTION,
787 OOMPH_EXCEPTION_LOCATION);
791 increment1=-nnodes_1d;
796 if ( (s[0] != 1.0) || (s[1] != -1.0) )
798 std::ostringstream error_stream;
799 error_stream<<
"Coordinate " << s[0] <<
" " << s[1] <<
" " << s[2]
800 <<
" is not on Bottom-Right edge\n";
803 OOMPH_CURRENT_FUNCTION,
804 OOMPH_EXCEPTION_LOCATION);
808 increment1=nnodes_2d;
813 if ( (s[0] != 1.0) || (s[1] != 1.0) )
815 std::ostringstream error_stream;
816 error_stream<<
"Coordinate " << s[0] <<
" " << s[1] <<
" " << s[2]
817 <<
" is not on Upper-Right edge\n";
820 OOMPH_CURRENT_FUNCTION,
821 OOMPH_EXCEPTION_LOCATION);
825 increment1=nnodes_2d;
830 if ( (s[0] != 1.0) || (s[2] != -1.0) )
832 std::ostringstream error_stream;
833 error_stream<<
"Coordinate " << s[0] <<
" " << s[1] <<
" " << s[2]
834 <<
" is not on Back-Right edge\n";
837 OOMPH_CURRENT_FUNCTION,
838 OOMPH_EXCEPTION_LOCATION);
842 increment1=nnodes_1d;
847 if ( (s[1] != -1.0) || (s[2] != -1.0) )
849 std::ostringstream error_stream;
850 error_stream<<
"Coordinate " << s[0] <<
" " << s[1] <<
" " << s[2]
851 <<
" is not on Back-Bottom edge\n";
854 OOMPH_CURRENT_FUNCTION,
855 OOMPH_EXCEPTION_LOCATION);
862 if ( (s[1] != -1.0) || (s[2] != 1.0) )
864 std::ostringstream error_stream;
865 error_stream<<
"Coordinate " << s[0] <<
" " << s[1] <<
" " << s[2]
866 <<
" is not on Front-Bottom edge\n";
869 OOMPH_CURRENT_FUNCTION,
870 OOMPH_EXCEPTION_LOCATION);
873 start = nnodes_3d-nnodes_2d;
878 if ( (s[1] != 1.0) || (s[2] != -1.0) )
880 std::ostringstream error_stream;
881 error_stream<<
"Coordinate " << s[0] <<
" " << s[1] <<
" " << s[2]
882 <<
" is not on Back-Upper edge\n";
885 OOMPH_CURRENT_FUNCTION,
886 OOMPH_EXCEPTION_LOCATION);
889 start = nnodes_2d-nnodes_1d;
894 if ( (s[1] != 1.0) || (s[2] != 1.0) )
896 std::ostringstream error_stream;
897 error_stream<<
"Coordinate " << s[0] <<
" " << s[1] <<
" " << s[2]
898 <<
" is not on Upper-Front edge\n";
901 OOMPH_CURRENT_FUNCTION,
902 OOMPH_EXCEPTION_LOCATION);
905 start = nnodes_3d-nnodes_1d;
910 std::ostringstream error_stream;
913 error_stream <<
"Trouble at : s= [" 914 << s[0] <<
" " << s[1] <<
" " << s[2]
917 this->interpolated_x(s,x);
918 error_stream <<
"corresponding to : x= [" 919 << x[0] <<
" " << x[1] <<
" " << x[2]
922 OOMPH_CURRENT_FUNCTION,
923 OOMPH_EXCEPTION_LOCATION);
935 for(
unsigned l1=0;l1<nnodes_1d;l1++)
939 node_pt(node)->get_coordinates_on_boundary(boundary,node_zeta);
942 zeta[0] += node_zeta[0]*psi(node);
943 zeta[1] += node_zeta[1]*psi(node);
951 for(
unsigned l2=0;l2<nnodes_1d;l2++)
953 for(
unsigned l1=0;l1<nnodes_1d;l1++)
957 node_pt(node)->get_coordinates_on_boundary(boundary,node_zeta);
960 zeta[0] += node_zeta[0]*psi(node);
961 zeta[1] += node_zeta[1]*psi(node);
983 using namespace OcTreeNames;
989 if(s_fraction[0]==0.0)
992 if (s_fraction[1]==0.0) {edges.push_back(
LD);}
993 if (s_fraction[2]==0.0) {edges.push_back(
LB);}
994 if (s_fraction[1]==1.0) {edges.push_back(
LU);}
995 if (s_fraction[2]==1.0) {edges.push_back(
LF);}
998 if(s_fraction[0]==1.0)
1001 if (s_fraction[1]==0.0) {edges.push_back(
RD);}
1002 if (s_fraction[2]==0.0) {edges.push_back(
RB);}
1003 if (s_fraction[1]==1.0) {edges.push_back(
RU);}
1004 if (s_fraction[2]==1.0) {edges.push_back(
RF);}
1007 if(s_fraction[1]==0.0)
1010 if (s_fraction[2]==0.0) {edges.push_back(
DB);}
1011 if (s_fraction[2]==1.0) {edges.push_back(
DF);}
1014 if(s_fraction[1]==1.0)
1017 if (s_fraction[2]==0.0) {edges.push_back(
UB);}
1018 if (s_fraction[2]==1.0) {edges.push_back(
UF);}
1021 if(s_fraction[2]==0.0)
1026 if(s_fraction[2]==1.0)
1032 unsigned n_face = faces.size();
1035 unsigned n_edge = edges.size();
1042 int neigh_face, diff_level;
1046 for(
unsigned j=0;j<n_face;j++)
1050 neigh_pt = octree_pt()->
1051 gteq_face_neighbour(faces[j],translate_s,s_lo_neigh,s_hi_neigh,neigh_face,
1068 for(
unsigned i=0;
i<3;
i++)
1070 s[
i] = s_lo_neigh[
i] + s_fraction[translate_s[
i]]*
1071 (s_hi_neigh[
i] - s_lo_neigh[
i]);
1075 Node* neighbour_node_pt =
1079 if(neighbour_node_pt!=0)
1081 return neighbour_node_pt;
1090 for(
unsigned j=0;j<n_edge;j++)
1105 unsigned i_root_edge_neighbour=0;
1108 unsigned nroot_edge_neighbour=0;
1112 bool keep_searching=
true;
1113 while (keep_searching)
1118 neigh_pt = octree_pt()->
1119 gteq_true_edge_neighbour(edges[j],
1120 i_root_edge_neighbour,
1121 nroot_edge_neighbour,
1123 s_lo_neigh,s_hi_neigh,neigh_face,
1141 for(
unsigned i=0;
i<3;
i++)
1143 s[
i] = s_lo_neigh[
i] + s_fraction[translate_s[
i]]*
1144 (s_hi_neigh[
i] - s_lo_neigh[
i]);
1148 Node* neighbour_node_pt =
1152 if(neighbour_node_pt!=0)
1154 return neighbour_node_pt;
1161 i_root_edge_neighbour++;
1164 if (i_root_edge_neighbour>=nroot_edge_neighbour)
1166 keep_searching=
false;
1207 bool& was_already_built,
1208 std::ofstream &new_nodes_file)
1210 using namespace OcTreeNames;
1214 unsigned n_p = nnode_1d();
1217 if (Father_bound[n_p].nrow()==0) {setup_father_bounds();}
1220 OcTree* father_pt =
dynamic_cast<OcTree*
>(octree_pt()->father_pt());
1223 int son_type=octree_pt()->
son_type();
1232 "Something fishy here: I have no father and yet \n";
1234 "I have no nodes. Who has created me then?!\n";
1237 OOMPH_CURRENT_FUNCTION,
1238 OOMPH_EXCEPTION_LOCATION);
1243 was_already_built=
false;
1254 unsigned ntstorage=time_stepper_pt->ntstorage();
1262 "Can't handle generalised nodal positions (yet).",
1263 OOMPH_CURRENT_FUNCTION,
1264 OOMPH_EXCEPTION_LOCATION);
1276 s_lo=octree_pt()->Direction_to_vector[son_type];
1281 for(
int i=0;
i<3;
i++)
1283 s_lo[
i]=(s_lo[
i]+1)/2-1;
1287 for(
int i=0;
i<3;
i++)
1297 for(
unsigned i=0;
i<3;
i++)
1310 if(father_el_pt->
node_pt(0)==0)
1313 "Trouble: father_el_pt->node_pt(0)==0\n Can't build son element!\n",
1314 OOMPH_CURRENT_FUNCTION,
1315 OOMPH_EXCEPTION_LOCATION);
1326 for(
unsigned i0=0;i0<n_p;i0++)
1329 s_fraction[0] = local_one_d_fraction_of_node(i0,0);
1331 s[0] = s_lo[0] + (s_hi[0]-s_lo[0])*s_fraction[0];
1333 for(
unsigned i1=0;i1<n_p;i1++)
1336 s_fraction[1] = local_one_d_fraction_of_node(i1,1);
1338 s[1] = s_lo[1] + (s_hi[1]-s_lo[1])*s_fraction[1];
1340 for(
unsigned i2=0;i2<n_p;i2++)
1343 s_fraction[2] = local_one_d_fraction_of_node(i2,2);
1345 s[2] = s_lo[2] + (s_hi[2]-s_lo[2])*s_fraction[2];
1348 jnod= i0 + n_p*i1 +n_p*n_p*i2;
1352 Node* father_node_pt = father_el_pt->
node_pt(jnod);
1357 "Can't handle periodic nodes (yet).",
1358 OOMPH_CURRENT_FUNCTION,
1359 OOMPH_EXCEPTION_LOCATION);
1365 bool node_done=
false;
1369 Node* created_node_pt =
1374 bool node_exists_in_father=
false;
1375 if(created_node_pt!=0)
1378 node_exists_in_father=
true;
1381 node_pt(jnod) = created_node_pt;
1389 for(
unsigned t=0;
t<ntstorage;
t++)
1398 unsigned n_val_at_node = created_node_pt->
nvalue();
1399 unsigned n_val_from_function = prev_values.size();
1401 unsigned n_var = n_val_at_node < n_val_from_function ?
1402 n_val_at_node : n_val_from_function;
1404 for(
unsigned k=0;k<n_var;k++)
1406 created_node_pt->
set_value(
t,k,prev_values[k]);
1423 created_node_pt = node_created_by_neighbour(s_fraction);
1425 if(created_node_pt!=0)
1427 node_pt(jnod) = created_node_pt;
1435 if(!node_exists_in_father)
1449 int father_bound=Father_bound[n_p](jnod,son_type);
1456 std::set<unsigned> boundaries;
1467 if (boundaries.size()>2)
1470 "boundaries.size()>2 seems a bit strange..\n",
1471 OOMPH_CURRENT_FUNCTION,
1472 OOMPH_EXCEPTION_LOCATION);
1478 if(boundaries.size()> 0)
1485 construct_boundary_node(jnod,time_stepper_pt);
1487 new_node_pt.push_back(created_node_pt);
1497 unsigned n_cont=ncont_interpolated_values();
1499 father_el_pt->
get_bcs(father_bound,bound_cons);
1503 for(
unsigned k=0;k<n_cont;k++)
1507 created_node_pt->
pin(k);
1514 dynamic_cast<SolidNode*
>(created_node_pt);
1515 if (solid_node_pt!=0)
1518 unsigned n_dim = created_node_pt->
ndim();
1523 if (father_solid_el_pt==0)
1526 "We have a SolidNode outside a refineable SolidElement\n";
1528 "during mesh refinement -- this doesn't make sense";
1531 OOMPH_CURRENT_FUNCTION,
1532 OOMPH_EXCEPTION_LOCATION);
1535 father_solid_el_pt->
1536 get_solid_bcs(father_bound,solid_bound_cons);
1539 for(
unsigned k=0;k<n_dim;k++)
1541 if (solid_bound_cons[k]) {solid_node_pt->
pin_position(k);}
1548 for(std::set<unsigned>::iterator it = boundaries.begin();
1549 it != boundaries.end(); ++it)
1578 created_node_pt = construct_node(jnod,time_stepper_pt);
1580 new_node_pt.push_back(created_node_pt);
1599 for (
unsigned t=0;
t<ntstorage;
t++)
1607 father_el_pt->
get_x(
t,s,x_prev);
1610 for(
unsigned i=0;
i<3;
i++)
1612 created_node_pt->
x(
t,
i) = x_prev[
i];
1618 for (
unsigned t=0;
t<ntstorage;
t++)
1626 unsigned n_value = created_node_pt->
nvalue();
1627 for(
unsigned k=0;k<n_value;k++)
1629 created_node_pt->
set_value(
t,k,prev_values[k]);
1663 if((!node_done) && (new_nodes_file.is_open()))
1665 new_nodes_file<< node_pt(jnod)->x(0) <<
" " <<
1666 node_pt(jnod)->x(1) <<
" " <<node_pt(jnod)->x(2)<<std::endl;
1682 if(father_m_el_pt!=0)
1696 "Failed to cast to MacroElementNodeUpdateElementBase*\n";
1698 "Strange -- if the father is a MacroElementNodeUpdateElement\n";
1699 error_message +=
"the son should be too....\n";
1702 OOMPH_CURRENT_FUNCTION,
1703 OOMPH_EXCEPTION_LOCATION);
1714 m_el_pt->set_node_update_info(geom_object_pt);
1717 #ifdef OOMPH_HAS_MPI 1719 if (tree_pt()->father_pt()->object_pt()->is_halo())
1722 tree_pt()->father_pt()->object_pt()->non_halo_proc_ID();
1738 if (aux_father_el_pt==0)
1741 "Failed to cast to ElementWithMovingNodes*\n";
1743 "Strange -- if the son is a ElementWithMovingNodes\n";
1744 error_message +=
"the father should be too....\n";
1747 OOMPH_CURRENT_FUNCTION,
1748 OOMPH_EXCEPTION_LOCATION);
1755 ->are_dresidual_dnodal_coordinates_always_evaluated_by_fd())
1758 enable_always_evaluate_dresidual_dnodal_coordinates_by_fd();
1768 ->is_fill_in_jacobian_from_geometric_data_bypassed())
1782 was_already_built=
true;
1795 if(output_stream.size() != 6)
1798 OOMPH_CURRENT_FUNCTION,
1799 OOMPH_EXCEPTION_LOCATION);
1803 using namespace OcTreeNames;
1806 oc_hang_helper(-1,
U,*(output_stream[0]));
1807 oc_hang_helper(-1,
D,*(output_stream[1]));
1808 oc_hang_helper(-1,
L,*(output_stream[2]));
1809 oc_hang_helper(-1,
R,*(output_stream[3]));
1810 oc_hang_helper(-1,
B,*(output_stream[4]));
1811 oc_hang_helper(-1,
F,*(output_stream[5]));
1820 using namespace OcTreeNames;
1822 std::ofstream dummy_hangfile;
1824 oc_hang_helper(value_id,
U,dummy_hangfile);
1825 oc_hang_helper(value_id,
D,dummy_hangfile);
1826 oc_hang_helper(value_id,
R,dummy_hangfile);
1827 oc_hang_helper(value_id,
L,dummy_hangfile);
1828 oc_hang_helper(value_id,
B,dummy_hangfile);
1829 oc_hang_helper(value_id,
F,dummy_hangfile);
1838 const int &my_face, std::ofstream& output_hangfile)
1840 using namespace OcTreeNames;
1845 int neigh_face,diff_level;
1849 neigh_pt=octree_pt()->
1850 gteq_face_neighbour(my_face, translate_s, s_lo_neigh,
1851 s_hi_neigh,neigh_face,diff_level);
1860 unsigned n_p = ninterpolating_node_1d(value_id);
1862 Node* local_node_pt=0;
1865 for(
unsigned i0=0;i0<n_p;i0++)
1867 for(
unsigned i1=0;i1<n_p;i1++)
1877 local_one_d_fraction_of_interpolating_node(i0,0,value_id);
1878 s_fraction[1] = 1.0;
1880 local_one_d_fraction_of_interpolating_node(i1,2,value_id);
1882 interpolating_node_pt(i0 +(n_p-1)*n_p + n_p*n_p*i1,value_id);
1887 local_one_d_fraction_of_interpolating_node(i0,0,value_id);
1888 s_fraction[1] = 0.0;
1890 local_one_d_fraction_of_interpolating_node(i1,2,value_id);
1892 interpolating_node_pt(i0+n_p*n_p*i1,value_id);
1896 s_fraction[0] = 1.0;
1898 local_one_d_fraction_of_interpolating_node(i0,1,value_id);
1900 local_one_d_fraction_of_interpolating_node(i1,2,value_id);
1902 interpolating_node_pt(n_p-1 + i0*n_p + i1*n_p*n_p,value_id);
1906 s_fraction[0] = 0.0;
1908 local_one_d_fraction_of_interpolating_node(i0,1,value_id);
1910 local_one_d_fraction_of_interpolating_node(i1,2,value_id);
1912 interpolating_node_pt(n_p*i0 + i1*n_p*n_p,value_id);
1917 local_one_d_fraction_of_interpolating_node(i0,0,value_id);
1919 local_one_d_fraction_of_interpolating_node(i1,1,value_id);
1920 s_fraction[2] = 0.0;
1922 interpolating_node_pt(i0 + i1*n_p,value_id);
1927 local_one_d_fraction_of_interpolating_node(i0,0,value_id);
1929 local_one_d_fraction_of_interpolating_node(i1,1,value_id);
1930 s_fraction[2] = 1.0;
1932 interpolating_node_pt(i0 + i1*n_p + (n_p-1)*n_p*n_p,value_id);
1937 OOMPH_CURRENT_FUNCTION,
1938 OOMPH_EXCEPTION_LOCATION);
1943 for(
unsigned i=0;
i<3;
i++)
1945 s_in_neighb[
i] = s_lo_neigh[
i] + s_fraction[translate_s[
i]]*
1946 (s_hi_neigh[
i] - s_lo_neigh[
i]);
1954 if(0==neighbouring_node_pt)
1958 bool make_hanging_node =
false;
1964 make_hanging_node =
true;
1970 if((value_id!=-1) && (local_node_pt->
hanging_pt(value_id)==
1973 make_hanging_node =
true;
1977 if(make_hanging_node ==
true)
1992 unsigned n_neighbour;
1995 for(
unsigned ii0=0;ii0<n_p;ii0++)
1997 for(
unsigned ii1=0;ii1<n_p;ii1++)
2002 n_neighbour = ii0+ n_p*(n_p-1) + ii1*n_p*n_p;
2006 n_neighbour = ii0 + ii1*n_p*n_p;
2010 n_neighbour = ii0*n_p + ii1*n_p*n_p;
2014 n_neighbour = (n_p-1) + ii0*n_p + ii1*n_p*n_p;
2018 n_neighbour = ii0 +ii1*n_p;
2022 n_neighbour = ii0 + ii1*n_p + n_p*n_p*(n_p-1);
2026 "neigh_face not U, L, R, B, F\n",
2027 OOMPH_CURRENT_FUNCTION,
2028 OOMPH_EXCEPTION_LOCATION);
2037 set_master_node_pt(ii0*n_p + ii1,
2049 if(output_hangfile.is_open())
2052 output_hangfile << local_node_pt->
x(0) <<
" " <<
2053 local_node_pt->
x(1) <<
" "<< local_node_pt->
x(2) << std::endl;
2059 if (local_node_pt!=neighbouring_node_pt)
2061 std::ofstream reportage(
"dodgy.dat",std::ios_base::app);
2062 reportage << local_node_pt->
x(0) <<
" " 2063 << local_node_pt->
x(1) <<
" " 2064 << local_node_pt->
x(2) << std::endl;
2067 std::ostringstream warning_stream;
2068 warning_stream <<
"SANITY CHECK in oc_hang_helper \n" 2069 <<
"Current node " << local_node_pt
2071 <<
"(" << local_node_pt->
x(0) <<
", " 2072 << local_node_pt->
x(1) <<
", " 2073 << local_node_pt->
x(2) <<
")" << std::endl
2074 <<
" is not hanging and has " << std::endl
2075 <<
"Neighbour's node " << neighbouring_node_pt
2077 <<
"(" << neighbouring_node_pt->x(0) <<
", " 2078 << neighbouring_node_pt->x(1) <<
", " 2079 << neighbouring_node_pt->x(2) <<
")" 2081 <<
"even though the two should be " 2082 <<
"identical" << std::endl;
2084 "RefineableQElement<3>:oc_hang_helper()",
2085 OOMPH_EXCEPTION_LOCATION);
2100 local_node_pt->
x(0)=x_in_neighb[0];
2101 local_node_pt->
x(1)=x_in_neighb[1];
2102 local_node_pt->
x(2)=x_in_neighb[2];
2120 using namespace OcTreeNames;
2125 unsigned n_p=nnode_1d();
2134 double max_error_val=0.0;
2138 faces[0] =
D; faces[1] =
U; faces[2] =
L; faces[3] =
R;
2139 faces[4] =
B; faces[5] =
F;
2142 for(
unsigned face_counter=0;face_counter<6;face_counter++)
2147 int neigh_face,diff_level;
2150 my_face = faces[face_counter];
2155 s_hi_neigh,neigh_face,
2164 for(
unsigned i0=0;i0<n_p;i0++)
2166 for(
unsigned i1=0;i1<n_p;i1++)
2170 switch(face_counter)
2174 s_fraction[0] = local_one_d_fraction_of_node(i0,0);
2175 s_fraction[1] = 0.0;
2176 s_fraction[2] = local_one_d_fraction_of_node(i1,2);
2182 s_fraction[0] = local_one_d_fraction_of_node(i0,0);
2183 s_fraction[1] = 1.0;
2184 s_fraction[2] = local_one_d_fraction_of_node(i1,2);
2186 n= i0 + n_p*(n_p-1) + i1*n_p*n_p;
2190 s_fraction[0] = 0.0;
2191 s_fraction[1] = local_one_d_fraction_of_node(i0,1);
2192 s_fraction[2] = local_one_d_fraction_of_node(i1,2);
2194 n = n_p*i0 + i1*n_p*n_p;
2198 s_fraction[0] = 1.0;
2199 s_fraction[1] = local_one_d_fraction_of_node(i0,1);
2200 s_fraction[2] = local_one_d_fraction_of_node(i1,2);
2202 n = n_p-1 + n_p*i0 + n_p*n_p*i1;
2206 s_fraction[0] = local_one_d_fraction_of_node(i0,0);
2207 s_fraction[1] = local_one_d_fraction_of_node(i1,1);
2208 s_fraction[2] = 0.0;
2214 s_fraction[0] = local_one_d_fraction_of_node(i0,0);
2215 s_fraction[1] = local_one_d_fraction_of_node(i1,1);
2216 s_fraction[2] = 1.0;
2218 n = i0 + n_p*i1 + n_p*n_p*(n_p-1);
2226 for(
unsigned i=0;
i<3;
i++)
2228 s[
i] = -1.0 + 2.0*s_fraction[
i];
2229 s_in_neighb[
i] = s_lo_neigh[
i] + s_fraction[translate_s[
i]]*
2230 (s_hi_neigh[
i] - s_lo_neigh[
i]);
2235 for(
unsigned t=0;
t<n_time;
t++)
2242 for(
unsigned i=0;
i<3;
i++)
2245 double err=std::fabs(node_pt(n)->x(
t,
i) - x_in_neighb[
i]);
2250 oomph_info <<
"errx[" << i <<
"], t x, x_neigh: " 2251 << err <<
" " <<
t <<
" " 2252 << node_pt(n)->x(
t,i)
2253 <<
" " << x_in_neighb[
i]<< std::endl;
2255 << node_pt(n)->x(0) <<
" " 2256 << node_pt(n)->x(1) <<
" " 2257 << node_pt(n)->x(2) <<
" " 2263 if (err>max_error_x[i]) {max_error_x[
i]=err;}
2271 get_interpolated_values(
t,s_in_neighb,values_in_neighb);
2275 get_interpolated_values(
t,
s,values);
2279 unsigned num_val=neigh_pt->
object_pt()->
2280 ncont_interpolated_values();
2283 for(
unsigned ival=0;ival<num_val;ival++)
2285 double err=std::fabs(values[ival] - values_in_neighb[ival]);
2290 << node_pt(n)->x(1) <<
" " 2291 << node_pt(n)->x(2) <<
" \n# " 2292 <<
"erru (S)" << err <<
" " << ival <<
" " << n <<
" " 2294 <<
" " << values_in_neighb[ival] << std::endl;
2301 if (err>max_error_val) {max_error_val=err;}
2311 max_error=max_error_x[0];
2312 if (max_error_x[1]>max_error) max_error=max_error_x[1];
2313 if (max_error_x[2]>max_error) max_error=max_error_x[2];
2314 if (max_error_val>max_error) max_error=max_error_val;
2318 oomph_info <<
"\n#------------------------------------ \n#Max error " ;
2320 <<
" " << max_error_x[1]
2321 <<
" " << max_error_x[2]
2322 <<
" " << max_error_val << std::endl;
2323 oomph_info <<
"#------------------------------------ \n " << std::endl;
2352 using namespace OcTreeNames;
2355 unsigned n_dim = this->nodal_dimension();
2357 Vector<int> bound_cons1(n_dim), bound_cons2(n_dim);
2370 for(
int i=0;
i<3;
i++)
2375 notzero.push_back(
i);
2383 get_face_solid_bcs(bound,solid_bound_cons);
2389 for(
unsigned i=0;
i<3;
i++)
2391 vect1[
i]=0; vect2[
i]=0;
2394 vect1[notzero[0]]=vect_elem[notzero[0]];
2395 vect2[notzero[1]]=vect_elem[notzero[1]];
2400 for(
unsigned k=0;k<n_dim;k++)
2402 solid_bound_cons[k]=(bound_cons1[k]||bound_cons2[k]);
2409 for(
unsigned i=0;
i<3;
i++)
2411 vect1[
i]=0; vect2[
i]=0; vect3[
i]=0;
2414 vect1[0]=vect_elem[0];
2415 vect2[1]=vect_elem[1];
2416 vect3[2]=vect_elem[2];
2424 for(
unsigned k=0;k<n_dim;k++)
2426 solid_bound_cons[k]=(bound_cons1[k]||bound_cons2[k]||
2432 throw OomphLibError(
"Make sure you are not giving OMEGA as bound",
2433 OOMPH_CURRENT_FUNCTION,
2434 OOMPH_EXCEPTION_LOCATION);
2449 const int& face,
Vector<int>& solid_bound_cons)
const 2451 using namespace OcTreeNames;
2454 unsigned n_p = nnode_1d();
2456 unsigned node1, node2, node3, node4;
2462 node1 = n_p*n_p*n_p-1;
2463 node2 = n_p*n_p - 1;
2464 node3 = n_p*(n_p-1);
2465 node4 = n_p*(n_p*n_p - 1);
2471 node3 = (n_p*n_p+1)*(n_p-1);
2472 node4 = n_p*n_p*(n_p-1);
2477 node2 = (n_p*n_p+1)*(n_p-1);
2478 node3 = n_p*n_p*n_p-1;
2479 node4 = n_p*n_p - 1;
2484 node2 = n_p*(n_p - 1);
2485 node3 = n_p*(n_p*n_p-1);
2486 node4 = n_p*n_p*(n_p-1);
2493 node4 = n_p*(n_p -1);
2497 node1 = n_p*n_p*n_p-1;
2498 node2 = n_p*(n_p*n_p-1);
2499 node3 = n_p*n_p*(n_p-1);
2500 node4 = (n_p-1)*(n_p*n_p+1);
2504 std::ostringstream error_stream;
2505 error_stream <<
"Wrong edge " << face <<
" passed\n";
2508 OOMPH_CURRENT_FUNCTION,
2509 OOMPH_EXCEPTION_LOCATION);
2519 if(solid_node1_pt==0)
2522 "Corner node 1 cannot be cast to SolidNode --> something is wrong",
2523 OOMPH_CURRENT_FUNCTION,
2524 OOMPH_EXCEPTION_LOCATION);
2527 if(solid_node2_pt==0)
2530 "Corner node 2 cannot be cast to SolidNode --> something is wrong",
2531 OOMPH_CURRENT_FUNCTION,
2532 OOMPH_EXCEPTION_LOCATION);
2535 if(solid_node3_pt==0)
2538 "Corner node 3 cannot be cast to SolidNode --> something is wrong",
2539 OOMPH_CURRENT_FUNCTION,
2540 OOMPH_EXCEPTION_LOCATION);
2543 if(solid_node4_pt==0)
2546 "Corner node 4 cannot be cast to SolidNode --> something is wrong",
2547 OOMPH_CURRENT_FUNCTION,
2548 OOMPH_EXCEPTION_LOCATION);
2554 unsigned n_dim = this->nodal_dimension();
2559 for(
unsigned k=0;k<n_dim;k++)
2561 solid_bound_cons[k] =
2562 solid_node1_pt->position_is_pinned(k)*
void get_x(const Vector< double > &s, Vector< double > &x) const
Global coordinates as function of local coordinates. Either via FE representation or via macro-elemen...
virtual void set_coordinates_on_boundary(const unsigned &b, const unsigned &k, const Vector< double > &boundary_zeta)
Set the vector of the k-th generalised boundary coordinates on mesh boundary b. Broken virtual interf...
virtual Node * interpolating_node_pt(const unsigned &n, const int &value_id)
In mixed elements, different sets of nodes are used to interpolate different unknowns. This function returns the n-th node that interpolates the value_id-th unknown. Default implementation is that all variables use the positional nodes, i.e. isoparametric elements. Note that any overloaded versions of this function MUST provide a set of nodes for the position, which always has the value_id -1.
A policy class that serves to establish the common interfaces for elements that contain moving nodes...
OcTree * gteq_face_neighbour(const int &direction, Vector< unsigned > &translate_s, Vector< double > &s_sw, Vector< double > &s_ne, int &face, int &diff_level) const
Find (pointer to) `greater-or-equal-sized face neighbour' in given direction (L/R/U/D/F/B). Another way of interpreting this is that we're looking for the neighbour across the present element's face 'direction'. The various arguments return additional information about the size and relative orientation of the neighbouring octree. To interpret these we use the following General convention:
static std::map< Vector< int >, int > Vector_to_direction
Each vector representing a direction can be translated into a direction, either a son type (vertex)...
void add_boundary_node(const unsigned &b, Node *const &node_pt)
Add a (pointer to) a node to the b-th boundary.
virtual Node * get_node_at_local_coordinate(const Vector< double > &s) const
If there is a node at this local coordinate, return the pointer to the node.
HangInfo *const & hanging_pt() const
Return pointer to hanging node data (this refers to the geometric hanging node status) (const version...
virtual void get_interpolated_values(const Vector< double > &s, Vector< double > &values)
Get all continously interpolated function values in this element as a Vector. Note: Vector sets is ow...
bool boundary_coordinate_exists(const unsigned &i) const
Indicate whether the i-th boundary has an intrinsic coordinate.
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
virtual Node * get_interpolating_node_at_local_coordinate(const Vector< double > &s, const int &value_id)
Return a pointer to the node that interpolates the value-id-th unknown at local coordinate s...
bool is_hanging() const
Test whether the node is geometrically hanging.
unsigned nvalue() const
Return number of values stored in data object (incl pinned ones).
void interpolated_zeta_on_face(const unsigned &boundary, const int &face, const Vector< double > &s, Vector< double > &zeta)
Return the value of the intrinsic boundary coordinate interpolated along the face.
void pin(const unsigned &i)
Pin the i-th stored variable.
virtual void interpolating_basis(const Vector< double > &s, Shape &psi, const int &value_id) const
Return the basis functions that are used to interpolate the value_id-th unknown. By default assume is...
unsigned Number
The unsigned.
void add_node_pt(Node *const &node_pt)
Add a (pointer to a) node to the mesh.
unsigned ndim() const
Return (Eulerian) spatial dimension of the node.
double & s_macro_ur(const unsigned &i)
Access fct to the i-th coordinate of the element's "upper right" vertex in the associated MacroElemen...
void get_bcs(int bound, Vector< int > &bound_cons) const
Determine Vector of boundary conditions along the element's boundary (or vertex) bound (S/W/N/E/SW/SE...
void pin_position(const unsigned &i)
Pin the nodal position.
Refineable version of Solid brick elements.
double & x(const unsigned &i)
Return the i-th nodal coordinate.
virtual double interpolated_x(const Vector< double > &s, const unsigned &i) const
Return FE interpolated coordinate x[i] at local coordinate s.
virtual unsigned ninterpolating_node(const int &value_id)
Return the number of nodes that are used to interpolate the value_id-th unknown. Default is to assume...
void start(const unsigned &i)
(Re-)start i-th timer
static Vector< Vector< int > > Direction_to_vector
For each direction, i.e. a son_type (vertex), a face or an edge, this defines a vector that indicates...
void set_value(const unsigned &i, const double &value_)
Set the i-th stored data value to specified value. The only reason that we require an explicit set fu...
unsigned nposition_type() const
Number of coordinate types needed in the mapping between local and global coordinates.
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Vector< GeomObject * > & geom_object_pt()
Vector of (pointers to) geometric objects involved in node update function.
void shape(const double &s, double *Psi)
Definition for 1D Lagrange shape functions. The value of all the shape functions at the local coordin...
MacroElement * macro_elem_pt()
Access function to pointer to macro element.
Class that contains data for hanging nodes.
static Vector< std::string > Direct_string
Translate (enumerated) directions into strings.
virtual bool nodes_built()
Return true if all the nodes have been built, false if not.
void set_hanging_pt(HangInfo *const &hang_pt, const int &i)
Set the hanging data for the i-th value. (hang_pt=0 to make non-hanging)
double & s_macro_ll(const unsigned &i)
Access fct to the i-th coordinate of the element's "lower left" vertex in the associated MacroElement...
static const int OMEGA
Default value for an unassigned neighbour.
A Class for nodes that deform elastically (i.e. position is an unknown in the problem). The idea is that the Eulerian positions are stored in a Data object and the Lagrangian coordinates are stored in addition. The pointer that addresses the Eulerian positions is set to the pointer to Value in the Data object. Hence, SolidNode uses knowledge of the internal structure of Data and must be a friend of the Data class. In order to allow a mesh to deform via an elastic-style equation in deforming-domain problems, the positions are stored separately from the values, so that elastic problems may be combined with any other type of problem.
Base class for elements that allow MacroElement-based node update.
TimeStepper *& time_stepper_pt()
Return the pointer to the timestepper.
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
virtual bool position_is_a_copy() const
Return whether any position coordinate has been copied (always false)
Vector< std::string > colour
Tecplot colours.
bool position_is_pinned(const unsigned &i)
Test whether the i-th coordinate is pinned, 0: false; 1: true.
int & method_for_shape_derivs()
Access to method (enumerated flag) for determination of shape derivs.
int son_type() const
Return son type.
RefineableElement * object_pt() const
Return the pointer to the object (RefineableElement) represented by the tree.
void get_boundaries(const int &edge, std::set< unsigned > &boundaries) const
virtual bool is_a_copy() const
Return a boolean to indicate whether the Data objact contains any copied values. A base Data object c...
void enable_bypass_fill_in_jacobian_from_geometric_data()
Bypass the call to fill_in_jacobian_from_geometric_data.
Base class for time-stepping schemes. Timestepper provides an approximation of the temporal derivativ...
void setup_algebraic_node_update(Node *&node_pt, const Vector< double > &s_father, FiniteElement *father_el_pt) const
Set up node update info for (newly created) algebraic node: I.e. work out its node update information...