73 for (
unsigned i = 0;
i < n_internal_data;
i++)
83 <<
"---------------------------------------------------------------"
86 <<
"Info: Data is already included in this element's internal "
89 <<
"It's stored as entry " <<
i <<
" and I'm not adding it again."
92 <<
"Note: You can suppress this message by recompiling without"
93 <<
"\n PARANOID or setting the boolean \n"
95 "GeneralisedElement::Suppress_warning_about_repeated_internal_"
97 <<
"\n\n to true." << std::endl
98 <<
"---------------------------------------------------------------"
110 Data** new_data_pt =
new Data*[n_internal_data + n_external_data + 1];
113 for (
unsigned i = 0;
i < n_internal_data;
i++)
119 new_data_pt[n_internal_data] = data_pt;
122 for (
unsigned i = 0;
i < n_external_data;
i++)
124 new_data_pt[n_internal_data + 1 +
i] =
Data_pt[n_internal_data +
i];
134 Data_fd.resize(n_internal_data + n_external_data + 1);
136 for (
unsigned i = n_external_data;
i > 0;
i--)
147 return n_internal_data;
157 std::deque<unsigned long>
const& global_eqn_numbers,
158 std::deque<double*>
const& global_dof_pt)
161 const unsigned n_dof =
Ndof;
163 const unsigned n_additional_dof = global_eqn_numbers.size();
165 if (n_additional_dof == 0)
171 const unsigned new_n_dof = n_dof + n_additional_dof;
173 unsigned long* new_eqn_number =
new unsigned long[new_n_dof];
176 for (
unsigned i = 0;
i < n_dof;
i++)
182 unsigned index = n_dof;
184 for (std::deque<unsigned long>::const_iterator it =
185 global_eqn_numbers.begin();
186 it != global_eqn_numbers.end();
190 new_eqn_number[index] = *it;
197 const unsigned n_additional_dof_pt = global_dof_pt.size();
198 if (n_additional_dof_pt > 0)
202 if (n_additional_dof_pt != n_additional_dof)
204 std::ostringstream error_stream;
206 <<
"global_dof_pt is non-empty, yet it does not have the same size\n"
207 <<
"as global_eqn_numbers.\n"
208 <<
"There are " << n_additional_dof <<
" equation numbers,\n"
209 <<
"but " << n_additional_dof_pt << std::endl;
212 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
217 double** new_dof_pt =
new double*[new_n_dof];
219 for (
unsigned i = 0;
i < n_dof;
i++)
225 unsigned index = n_dof;
227 for (std::deque<double*>::const_iterator it = global_dof_pt.begin();
228 it != global_dof_pt.end();
232 new_dof_pt[index] = *it;
276 GeneralisedElement::~GeneralisedElement()
317 for (
unsigned i = 0;
i < n_external_data;
i++)
327 <<
"---------------------------------------------------------------"
330 <<
"Info: Data is already included in this element's external "
333 <<
"It's stored as entry " <<
i <<
" and I'm not adding it again"
336 <<
"Note: You can suppress this message by recompiling without"
337 <<
"\n PARANOID or setting the boolean \n"
339 "GeneralisedElement::Suppress_warning_about_repeated_external_"
341 <<
"\n\n to true." << std::endl
342 <<
"---------------------------------------------------------------"
354 Data** new_data_pt =
new Data*[n_internal_data + n_external_data + 1];
357 for (
unsigned i = 0;
i < (n_internal_data + n_external_data);
i++)
363 new_data_pt[n_internal_data + n_external_data] = data_pt;
372 Data_fd.resize(n_internal_data + n_external_data + 1);
374 Data_fd[n_internal_data + n_external_data] = fd;
380 return n_external_data;
392 if (n_external_data > 0)
395 Data** new_data_pt = 0;
401 if (n_internal_data > 0)
404 new_data_pt =
new Data*[n_internal_data];
406 for (
unsigned i = 0;
i < n_internal_data;
i++)
420 Data_fd.resize(n_internal_data);
436 unsigned index = n_external_data;
438 for (
unsigned i = 0;
i < n_external_data;
i++)
450 if (index < n_external_data)
453 Data** new_data_pt = 0;
459 const unsigned n_total_data = n_internal_data + n_external_data - 1;
462 if (n_total_data > 0)
464 new_data_pt =
new Data*[n_total_data];
468 for (
unsigned i = 0;
i < n_internal_data;
i++)
474 unsigned counter = 0;
475 for (
unsigned i = 0;
i < n_external_data;
i++)
482 new_data_pt[n_internal_data + counter] =
Data_pt[
i];
503 std::ostringstream warning_stream;
505 <<
"Data removed from element's external data " << std::endl
506 <<
"You may have to update the indices for remaining data "
508 <<
"This can be achieved by using add_external_data() "
511 "GeneralisedElement::flush_external_data()",
512 OOMPH_EXCEPTION_LOCATION);
552 std::ostream& out,
const std::string& current_string)
const
556 std::stringstream conversion;
557 conversion <<
" of Internal Data " <<
i << current_string;
574 std::ostream& out,
const std::string& current_string)
const
581 for (
unsigned i = 0;
i < n_internal_data;
i++)
586 std::stringstream conversion;
587 conversion <<
" of Internal Data " <<
i << current_string;
594 for (
unsigned i = 0;
i < n_external_data;
i++)
599 std::stringstream conversion;
600 conversion <<
" of External Data " <<
i << current_string;
612 std::map<unsigned, double*>& map_of_value_pt)
671 const Vector<long>& vector_of_eqn_numbers,
unsigned& index)
692 const bool& store_local_dof_pt)
701 std::ostringstream error_stream;
705 std::map<unsigned, bool> is_repeated;
706 std::set<unsigned long> set_of_global_eqn_numbers;
707 unsigned old_ndof = 0;
708 for (
unsigned n = 0; n <
Ndof; ++n)
710 set_of_global_eqn_numbers.insert(
Eqn_number[n]);
711 if (set_of_global_eqn_numbers.size() == old_ndof)
713 error_stream <<
"Repeated global eqn: " <<
Eqn_number[n] << std::endl;
716 old_ndof = set_of_global_eqn_numbers.size();
720 if (set_of_global_eqn_numbers.size() !=
Ndof)
723 error_stream <<
"Element is ";
724 if (!
is_halo()) error_stream <<
"not ";
725 error_stream <<
"a halo element\n\n";
727 error_stream <<
"\nLocal/lobal equation numbers: " << std::endl;
728 for (
unsigned n = 0; n <
Ndof; ++n)
730 error_stream <<
" " << n <<
" " <<
Eqn_number[n] << std::endl;
734 error_stream << std::endl <<
" element address is " <<
this << std::endl;
738 error_stream <<
"Number of internal data " << nint << std::endl;
739 for (
unsigned i = 0;
i < nint;
i++)
742 unsigned nval = data_pt->
nvalue();
743 for (
unsigned j = 0; j < nval; j++)
746 error_stream <<
"Internal dof: " << eqn_no << std::endl;
747 if (is_repeated[
unsigned(eqn_no)])
749 error_stream <<
"Repeated internal dof: " << eqn_no << std::endl;
756 error_stream <<
"Number of external data " << next << std::endl;
757 for (
unsigned i = 0;
i < next;
i++)
760 unsigned nval = data_pt->
nvalue();
761 for (
unsigned j = 0; j < nval; j++)
764 error_stream <<
"External dof: " << eqn_no << std::endl;
765 if (is_repeated[
unsigned(eqn_no)])
767 error_stream <<
"Repeated external dof: " << eqn_no;
768 Node* nod_pt =
dynamic_cast<Node*
>(data_pt);
771 error_stream <<
" (is a node at: ";
772 unsigned ndim = nod_pt->
ndim();
773 for (
unsigned ii = 0; ii < ndim; ii++)
775 error_stream << nod_pt->
x(ii) <<
" ";
778 error_stream <<
")\n";
793 error_stream <<
"Number of external element data " << next
796 for (
unsigned i = 0;
i < next;
i++)
798 unsigned nval = data_pt[
i]->nvalue();
799 for (
unsigned j = 0; j < nval; j++)
801 int eqn_no = data_pt[
i]->eqn_number(j);
802 error_stream <<
"External element dof: " << eqn_no << std::endl;
803 if (is_repeated[
unsigned(eqn_no)])
805 error_stream <<
"Repeated external element dof: " << eqn_no;
806 Node* nod_pt =
dynamic_cast<Node*
>(data_pt[
i]);
809 error_stream <<
" (is a node at: ";
810 unsigned ndim = nod_pt->
ndim();
811 for (
unsigned ii = 0; ii < ndim; ii++)
813 error_stream << nod_pt->
x(ii) <<
" ";
816 error_stream <<
")\n";
826 error_stream <<
"Number of external element geom data " << next
830 for (
unsigned i = 0;
i < next;
i++)
832 unsigned nval = data_pt[
i]->nvalue();
833 for (
unsigned j = 0; j < nval; j++)
835 int eqn_no = data_pt[
i]->eqn_number(j);
836 error_stream <<
"External element geometric dof: " << eqn_no
838 if (is_repeated[
unsigned(eqn_no)])
841 <<
"Repeated external element geometric dof: " << eqn_no
842 <<
" " << data_pt[
i]->value(j);
843 Node* nod_pt =
dynamic_cast<Node*
>(data_pt[
i]);
846 error_stream <<
" (is a node at: ";
847 unsigned ndim = nod_pt->
ndim();
848 for (
unsigned ii = 0; ii < ndim; ii++)
850 error_stream << nod_pt->
x(
i) <<
" ";
854 error_stream <<
"\n";
865 unsigned n_node = f_el_pt->
nnode();
866 for (
unsigned n = 0; n < n_node; n++)
869 unsigned nval = nod_pt->
nvalue();
870 for (
unsigned j = 0; j < nval; j++)
873 error_stream <<
"Node " << n <<
": Nodal dof: " << eqn_no;
876 if (is_repeated[
unsigned(eqn_no)])
878 error_stream <<
"Node " << n
879 <<
": Repeated nodal dof: " << eqn_no;
882 error_stream <<
" (resized)";
884 error_stream << std::endl;
889 if (solid_nod_pt != 0)
892 unsigned nval = data_pt->
nvalue();
893 for (
unsigned j = 0; j < nval; j++)
896 error_stream <<
"Node " << n <<
": Positional dof: " << eqn_no
898 if (is_repeated[
unsigned(eqn_no)])
900 error_stream <<
"Repeated positional dof: " << eqn_no <<
" "
901 << data_pt->
value(j) << std::endl;
908 n_node = f_el_pt->
nnode();
909 for (
unsigned n = 0; n < n_node; n++)
912 unsigned n_dim = nod_pt->
ndim();
913 error_stream <<
"Node " << n <<
" at ( ";
914 for (
unsigned i = 0;
i < n_dim;
i++)
916 error_stream << nod_pt->
x(
i) <<
" ";
918 error_stream <<
")" << std::endl;
924 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
939 const bool& store_local_dof_pt)
945 const unsigned n_total_data = n_internal_data + n_external_data;
948 if (n_total_data > 0)
958 for (
unsigned i = 1;
i < n_total_data; ++
i)
972 if (n_total_values == 0)
987 for (
unsigned i = 0;
i < n_total_values; ++
i)
993 for (
unsigned i = 1;
i < n_total_data; ++
i)
1004 std::deque<unsigned long> global_eqn_number_queue;
1007 for (
unsigned i = 0;
i < n_internal_data;
i++)
1012 unsigned n_value = data_pt->
nvalue();
1015 for (
unsigned j = 0; j < n_value; j++)
1023 global_eqn_number_queue.push_back(
eqn_number);
1025 if (store_local_dof_pt)
1044 for (
unsigned i = 0;
i < n_external_data;
i++)
1049 unsigned n_value = data_pt->
nvalue();
1052 for (
unsigned j = 0; j < n_value; j++)
1060 global_eqn_number_queue.push_back(
eqn_number);
1062 if (store_local_dof_pt)
1083 if (store_local_dof_pt)
1105 const bool& fd_all_data)
1111 if (n_internal_data == 0)
1121 const unsigned n_dof =
ndof();
1127 int local_unknown = 0;
1133 for (
unsigned i = 0;
i < n_internal_data;
i++)
1143 for (
unsigned j = 0; j < n_value; j++)
1148 if (local_unknown >= 0)
1154 const double old_var = *value_pt;
1157 *value_pt += fd_step;
1166 for (
unsigned m = 0; m < n_dof; m++)
1168 double sum = (newres[m] - residuals[m]) / fd_step;
1170 jacobian(m, local_unknown) = sum;
1174 *value_pt = old_var;
1202 const bool& fd_all_data)
1207 if (n_external_data == 0)
1217 const unsigned n_dof =
ndof();
1223 int local_unknown = 0;
1229 for (
unsigned i = 0;
i < n_external_data;
i++)
1239 for (
unsigned j = 0; j < n_value; j++)
1244 if (local_unknown >= 0)
1250 const double old_var = *value_pt;
1253 *value_pt += fd_step;
1262 for (
unsigned m = 0; m < n_dof; m++)
1264 double sum = (newres[m] - residuals[m]) / fd_step;
1266 jacobian(m, local_unknown) = sum;
1270 *value_pt = old_var;
1296 "Empty fill_in_contribution_to_mass_matrix() has been called.\n";
1298 "This function is called from the default implementation of\n";
1299 error_message +=
"get_mass_matrix();\n";
1300 error_message +=
"and must calculate the residuals vector and mass matrix ";
1301 error_message +=
"without initialising any of their entries.\n\n";
1304 "If you do not wish to use these defaults, you must overload\n";
1305 error_message +=
"get_mass_matrix(), which must initialise the entries\n";
1306 error_message +=
"of the residuals vector and mass matrix to zero.\n";
1310 "GeneralisedElement::fill_in_contribution_to_mass_matrix()",
1311 OOMPH_EXCEPTION_LOCATION);
1328 "Empty fill_in_contribution_to_jacobian_and_mass_matrix() has been ";
1329 error_message +=
"called.\n";
1331 "This function is called from the default implementation of\n";
1332 error_message +=
"get_jacobian_and_mass_matrix();\n";
1334 "and must calculate the residuals vector and mass and jacobian matrices ";
1335 error_message +=
"without initialising any of their entries.\n\n";
1338 "If you do not wish to use these defaults, you must overload\n";
1340 "get_jacobian_and_mass_matrix(), which must initialise the entries\n";
1342 "of the residuals vector, jacobian and mass matrix to zero.\n";
1346 "GeneralisedElement::fill_in_contribution_to_jacobian_and_mass_matrix()",
1347 OOMPH_EXCEPTION_LOCATION);
1362 "Empty fill_in_contribution_to_dresiduals_dparameter() has been ";
1363 error_message +=
"called.\n";
1365 "This function is called from the default implementation of\n";
1366 error_message +=
"get_dresiduals_dparameter();\n";
1367 error_message +=
"and must calculate the derivatives of the residuals "
1368 "vector with respect\n";
1369 error_message +=
"to the passed parameter ";
1370 error_message +=
"without initialising any values.\n\n";
1373 "If you do not wish to use these defaults, you must overload\n";
1375 "get_dresiduals_dparameter(), which must initialise the entries\n";
1376 error_message +=
"of the returned vector to zero.\n";
1379 "This function is intended for use instead of the default (global) \n";
1381 "finite-difference routine when analytic expressions are to be used\n";
1382 error_message +=
"in continuation and bifurcation tracking problems.\n\n";
1383 error_message +=
"This function is only called when the function\n";
1385 "Problem::set_analytic_dparameter() has been called in the driver code\n";
1389 "GeneralisedElement::fill_in_contribution_to_dresiduals_dparameter()",
1390 OOMPH_EXCEPTION_LOCATION);
1403 double*
const& parameter_pt,
1408 "Empty fill_in_contribution_to_djacobian_dparameter() has been ";
1409 error_message +=
"called.\n";
1411 "This function is called from the default implementation of\n";
1412 error_message +=
"get_djacobian_dparameter();\n";
1414 "and must calculate the derivatives of residuals vector and jacobian ";
1415 error_message +=
"matrix\n";
1416 error_message +=
"with respect to the passed parameter ";
1417 error_message +=
"without initialising any values.\n\n";
1420 "If you do not wish to use these defaults, you must overload\n";
1422 "get_djacobian_dparameter(), which must initialise the entries\n";
1423 error_message +=
"of the returned vector and matrix to zero.\n\n";
1426 "This function is intended for use instead of the default (global) \n";
1428 "finite-difference routine when analytic expressions are to be used\n";
1429 error_message +=
"in continuation and bifurcation tracking problems.\n\n";
1430 error_message +=
"This function is only called when the function\n";
1432 "Problem::set_analytic_dparameter() has been called in the driver code\n";
1437 "GeneralisedElement::fill_in_contribution_to_djacobian_dparameter()",
1438 OOMPH_EXCEPTION_LOCATION);
1454 double*
const& parameter_pt,
1460 "Empty fill_in_contribution_to_djacobian_and_dmass_matrix_dparameter() "
1462 error_message +=
" been called.\n";
1464 "This function is called from the default implementation of\n";
1465 error_message +=
"get_djacobian_and_dmass_matrix_dparameter();\n";
1467 "and must calculate the residuals vector and mass and jacobian matrices ";
1468 error_message +=
"without initialising any of their entries.\n\n";
1471 "If you do not wish to use these defaults, you must overload\n";
1472 error_message +=
"get_djacobian_and_dmass_matrix_dparameter(), which must "
1474 error_message +=
"entries of the returned vector and matrices to zero.\n";
1478 "This function is intended for use instead of the default (global) \n";
1480 "finite-difference routine when analytic expressions are to be used\n";
1481 error_message +=
"in continuation and bifurcation tracking problems.\n\n";
1482 error_message +=
"This function is only called when the function\n";
1484 "Problem::set_analytic_dparameter() has been called in the driver code\n";
1488 "GeneralisedElement::fill_in_contribution_to_djacobian_"
1489 "and_dmass_matrix_dparameter()",
1490 OOMPH_EXCEPTION_LOCATION);
1509 "Empty fill_in_contribution_to_hessian_vector_products() has been ";
1510 error_message +=
"called.\n";
1512 "This function is called from the default implementation of\n";
1513 error_message +=
"get_hessian_vector_products(); ";
1514 error_message +=
" and must calculate the products \n";
1515 error_message +=
"of the hessian matrix with the (global) ";
1516 error_message +=
"vectors Y and C\n";
1517 error_message +=
"without initialising any values.\n\n";
1520 "If you do not wish to use these defaults, you must overload\n";
1522 "get_hessian_vector_products(), which must initialise the entries\n";
1523 error_message +=
"of the returned vector to zero.\n\n";
1526 "This function is intended for use instead of the default (global) \n";
1528 "finite-difference routine when analytic expressions are to be used.\n";
1529 error_message +=
"This function is only called when the function\n";
1530 error_message +=
"Problem::set_analytic_hessian_products() has been called "
1531 "in the driver code\n";
1535 "GeneralisedElement::fill_in_contribution_to_hessian_vector_product()",
1536 OOMPH_EXCEPTION_LOCATION);
1544 Vector<std::pair<unsigned, unsigned>>
const& history_index,
1548 "Empty fill_in_contribution_to_inner_products() has been called.\n";
1550 "This function is called from the default implementation of\n";
1551 error_message +=
"get_inner_products();\n ";
1552 error_message +=
"It must calculate the inner products over the element\n";
1553 error_message +=
"of given pairs of history values\n";
1554 error_message +=
"without initialision of the output vector.\n\n";
1557 "If you do not wish to use these defaults, you must overload\n";
1559 "get_inner_products(), which must initialise the entries\n";
1560 error_message +=
"of the returned vector to zero.\n\n";
1563 error_message, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1576 "Empty fill_in_contribution_to_inner_product_vectors() has been "
1579 "This function is called from the default implementation of\n";
1580 error_message +=
"get_inner_product_vectors(); ";
1581 error_message +=
" and must calculate the vectors \n";
1582 error_message +=
"corresponding to the input history values\n ";
1584 "that when multiplied by other vectors of history values\n";
1585 error_message +=
"return the appropriate dot products.\n\n";
1586 error_message +=
"The output vectors must not be initialised.\n\n";
1589 "If you do not wish to use these defaults, you must overload\n";
1591 "get_inner_products(), which must initialise the entries\n";
1592 error_message +=
"of the returned vector to zero.\n\n";
1595 error_message, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1614 oomph_info <<
"\n ERROR: Failed GeneralisedElement::self_test()!"
1616 oomph_info <<
"for internal data object number: " <<
i << std::endl;
1626 oomph_info <<
"\n ERROR: Failed GeneralisedElement::self_test()!"
1628 oomph_info <<
"for external data object number: " <<
i << std::endl;
1648 namespace Locate_zeta_helpers
1687 const unsigned&
i)
const
1710 std::ostream& out,
const std::string& current_string)
const
1728 std::ostream& out,
const std::string& current_string)
const
1731 const unsigned n_node =
nnode();
1732 for (
unsigned n = 0; n < n_node; n++)
1737 std::stringstream conversion;
1738 conversion <<
" of Node " << n << current_string;
1761 std::ostringstream error_stream;
1763 <<
"Determinant of Jacobian matrix is zero --- "
1764 <<
"singular mapping!\nThe determinant of the "
1765 <<
"jacobian is " << std::fabs(jacobian)
1766 <<
" which is smaller than the treshold "
1768 <<
"You can change this treshold, by specifying "
1769 <<
"FiniteElement::Tolerance_for_singular_jacobian \n"
1770 <<
"Here are the nodal coordinates of the inverted element\n"
1771 <<
"in the form \n\n x,y[,z], hang_status\n\n"
1772 <<
"where hang_status = 1 or 2 for non-hanging or hanging\n"
1773 <<
"nodes respectively (useful for automatic sizing of\n"
1774 <<
"tecplot markers to identify the hanging nodes). \n\n";
1776 unsigned n_nod =
nnode();
1777 unsigned hang_count = 0;
1778 for (
unsigned j = 0; j < n_nod; j++)
1780 for (
unsigned i = 0;
i < n_dim_nod;
i++)
1782 error_stream <<
node_pt(j)->
x(
i) <<
" ";
1786 error_stream <<
" 2";
1791 error_stream <<
" 1";
1793 error_stream << std::endl;
1795 error_stream << std::endl << std::endl;
1799 <<
"NOTE: Offending element is associated with a MacroElement\n"
1800 <<
" AND the element has hanging nodes! \n"
1801 <<
" If an element is thin and highly curved, the \n"
1802 <<
" constraints imposed by\n \n"
1803 <<
" (1) inter-element continuity (imposed by the hanging\n"
1804 <<
" node constraints) and \n\n"
1805 <<
" (2) the need to respect curvilinear domain boundaries\n"
1806 <<
" during mesh refinement (imposed by the element's\n"
1807 <<
" macro element mapping)\n\n"
1808 <<
" may be irreconcilable! \n \n"
1809 <<
" You may have to re-design your base mesh to avoid \n"
1810 <<
" the creation of thin, highly curved elements during\n"
1811 <<
" the refinement process.\n"
1815 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1829 std::ostringstream error_stream;
1830 error_stream <<
"Negative Jacobian in transform from "
1831 <<
"local to global coordinates" << std::endl
1832 <<
" You have an inverted coordinate system!"
1836 <<
"Here are the nodal coordinates of the inverted element\n"
1837 <<
"in the form \n\n x,y[,z], hang_status\n\n"
1838 <<
"where hang_status = 1 or 2 for non-hanging or hanging\n"
1839 <<
"nodes respectively (useful for automatic sizing of\n"
1840 <<
"tecplot markers to identify the hanging nodes). \n\n";
1842 unsigned n_nod =
nnode();
1843 unsigned hang_count = 0;
1844 for (
unsigned j = 0; j < n_nod; j++)
1846 for (
unsigned i = 0;
i < n_dim_nod;
i++)
1848 error_stream <<
node_pt(j)->
x(
i) <<
" ";
1852 error_stream <<
" 2";
1857 error_stream <<
" 1";
1859 error_stream << std::endl;
1861 error_stream << std::endl << std::endl;
1865 <<
"NOTE: The inverted element is associated with a MacroElement\n"
1866 <<
" AND the element has hanging nodes! \n"
1867 <<
" If an element is thin and highly curved, the \n"
1868 <<
" constraints imposed by\n \n"
1869 <<
" (1) inter-element continuity (imposed by the hanging\n"
1870 <<
" node constraints) and \n\n"
1871 <<
" (2) the need to respect curvilinear domain boundaries\n"
1872 <<
" during mesh refinement (imposed by the element's\n"
1873 <<
" macro element mapping)\n\n"
1874 <<
" may be irreconcilable! \n \n"
1875 <<
" You may have to re-design your base mesh to avoid \n"
1876 <<
" the creation of thin, highly curved elements during\n"
1877 <<
" the refinement process.\n"
1884 <<
"If you believe that inverted elements do not cause any\n"
1885 <<
"problems in your specific application you can \n "
1886 <<
"suppress this test by: " << std::endl
1887 <<
" i) setting the (static) flag "
1888 <<
"FiniteElement::Accept_negative_jacobian to be true" << std::endl;
1889 error_stream <<
" ii) switching OFF the PARANOID flag" << std::endl
1893 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1909 const unsigned el_dim =
dim();
1912 const unsigned n_shape =
nnode();
1921 std::ostringstream error_message;
1922 error_message <<
"Dimension mismatch" << std::endl;
1925 <<
" for the jacobian of the mapping to be well-defined"
1928 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1934 for (
unsigned i = 0;
i < el_dim;
i++)
1937 for (
unsigned j = 0; j < el_dim; j++)
1940 jacobian(
i, j) = 0.0;
1942 for (
unsigned l = 0; l < n_shape; l++)
1944 for (
unsigned k = 0; k < n_shape_type; k++)
1967 const unsigned el_dim =
dim();
1971 const unsigned n_shape =
nnode();
1974 const unsigned n_row =
N2deriv[el_dim];
1979 for (
unsigned i = 0;
i < n_row;
i++)
1982 for (
unsigned j = 0; j < el_dim; j++)
1985 jacobian2(
i, j) = 0.0;
1987 for (
unsigned l = 0; l < n_shape; l++)
1990 for (
unsigned k = 0; k < n_shape_type; k++)
2013 const unsigned n_node =
nnode();
2017 const unsigned n_dim_element =
dim();
2021 for (
unsigned i = 0;
i < n_dim_element;
i++)
2023 for (
unsigned j = 0; j < n_dim_node; j++)
2026 interpolated_G(
i, j) = 0.0;
2027 for (
unsigned l = 0; l < n_node; l++)
2029 for (
unsigned k = 0; k < n_position_type; k++)
2031 interpolated_G(
i, j) +=
2044 double FiniteElement::invert_jacobian<0>(
2049 oomph_info <<
"\nWarning: You are trying to invert the jacobian for "
2050 <<
"a 'point' element" << std::endl
2051 <<
"This makes no sense and is almost certainly an error"
2064 double FiniteElement::invert_jacobian<1>(
2069 const double det = jacobian(0, 0);
2077 inverse_jacobian(0, 0) = 1.0 / jacobian(0, 0);
2087 double FiniteElement::invert_jacobian<2>(
2093 jacobian(0, 0) * jacobian(1, 1) - jacobian(0, 1) * jacobian(1, 0);
2101 inverse_jacobian(0, 0) = jacobian(1, 1) / det;
2102 inverse_jacobian(0, 1) = -jacobian(0, 1) / det;
2103 inverse_jacobian(1, 0) = -jacobian(1, 0) / det;
2104 inverse_jacobian(1, 1) = jacobian(0, 0) / det;
2115 double FiniteElement::invert_jacobian<3>(
2120 const double det = jacobian(0, 0) * jacobian(1, 1) * jacobian(2, 2) +
2121 jacobian(0, 1) * jacobian(1, 2) * jacobian(2, 0) +
2122 jacobian(0, 2) * jacobian(1, 0) * jacobian(2, 1) -
2123 jacobian(0, 0) * jacobian(1, 2) * jacobian(2, 1) -
2124 jacobian(0, 1) * jacobian(1, 0) * jacobian(2, 2) -
2125 jacobian(0, 2) * jacobian(1, 1) * jacobian(2, 0);
2133 inverse_jacobian(0, 0) =
2134 (jacobian(1, 1) * jacobian(2, 2) - jacobian(1, 2) * jacobian(2, 1)) / det;
2135 inverse_jacobian(0, 1) =
2136 -(jacobian(0, 1) * jacobian(2, 2) - jacobian(0, 2) * jacobian(2, 1)) /
2138 inverse_jacobian(0, 2) =
2139 (jacobian(0, 1) * jacobian(1, 2) - jacobian(0, 2) * jacobian(1, 1)) / det;
2140 inverse_jacobian(1, 0) =
2141 -(jacobian(1, 0) * jacobian(2, 2) - jacobian(1, 2) * jacobian(2, 0)) /
2143 inverse_jacobian(1, 1) =
2144 (jacobian(0, 0) * jacobian(2, 2) - jacobian(0, 2) * jacobian(2, 0)) / det;
2145 inverse_jacobian(1, 2) =
2146 -(jacobian(0, 0) * jacobian(1, 2) - jacobian(0, 2) * jacobian(1, 0)) /
2148 inverse_jacobian(2, 0) =
2149 (jacobian(1, 0) * jacobian(2, 1) - jacobian(1, 1) * jacobian(2, 0)) / det;
2150 inverse_jacobian(2, 1) =
2151 -(jacobian(0, 0) * jacobian(2, 1) - jacobian(0, 1) * jacobian(2, 0)) /
2153 inverse_jacobian(2, 2) =
2154 (jacobian(0, 0) * jacobian(1, 1) - jacobian(0, 1) * jacobian(1, 0)) / det;
2171 const unsigned el_dim =
dim();
2177 return invert_jacobian<0>(jacobian, inverse_jacobian);
2180 return invert_jacobian<1>(jacobian, inverse_jacobian);
2183 return invert_jacobian<2>(jacobian, inverse_jacobian);
2186 return invert_jacobian<3>(jacobian, inverse_jacobian);
2190 std::ostringstream error_stream;
2191 error_stream <<
"Dimension of the element must be 0,1,2 or 3, not "
2192 << el_dim << std::endl;
2195 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
2206 void FiniteElement::dJ_eulerian_dnodal_coordinates_templated_helper<0>(
2212 oomph_info <<
"\nWarning: You are trying to calculate derivatives of "
2213 <<
"a jacobian w.r.t. nodal coordinates for a 'point' "
2214 <<
"element." << std::endl
2215 <<
"This makes no sense and is almost certainly an error."
2225 void FiniteElement::dJ_eulerian_dnodal_coordinates_templated_helper<1>(
2231 const unsigned n_node =
nnode();
2234 for (
unsigned j = 0; j < n_node; j++)
2236 djacobian_dX(0, j) = dpsids(j, 0);
2245 void FiniteElement::dJ_eulerian_dnodal_coordinates_templated_helper<2>(
2251 const unsigned n_node =
nnode();
2254 for (
unsigned j = 0; j < n_node; j++)
2257 djacobian_dX(0, j) =
2258 dpsids(j, 0) * jacobian(1, 1) - dpsids(j, 1) * jacobian(0, 1);
2261 djacobian_dX(1, j) =
2262 dpsids(j, 1) * jacobian(0, 0) - dpsids(j, 0) * jacobian(1, 0);
2271 void FiniteElement::dJ_eulerian_dnodal_coordinates_templated_helper<3>(
2277 const unsigned n_node =
nnode();
2280 for (
unsigned j = 0; j < n_node; j++)
2283 djacobian_dX(0, j) =
2285 (jacobian(1, 1) * jacobian(2, 2) - jacobian(1, 2) * jacobian(2, 1)) +
2287 (jacobian(0, 2) * jacobian(2, 1) - jacobian(0, 1) * jacobian(2, 2)) +
2289 (jacobian(0, 1) * jacobian(1, 2) - jacobian(0, 2) * jacobian(1, 1));
2292 djacobian_dX(1, j) =
2294 (jacobian(1, 2) * jacobian(2, 0) - jacobian(1, 0) * jacobian(2, 2)) +
2296 (jacobian(0, 0) * jacobian(2, 2) - jacobian(0, 2) * jacobian(2, 0)) +
2298 (jacobian(0, 2) * jacobian(1, 0) - jacobian(0, 0) * jacobian(1, 2));
2301 djacobian_dX(2, j) =
2303 (jacobian(1, 0) * jacobian(2, 1) - jacobian(1, 1) * jacobian(2, 0)) +
2305 (jacobian(0, 1) * jacobian(2, 0) - jacobian(0, 0) * jacobian(2, 1)) +
2307 (jacobian(0, 0) * jacobian(1, 1) - jacobian(0, 1) * jacobian(1, 0));
2317 void FiniteElement::d_dshape_eulerian_dnodal_coordinates_templated_helper<0>(
2318 const double& det_jacobian,
2326 oomph_info <<
"\nWarning: You are trying to calculate derivatives of "
2327 <<
"eulerian derivatives of shape functions w.r.t. nodal "
2328 <<
"coordinates for a 'point' element." << std::endl
2329 <<
"This makes no sense and is almost certainly an error."
2340 void FiniteElement::d_dshape_eulerian_dnodal_coordinates_templated_helper<1>(
2341 const double& det_jacobian,
2349 const double inv_det_jac = 1.0 / det_jacobian;
2352 const unsigned n_node =
nnode();
2355 for (
unsigned q = 0; q < n_node; q++)
2358 for (
unsigned j = 0; j < n_node; j++)
2360 d_dpsidx_dX(0, q, j, 0) =
2361 -djacobian_dX(0, q) * dpsids(j, 0) * inv_det_jac * inv_det_jac;
2372 void FiniteElement::d_dshape_eulerian_dnodal_coordinates_templated_helper<2>(
2373 const double& det_jacobian,
2381 const double inv_det_jac = 1.0 / det_jacobian;
2384 const unsigned n_node =
nnode();
2387 for (
unsigned p = 0; p < 2; p++)
2390 for (
unsigned q = 0; q < n_node; q++)
2393 for (
unsigned j = 0; j < n_node; j++)
2396 d_dpsidx_dX(p, q, j, 0) =
2397 -djacobian_dX(p, q) * (inverse_jacobian(0, 0) * dpsids(j, 0) +
2398 inverse_jacobian(0, 1) * dpsids(j, 1));
2402 d_dpsidx_dX(p, q, j, 0) +=
2403 dpsids(j, 0) * dpsids(q, 1) - dpsids(j, 1) * dpsids(q, 0);
2405 d_dpsidx_dX(p, q, j, 0) *= inv_det_jac;
2408 d_dpsidx_dX(p, q, j, 1) =
2409 -djacobian_dX(p, q) * (inverse_jacobian(1, 1) * dpsids(j, 1) +
2410 inverse_jacobian(1, 0) * dpsids(j, 0));
2414 d_dpsidx_dX(p, q, j, 1) +=
2415 dpsids(j, 1) * dpsids(q, 0) - dpsids(j, 0) * dpsids(q, 1);
2417 d_dpsidx_dX(p, q, j, 1) *= inv_det_jac;
2429 void FiniteElement::d_dshape_eulerian_dnodal_coordinates_templated_helper<3>(
2430 const double& det_jacobian,
2438 const double inv_det_jac = 1.0 / det_jacobian;
2441 const unsigned n_node =
nnode();
2444 for (
unsigned p = 0; p < 3; p++)
2447 for (
unsigned q = 0; q < n_node; q++)
2450 for (
unsigned j = 0; j < n_node; j++)
2453 for (
unsigned i = 0;
i < 3;
i++)
2455 d_dpsidx_dX(p, q, j,
i) =
2456 -djacobian_dX(p, q) * (inverse_jacobian(
i, 0) * dpsids(j, 0) +
2457 inverse_jacobian(
i, 1) * dpsids(j, 1) +
2458 inverse_jacobian(
i, 2) * dpsids(j, 2));
2465 d_dpsidx_dX(p, q, j, 1) += ((dpsids(q, 2) * jacobian(1, 2) -
2466 dpsids(q, 1) * jacobian(2, 2)) *
2468 (dpsids(q, 0) * jacobian(2, 2) -
2469 dpsids(q, 2) * jacobian(0, 2)) *
2471 (dpsids(q, 1) * jacobian(0, 2) -
2472 dpsids(q, 0) * jacobian(1, 2)) *
2475 d_dpsidx_dX(p, q, j, 2) += ((dpsids(q, 1) * jacobian(2, 1) -
2476 dpsids(q, 2) * jacobian(1, 1)) *
2478 (dpsids(q, 2) * jacobian(0, 1) -
2479 dpsids(q, 0) * jacobian(2, 1)) *
2481 (dpsids(q, 0) * jacobian(1, 1) -
2482 dpsids(q, 1) * jacobian(0, 1)) *
2488 d_dpsidx_dX(p, q, j, 0) += ((dpsids(q, 1) * jacobian(2, 2) -
2489 dpsids(q, 2) * jacobian(1, 2)) *
2491 (dpsids(q, 2) * jacobian(0, 2) -
2492 dpsids(q, 0) * jacobian(2, 2)) *
2494 (dpsids(q, 0) * jacobian(1, 2) -
2495 dpsids(q, 1) * jacobian(0, 2)) *
2498 d_dpsidx_dX(p, q, j, 2) += ((dpsids(q, 2) * jacobian(1, 0) -
2499 dpsids(q, 1) * jacobian(2, 0)) *
2501 (dpsids(q, 0) * jacobian(2, 0) -
2502 dpsids(q, 2) * jacobian(0, 0)) *
2504 (dpsids(q, 1) * jacobian(0, 0) -
2505 dpsids(q, 0) * jacobian(1, 0)) *
2511 d_dpsidx_dX(p, q, j, 0) += ((dpsids(q, 2) * jacobian(1, 1) -
2512 dpsids(q, 1) * jacobian(2, 1)) *
2514 (dpsids(q, 0) * jacobian(2, 1) -
2515 dpsids(q, 2) * jacobian(0, 1)) *
2517 (dpsids(q, 1) * jacobian(0, 1) -
2518 dpsids(q, 0) * jacobian(1, 1)) *
2521 d_dpsidx_dX(p, q, j, 1) += ((dpsids(q, 1) * jacobian(2, 0) -
2522 dpsids(q, 2) * jacobian(1, 0)) *
2524 (dpsids(q, 2) * jacobian(0, 0) -
2525 dpsids(q, 0) * jacobian(2, 0)) *
2527 (dpsids(q, 0) * jacobian(1, 0) -
2528 dpsids(q, 1) * jacobian(0, 0)) *
2534 for (
unsigned i = 0;
i < 3;
i++)
2536 d_dpsidx_dX(p, q, j,
i) *= inv_det_jac;
2594 const unsigned el_dim =
dim();
2597 const unsigned n_shape =
nnode();
2604 std::ostringstream error_message;
2605 error_message <<
"Dimension mismatch" << std::endl;
2608 <<
" for the jacobian of the mapping to be well-defined"
2611 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
2619 for (
unsigned i = 0;
i < el_dim;
i++)
2622 for (
unsigned j = 0; j < el_dim; j++)
2624 jacobian(
i, j) = 0.0;
2625 inverse_jacobian(
i, j) = 0.0;
2629 for (
unsigned l = 0; l < n_shape; l++)
2632 for (
unsigned k = 0; k < n_shape_type; k++)
2642 for (
unsigned i = 0;
i < el_dim;
i++)
2644 det *= jacobian(
i,
i);
2653 for (
unsigned i = 0;
i < el_dim;
i++)
2655 inverse_jacobian(
i,
i) = 1.0 / jacobian(
i,
i);
2675 const unsigned el_dim =
dim();
2679 const unsigned n_node =
nnode();
2682 if (djacobian_dX.
nrow() != el_dim)
2684 std::ostringstream error_message;
2685 error_message <<
"djacobian_dX must have the same number of rows as the"
2686 <<
"\nspatial dimension of the element.";
2688 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
2691 if (djacobian_dX.
ncol() != n_node)
2693 std::ostringstream error_message;
2695 <<
"djacobian_dX must have the same number of columns as the"
2696 <<
"\nnumber of nodes in the element.";
2698 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
2707 dJ_eulerian_dnodal_coordinates_templated_helper<0>(
2708 jacobian, dpsids, djacobian_dX);
2711 dJ_eulerian_dnodal_coordinates_templated_helper<1>(
2712 jacobian, dpsids, djacobian_dX);
2715 dJ_eulerian_dnodal_coordinates_templated_helper<2>(
2716 jacobian, dpsids, djacobian_dX);
2719 dJ_eulerian_dnodal_coordinates_templated_helper<3>(
2720 jacobian, dpsids, djacobian_dX);
2724 std::ostringstream error_stream;
2725 error_stream <<
"Dimension of the element must be 0,1,2 or 3, not "
2726 << el_dim << std::endl;
2729 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
2750 const double& det_jacobian,
2758 const unsigned el_dim =
dim();
2762 const unsigned n_node =
nnode();
2765 if (d_dpsidx_dX.
nindex1() != el_dim || d_dpsidx_dX.
nindex2() != n_node ||
2766 d_dpsidx_dX.
nindex3() != n_node || d_dpsidx_dX.
nindex4() != el_dim)
2768 std::ostringstream error_message;
2769 error_message <<
"d_dpsidx_dX must be of the following dimensions:"
2770 <<
"\nd_dpsidx_dX(el_dim,n_node,n_node,el_dim)";
2772 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
2781 d_dshape_eulerian_dnodal_coordinates_templated_helper<0>(
2790 d_dshape_eulerian_dnodal_coordinates_templated_helper<1>(
2799 d_dshape_eulerian_dnodal_coordinates_templated_helper<2>(
2808 d_dshape_eulerian_dnodal_coordinates_templated_helper<3>(
2818 std::ostringstream error_stream;
2819 error_stream <<
"Dimension of the element must be 0,1,2 or 3, not "
2820 << el_dim << std::endl;
2823 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
2837 const unsigned n_basis = dbasis.
nindex1();
2838 const unsigned n_basis_type = dbasis.
nindex2();
2840 const unsigned n_dim =
dim();
2843 double new_derivatives[n_dim];
2846 for (
unsigned l = 0; l < n_basis; l++)
2849 for (
unsigned k = 0; k < n_basis_type; k++)
2852 for (
unsigned j = 0; j < n_dim; j++)
2855 new_derivatives[j] = 0.0;
2857 for (
unsigned i = 0;
i < n_dim;
i++)
2859 new_derivatives[j] += inverse_jacobian(j,
i) * dbasis(l, k,
i);
2863 for (
unsigned j = 0; j < n_dim; j++)
2865 dbasis(l, k, j) = new_derivatives[j];
2881 const unsigned n_basis = dbasis.
nindex1();
2882 const unsigned n_basis_type = dbasis.
nindex2();
2884 const unsigned n_dim =
dim();
2887 for (
unsigned l = 0; l < n_basis; l++)
2890 for (
unsigned k = 0; k < n_basis_type; k++)
2893 for (
unsigned j = 0; j < n_dim; j++)
2895 dbasis(l, k, j) *= inverse_jacobian(j, j);
2909 void FiniteElement::transform_second_derivatives_template<1>(
2917 const unsigned n_basis = dbasis.
nindex1();
2918 const unsigned n_basis_type = dbasis.
nindex2();
2922 for (
unsigned l = 0; l < n_basis; l++)
2925 for (
unsigned k = 0; k < n_basis_type; k++)
2928 d2basis(l, k, 0) / (jacobian(0, 0) * jacobian(0, 0))
2930 - dbasis(l, k, 0) * jacobian2(0, 0) /
2931 (jacobian(0, 0) * jacobian(0, 0) * jacobian(0, 0));
2948 void FiniteElement::transform_second_derivatives_template<2>(
2956 const unsigned n_basis = dbasis.
nindex1();
2957 const unsigned n_basis_type = dbasis.
nindex2();
2961 jacobian(0, 0) * jacobian(1, 1) - jacobian(0, 1) * jacobian(1, 0);
2970 jacobian2(0, 0) * jacobian(1, 1) + jacobian(0, 0) * jacobian2(2, 1) -
2971 jacobian2(0, 1) * jacobian(1, 0) - jacobian(0, 1) * jacobian2(2, 0);
2973 jacobian2(2, 0) * jacobian(1, 1) + jacobian(0, 0) * jacobian2(1, 1) -
2974 jacobian2(2, 1) * jacobian(1, 0) - jacobian(0, 1) * jacobian2(1, 0);
2978 double dinverse_jacobiands[2][2][2];
2980 dinverse_jacobiands[0][0][0] =
2981 jacobian2(2, 1) / det - jacobian(1, 1) * ddetds[0] / (det * det);
2982 dinverse_jacobiands[0][1][0] =
2983 -jacobian2(0, 1) / det + jacobian(0, 1) * ddetds[0] / (det * det);
2984 dinverse_jacobiands[1][0][0] =
2985 -jacobian2(2, 0) / det + jacobian(1, 0) * ddetds[0] / (det * det);
2986 dinverse_jacobiands[1][1][0] =
2987 jacobian2(0, 0) / det - jacobian(0, 0) * ddetds[0] / (det * det);
2989 dinverse_jacobiands[0][0][1] =
2990 jacobian2(1, 1) / det - jacobian(1, 1) * ddetds[1] / (det * det);
2991 dinverse_jacobiands[0][1][1] =
2992 -jacobian2(2, 1) / det + jacobian(0, 1) * ddetds[1] / (det * det);
2993 dinverse_jacobiands[1][0][1] =
2994 -jacobian2(1, 0) / det + jacobian(1, 0) * ddetds[1] / (det * det);
2995 dinverse_jacobiands[1][1][1] =
2996 jacobian2(2, 0) / det - jacobian(0, 0) * ddetds[1] / (det * det);
2999 DShape dphidXds0(n_basis, n_basis_type, 2),
3000 dphidXds1(n_basis, n_basis_type, 2);
3002 for (
unsigned l = 0; l < n_basis; l++)
3004 for (
unsigned k = 0; k < n_basis_type; k++)
3006 for (
unsigned j = 0; j < 2; j++)
3010 dphidXds0(l, k, j) = dinverse_jacobiands[j][0][0] * dbasis(l, k, 0) +
3011 dinverse_jacobiands[j][1][0] * dbasis(l, k, 1) +
3012 inverse_jacobian(j, 0) * d2basis(l, k, 0) +
3013 inverse_jacobian(j, 1) * d2basis(l, k, 2);
3015 dphidXds1(l, k, j) = dinverse_jacobiands[j][0][1] * dbasis(l, k, 0) +
3016 dinverse_jacobiands[j][1][1] * dbasis(l, k, 1) +
3017 inverse_jacobian(j, 0) * d2basis(l, k, 2) +
3018 inverse_jacobian(j, 1) * d2basis(l, k, 1);
3024 for (
unsigned l = 0; l < n_basis; l++)
3026 for (
unsigned k = 0; k < n_basis_type; k++)
3029 for (
unsigned j = 0; j < 3; j++)
3031 d2basis(l, k, j) = 0.0;
3035 for (
unsigned i = 0;
i < 2;
i++)
3037 d2basis(l, k,
i) = inverse_jacobian(
i, 0) * dphidXds0(l, k,
i) +
3038 inverse_jacobian(
i, 1) * dphidXds1(l, k,
i);
3041 d2basis(l, k, 2) += inverse_jacobian(0, 0) * dphidXds0(l, k, 1) +
3042 inverse_jacobian(0, 1) * dphidXds1(l, k, 1);
3060 void FiniteElement::transform_second_derivatives_diagonal<1>(
3067 FiniteElement::transform_second_derivatives_template<1>(
3068 jacobian, inverse_jacobian, jacobian2, dbasis, d2basis);
3078 void FiniteElement::transform_second_derivatives_diagonal<2>(
3086 const unsigned n_basis = dbasis.
nindex1();
3087 const unsigned n_basis_type = dbasis.
nindex2();
3093 for (
unsigned l = 0; l < n_basis; l++)
3095 for (
unsigned k = 0; k < n_basis_type; k++)
3099 d2basis(l, k, 0) / (jacobian(0, 0) * jacobian(0, 0)) -
3100 dbasis(l, k, 0) * jacobian2(0, 0) /
3101 (jacobian(0, 0) * jacobian(0, 0) * jacobian(0, 0));
3104 d2basis(l, k, 1) / (jacobian(1, 1) * jacobian(1, 1)) -
3105 dbasis(l, k, 1) * jacobian2(1, 1) /
3106 (jacobian(1, 1) * jacobian(1, 1) * jacobian(1, 1));
3108 d2basis(l, k, 2) = d2basis(l, k, 2) / (jacobian(0, 0) * jacobian(1, 1));
3133 const unsigned el_dim =
dim();
3138 transform_second_derivatives_template<1>(
3139 jacobian, inverse_jacobian, jacobian2, dbasis, d2basis);
3142 transform_second_derivatives_template<2>(
3143 jacobian, inverse_jacobian, jacobian2, dbasis, d2basis);
3147 throw OomphLibError(
"Not implemented yet ... maybe one day",
3148 OOMPH_CURRENT_FUNCTION,
3149 OOMPH_EXCEPTION_LOCATION);
3157 std::ostringstream error_stream;
3158 error_stream <<
"Dimension of the element must be 1,2 or 3, not "
3159 << el_dim << std::endl;
3162 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
3197 unsigned n_coordinates = s_fraction.size();
3198 for (
unsigned i = 0;
i < n_coordinates;
i++)
3223 const unsigned el_dim =
dim();
3227 for (
unsigned i = 0;
i < el_dim;
i++)
3244 const unsigned el_dim =
dim();
3248 for (
unsigned i = 0;
i < el_dim;
i++)
3280 const unsigned el_dim =
dim();
3284 for (
unsigned i = 0;
i < el_dim;
i++)
3303 const unsigned el_dim =
dim();
3330 const unsigned el_dim =
dim();
3358 const unsigned el_dim =
dim();
3361 unsigned nnod =
nnode();
3362 DShape dpsi(nnod, el_dim);
3391 const unsigned& ipt,
3398 const unsigned el_dim =
dim();
3419 det, jacobian, djacobian_dX, inverse_jacobian, dpsi, d_dpsidx_dX);
3456 const unsigned el_dim =
dim();
3458 const unsigned n_deriv =
N2deriv[el_dim];
3476 jacobian, inverse_jacobian, jacobian2, dpsi, d2psi);
3510 const unsigned el_dim =
dim();
3512 const unsigned n_deriv =
N2deriv[el_dim];
3530 jacobian, inverse_jacobian, jacobian2, dpsi, d2psi);
3545 const bool& store_local_dof_pt)
3548 const unsigned n_node =
nnode();
3559 for (
unsigned n = 1; n < n_node; n++)
3573 if (n_total_values == 0)
3585 for (
unsigned i = 0;
i < n_total_values;
i++)
3591 for (
unsigned n = 1; n < n_node; ++n)
3603 std::deque<unsigned long> global_eqn_number_queue;
3606 for (
unsigned n = 0; n < n_node; n++)
3612 unsigned n_value = nod_pt->
nvalue();
3615 for (
unsigned j = 0; j < n_value; j++)
3623 global_eqn_number_queue.push_back(
eqn_number);
3625 if (store_local_dof_pt)
3646 if (store_local_dof_pt)
3664 const unsigned n_node =
nnode();
3676 const unsigned n_dof =
ndof();
3681 int local_unknown = 0;
3687 for (
unsigned n = 0; n < n_node; n++)
3693 for (
unsigned i = 0;
i < n_value;
i++)
3698 if (local_unknown >= 0)
3704 const double old_var = *value_pt;
3707 *value_pt += fd_step;
3716 for (
unsigned m = 0; m < n_dof; m++)
3718 double sum = (newres[m] - residuals[m]) / fd_step;
3720 jacobian(m, local_unknown) = sum;
3724 *value_pt = old_var;
3748 unsigned n_nod =
nnode();
3751 if (n_nod == 0)
return;
3757 unsigned n_dof =
ndof();
3768 for (
unsigned j = 0; j < n_nod; j++)
3774 for (
unsigned i = 0;
i < dim_nod;
i++)
3777 double backup = nod_pt->
x(
i);
3781 nod_pt->
x(
i) += eps_fd;
3793 for (
unsigned l = 0; l < n_dof; l++)
3795 dresidual_dnodal_coordinates(l,
i, j) =
3796 (res_pls[l] - res[l]) / eps_fd;
3801 nod_pt->
x(
i) = backup;
3819 unsigned n_node =
nnode();
3825 std::vector<int> local_node_number;
3827 for (
unsigned i = 0;
i < n_node;
i++)
3834 local_node_number.push_back(
i);
3841 std::ostringstream error_stream;
3842 error_stream <<
"Node " << global_node_pt <<
" appears " << count
3843 <<
" times in an element." << std::endl
3844 <<
"In positions: ";
3845 for (std::vector<int>::iterator it = local_node_number.begin();
3846 it != local_node_number.end();
3849 error_stream << *it <<
" ";
3851 error_stream << std::endl <<
"That seems very odd." << std::endl;
3854 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
3860 for (
unsigned i = 0;
i < n_node;
i++)
3890 const unsigned n_node =
Nnode;
3892 for (
unsigned n = 0; n < n_node; n++)
3897 for (
unsigned i = 0;
i < el_dim;
i++)
3902 if (std::fabs(
s[
i] - s_node[
i]) > tol)
3932 unsigned nnod =
nnode();
3933 for (
unsigned j = 0; j < nnod; j++)
3942 cog[
i] /= double(nnod);
3946 for (
unsigned j = 0; j < nnod; j++)
3948 double dist_squared = 0.0;
3954 if (dist_squared > max_radius) max_radius = dist_squared;
3956 max_radius = sqrt(max_radius);
3963 const unsigned&
i)
const
3966 const unsigned n_node =
nnode();
3970 Shape psi(n_node, n_position_type);
3977 for (
unsigned l = 0; l < n_node; l++)
3980 for (
unsigned k = 0; k < n_position_type; k++)
3995 const unsigned&
i)
const
3998 const unsigned n_node =
nnode();
4003 Shape psi(n_node, n_position_type);
4010 for (
unsigned l = 0; l < n_node; l++)
4013 for (
unsigned k = 0; k < n_position_type; k++)
4029 const unsigned n_node =
nnode();
4036 Shape psi(n_node, n_position_type);
4041 for (
unsigned i = 0;
i < nodal_dim;
i++)
4046 for (
unsigned l = 0; l < n_node; l++)
4049 for (
unsigned k = 0; k < n_position_type; k++)
4066 const unsigned n_node =
nnode();
4073 Shape psi(n_node, n_position_type);
4078 for (
unsigned i = 0;
i < nodal_dim;
i++)
4083 for (
unsigned l = 0; l < n_node; l++)
4086 for (
unsigned k = 0; k < n_position_type; k++)
4106 const unsigned n_node =
nnode();
4110 const unsigned n_dim_element =
dim();
4113 Shape psi(n_node, n_position_type);
4114 DShape dpsids(n_node, n_position_type, n_dim_element);
4124 for (
unsigned i = 0;
i < n_dim_element;
i++)
4126 for (
unsigned j = 0; j < n_dim_element; j++)
4128 for (
unsigned k = 0; k < n_dim_node; k++)
4130 G(
i, j) += interpolated_G(
i, k) * interpolated_G(j, k);
4137 switch (n_dim_element)
4140 throw OomphLibError(
"Cannot calculate J_eulerian() for point element\n",
4141 OOMPH_CURRENT_FUNCTION,
4142 OOMPH_EXCEPTION_LOCATION);
4148 det = G(0, 0) * G(1, 1) - G(0, 1) * G(1, 0);
4151 det = G(0, 0) * G(1, 1) * G(2, 2) + G(0, 1) * G(1, 2) * G(2, 0) +
4152 G(0, 2) * G(1, 0) * G(2, 1) - G(0, 0) * G(1, 2) * G(2, 1) -
4153 G(0, 1) * G(1, 0) * G(2, 2) - G(0, 2) * G(1, 1) * G(2, 0);
4156 oomph_info <<
"More than 3 dimensions in J_eulerian()" << std::endl;
4171 const unsigned n_node =
nnode();
4176 const unsigned n_dim_element =
dim();
4179 Shape psi(n_node, n_position_type);
4180 DShape dpsids(n_node, n_position_type, n_dim_element);
4193 for (
unsigned i = 0;
i < n_dim_element;
i++)
4195 for (
unsigned j = 0; j < n_dim_element; j++)
4197 for (
unsigned k = 0; k < n_dim_node; k++)
4199 G(
i, j) += interpolated_G(
i, k) * interpolated_G(j, k);
4206 switch (n_dim_element)
4209 throw OomphLibError(
"Cannot calculate J_eulerian() for point element\n",
4210 OOMPH_CURRENT_FUNCTION,
4211 OOMPH_EXCEPTION_LOCATION);
4217 det = G(0, 0) * G(1, 1) - G(0, 1) * G(1, 0);
4220 det = G(0, 0) * G(1, 1) * G(2, 2) + G(0, 1) * G(1, 2) * G(2, 0) +
4221 G(0, 2) * G(1, 0) * G(2, 1) - G(0, 0) * G(1, 2) * G(2, 1) -
4222 G(0, 1) * G(1, 0) * G(2, 2) - G(0, 2) * G(1, 1) * G(2, 0);
4225 oomph_info <<
"More than 3 dimensions in J_eulerian()" << std::endl;
4247 const unsigned n_node =
nnode();
4256 const unsigned n_dim_element =
dim();
4259 Shape psi(n_node, n_position_type);
4260 DShape dpsi(n_node, n_dim_element);
4263 for (
unsigned ipt = 0; ipt < nintpt; ipt++)
4297 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
4321 const unsigned ncomponents = integral.size();
4323 for (
unsigned i = 0;
i < ncomponents;
i++)
4339 const unsigned n_dim =
dim();
4343 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
4346 for (
unsigned i = 0;
i < n_dim;
i++)
4352 for (
unsigned i = 0;
i < n_dim_eulerian;
i++)
4364 integrand_fct_pt(time, x, integrand);
4367 for (
unsigned i = 0;
i < ncomponents;
i++)
4369 integral[
i] += integrand[
i] * w * J;
4382 const unsigned ncomponents = integral.size();
4384 for (
unsigned i = 0;
i < ncomponents;
i++)
4400 const unsigned n_dim =
dim();
4404 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
4407 for (
unsigned i = 0;
i < n_dim;
i++)
4413 for (
unsigned i = 0;
i < n_dim_eulerian;
i++)
4425 integrand_fct_pt(x, integrand);
4428 for (
unsigned i = 0;
i < ncomponents;
i++)
4430 integral[
i] += integrand[
i] * w * J;
4455 OomphLibWarning(
"Pointer to spatial integration scheme has not been set.",
4456 "FiniteElement::self_test()",
4457 OOMPH_EXCEPTION_LOCATION);
4462 const unsigned dim_el =
dim();
4476 const unsigned n_node =
nnode();
4479 Shape psi(n_node, n_position_type);
4480 DShape dpsidx(n_node, dim_el);
4493 if (face_el_pt == 0)
4503 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
4506 for (
unsigned i = 0;
i < dim_el;
i++)
4513 for (
unsigned test = 0; test < ntest; test++)
4537 OOMPH_CURRENT_FUNCTION,
4538 OOMPH_EXCEPTION_LOCATION);
4543 if (std::fabs(jacobian) < 1.0e-16)
4545 std::ostringstream warning_stream;
4546 warning_stream <<
"Determinant of Jacobian matrix is zero at ipt "
4547 << ipt << std::endl;
4549 "FiniteElement::self_test()",
4550 OOMPH_EXCEPTION_LOCATION);
4559 std::ostringstream warning_stream;
4560 warning_stream <<
"Jacobian negative at integration point ipt="
4561 << ipt << std::endl;
4563 <<
"If you think that this is what you want you may: "
4565 <<
"set the (static) flag "
4566 <<
"FiniteElement::Accept_negative_jacobian to be true"
4570 "FiniteElement::self_test()",
4571 OOMPH_EXCEPTION_LOCATION);
4598 const unsigned& t_deriv)
4601 const unsigned n_node =
nnode();
4604 Shape psi(n_node, n_position_type);
4612 for (
unsigned l = 0; l < n_node; l++)
4615 for (
unsigned k = 0; k < n_position_type; k++)
4630 const unsigned& t_deriv,
4634 const unsigned n_node =
nnode();
4639 Shape psi(n_node, n_position_type);
4643 for (
unsigned i = 0;
i < nodal_dim;
i++)
4650 for (
unsigned l = 0; l < n_node; l++)
4653 for (
unsigned k = 0; k < n_position_type; k++)
4687 const unsigned n_node = this->
nnode();
4691 Shape psi(n_node, n_position_type);
4693 this->
shape(s, psi);
4696 const unsigned ncoord = this->
dim();
4698 for (
unsigned i = 0;
i < ncoord;
i++)
4705 for (
unsigned l = 0; l < n_node; l++)
4707 for (
unsigned k = 0; k < n_position_type; k++)
4710 const double psi_ = psi(l, k);
4711 for (
unsigned i = 0;
i < ncoord;
i++)
4737 const bool& use_coordinate_as_initial_guess)
4741 unsigned ncoord = this->
dim();
4749 double max_radius = 0.0;
4753 double radius = 0.0;
4754 for (
unsigned i = 0;
i < ncoord;
i++)
4756 radius += (cog[
i] - zeta[
i]) * (cog[
i] - zeta[
i]);
4758 radius = sqrt(radius);
4759 if (radius > Locate_zeta_helpers::
4782 if (!use_coordinate_as_initial_guess)
4788 unsigned num_plot_points =
4790 for (
unsigned iplot = 0; iplot < num_plot_points; iplot++)
4794 s_list.push_back(s_c);
4802 bool keep_going =
true;
4808 if (use_coordinate_as_initial_guess)
4814 for (
unsigned i = 0;
i < ncoord;
i++)
4816 dx[
i] = zeta[
i] - inter_x[
i];
4822 double my_min_resid = DBL_MAX;
4827 unsigned n_list_coord = s_list.size();
4829 for (
unsigned i_coord = 0; i_coord < n_list_coord; i_coord++)
4831 for (
unsigned i = 0;
i < ncoord;
i++)
4833 s_local[
i] = s_list[i_coord][
i];
4839 for (
unsigned i = 0;
i < ncoord;
i++)
4841 work_dx[
i] = zeta[
i] - work_x[
i];
4844 double maxres = std::fabs(
4845 *std::max_element(work_dx.begin(), work_dx.end(),
AbsCmp<double>()));
4848 if (maxres < my_min_resid)
4850 my_min_resid = maxres;
4875 std::fabs(*std::max_element(dx.begin(), dx.end(),
AbsCmp<double>()));
4899 for (
unsigned i = 0;
i < ncoord;
i++)
4902 work_s[
i] += fd_step;
4908 for (
unsigned j = 0; j < ncoord; j++)
4910 jacobian(j,
i) = -(work_r[j] - r[j]) / fd_step;
4920 unsigned n_node = this->
nnode();
4922 Shape psi(n_node, n_position_type);
4923 DShape dpsids(n_node, n_position_type, ncoord);
4952 for (
unsigned l = 0; l < n_node; l++)
4956 for (
unsigned k = 0; k < n_position_type; k++)
4959 for (
unsigned i = 0;
i < ncoord;
i++)
4961 for (
unsigned j = 0; j < ncoord; j++)
4963 interpolated_dxds(
i, j) +=
4972 for (
unsigned i = 0;
i < ncoord;
i++)
4974 for (
unsigned j = 0; j < ncoord; j++)
4976 jacobian(
i, j) = -interpolated_dxds(
i, j);
4992 <<
"FiniteElement::locate_zeta()" << std::endl;
4993 oomph_info <<
"Should not affect the result!" << std::endl;
4998 for (
unsigned i = 0;
i < ncoord;
i++)
5005 for (
unsigned i = 0;
i < ncoord;
i++)
5007 dx[
i] = zeta[
i] - inter_x[
i];
5012 std::fabs(*std::max_element(dx.begin(), dx.end(),
AbsCmp<double>()));
5020 }
while (keep_going);
5033 for (
unsigned i = 0;
i < ncoord;
i++)
5035 dx[
i] = zeta[
i] - inter_x[
i];
5040 std::fabs(*std::max_element(dx.begin(), dx.end(),
AbsCmp<double>()));
5064 geom_object_pt =
this;
5074 const unsigned n_node =
nnode();
5075 for (
unsigned n = 0; n < n_node; n++)
5097 std::set<std::pair<Data*, unsigned>>& paired_field_data)
5101 for (
unsigned n = 0; n < n_internal; n++)
5106 const unsigned n_value = dat_pt->
nvalue();
5109 for (
unsigned i = 0;
i < n_value;
i++)
5111 paired_field_data.insert(std::make_pair(dat_pt,
i));
5116 const unsigned n_node = this->
nnode();
5117 for (
unsigned n = 0; n < n_node; n++)
5122 const unsigned n_value = nod_pt->
nvalue();
5125 for (
unsigned i = 0;
i < n_value;
i++)
5127 paired_field_data.insert(std::make_pair(nod_pt,
i));
5141 #ifdef OOMPH_HAS_MPI
5171 for (
unsigned i = 0;
i < nnode_face;
i++)
5203 unsigned n_dim =
dim();
5211 for (
unsigned iplot = 0; iplot < num_plot_points; iplot++)
5217 for (
unsigned i = 0;
i < n_dim + 1;
i++)
5225 for (
unsigned i = 0;
i < n_dim;
i++)
5227 outfile << zeta[
i] <<
" ";
5229 outfile << std::endl;
5245 unsigned n_dim_el = this->
dim();
5249 if (n_dim_el == 0)
return 1.0;
5252 unsigned n_node =
nnode();
5261 Shape psi(n_node, n_position_type);
5262 DShape dpsids(n_node, n_position_type, n_dim_el);
5271 for (
unsigned l = 0; l < n_node; l++)
5274 for (
unsigned k = 0; k < n_position_type; k++)
5277 for (
unsigned i = 0;
i < n_dim;
i++)
5280 for (
unsigned j = 0; j < n_dim_el; j++)
5282 interpolated_A(j,
i) +=
5290 for (
unsigned i = 0;
i < n_dim_el;
i++)
5292 for (
unsigned j = 0; j < n_dim_el; j++)
5295 for (
unsigned k = 0; k < n_dim; k++)
5297 A(
i, j) += interpolated_A(
i, k) * interpolated_A(j, k);
5310 Adet = A(0, 0) * A(1, 1) - A(0, 1) * A(1, 0);
5314 "FaceElement::J_eulerian()",
5315 OOMPH_EXCEPTION_LOCATION);
5331 const unsigned n_node =
nnode();
5338 const unsigned n_dim_el =
dim();
5341 Shape psi(n_node, n_position_type);
5342 DShape dpsids(n_node, n_position_type, n_dim_el);
5354 for (
unsigned l = 0; l < n_node; l++)
5357 for (
unsigned k = 0; k < n_position_type; k++)
5360 for (
unsigned i = 0;
i < n_dim;
i++)
5363 for (
unsigned j = 0; j < n_dim_el; j++)
5365 interpolated_A(j,
i) +=
5374 for (
unsigned i = 0;
i < n_dim_el;
i++)
5376 for (
unsigned j = 0; j < n_dim_el; j++)
5379 for (
unsigned k = 0; k < n_dim; k++)
5381 A(
i, j) += interpolated_A(
i, k) * interpolated_A(j, k);
5394 Adet = A(0, 0) * A(1, 1) - A(0, 1) * A(1, 0);
5398 "FaceElement::J_eulerian_at_knot()",
5399 OOMPH_EXCEPTION_LOCATION);
5416 const unsigned n_node =
nnode();
5423 const unsigned n_dim_el =
dim();
5426 Shape psi(n_node, n_position_type);
5427 DShape dpsids(n_node, n_position_type, n_dim_el);
5431 for (
unsigned ipt = 0; ipt < nintpt; ipt++)
5443 for (
unsigned l = 0; l < n_node; l++)
5446 for (
unsigned k = 0; k < n_position_type; k++)
5449 for (
unsigned i = 0;
i < n_dim;
i++)
5453 for (
unsigned j = 0; j < n_dim_el; j++)
5455 interpolated_A(j,
i) +=
5465 for (
unsigned i = 0;
i < n_dim_el;
i++)
5467 for (
unsigned j = 0; j < n_dim_el; j++)
5470 for (
unsigned k = 0; k < n_dim; k++)
5472 A(
i, j) += interpolated_A(
i, k) * interpolated_A(j, k);
5485 Adet = A(0, 0) * A(1, 1) - A(0, 1) * A(1, 0);
5489 "FaceElement::J_eulerian_at_knot()",
5490 OOMPH_EXCEPTION_LOCATION);
5518 const unsigned element_dim =
dim();
5526 if (
s.size() != element_dim)
5528 std::ostringstream error_stream;
5530 <<
"Local coordinate s passed to outer_unit_normal() has dimension "
5531 <<
s.size() << std::endl
5532 <<
"but element dimension is " << element_dim << std::endl;
5535 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
5543 std::ostringstream error_stream;
5544 error_stream <<
"Tangent direction vector has dimension "
5546 <<
"but spatial dimension is " << spatial_dim << std::endl;
5549 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
5553 if (unit_normal.size() != spatial_dim)
5555 std::ostringstream error_stream;
5556 error_stream <<
"Unit normal passed to outer_unit_normal() has dimension "
5557 << unit_normal.size() << std::endl
5558 <<
"but spatial dimension is " << spatial_dim << std::endl;
5561 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
5566 unsigned ntangent_vec = tang_vec.size();
5572 switch (element_dim)
5578 if (ntangent_vec != 1)
5580 std::ostringstream error_stream;
5582 <<
"This is a 0D FaceElement, we need one tangent vector.\n"
5583 <<
"You have given me " << tang_vec.size() <<
" vector(s).\n";
5585 OOMPH_CURRENT_FUNCTION,
5586 OOMPH_EXCEPTION_LOCATION);
5595 if (ntangent_vec != 1)
5597 std::ostringstream error_stream;
5599 <<
"This is a 1D FaceElement, we need one tangent vector.\n"
5600 <<
"You have given me " << tang_vec.size() <<
" vector(s).\n";
5602 OOMPH_CURRENT_FUNCTION,
5603 OOMPH_EXCEPTION_LOCATION);
5612 if (ntangent_vec != 2)
5614 std::ostringstream error_stream;
5616 <<
"This is a 2D FaceElement, we need two tangent vectors.\n"
5617 <<
"You have given me " << tang_vec.size() <<
" vector(s).\n";
5619 OOMPH_CURRENT_FUNCTION,
5620 OOMPH_EXCEPTION_LOCATION);
5628 "Cannot have a FaceElement with dimension higher than 2",
5629 OOMPH_CURRENT_FUNCTION,
5630 OOMPH_EXCEPTION_LOCATION);
5635 for (
unsigned vec_i = 0; vec_i < ntangent_vec; vec_i++)
5637 if (tang_vec[vec_i].
size() != spatial_dim)
5639 std::ostringstream error_stream;
5640 error_stream <<
"This problem has " << spatial_dim
5641 <<
" spatial dimensions.\n"
5642 <<
"But the " << vec_i <<
" tangent vector has size "
5643 << tang_vec[vec_i].size() << std::endl;
5645 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
5653 switch (element_dim)
5658 std::ostringstream error_stream;
5660 <<
"It is unclear how to calculate a tangent and normal vectors for "
5661 <<
"a point element.\n";
5663 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
5676 const unsigned n_position_type_bulk =
5686 Shape psi(n_node_bulk, n_position_type_bulk);
5687 DShape dpsids(n_node_bulk, n_position_type_bulk, 2);
5696 for (
unsigned l = 0; l < n_node_bulk; l++)
5699 for (
unsigned k = 0; k < n_position_type_bulk; k++)
5702 for (
unsigned j = 0; j < 2; j++)
5705 for (
unsigned i = 0;
i < spatial_dim;
i++)
5708 interpolated_dxds(j,
i) +=
5728 unsigned interior_direction = 0;
5731 for (
unsigned i = 0;
i < spatial_dim;
i++)
5735 tangent[
i] = interpolated_dxds(0,
i) * dsbulk_dsface(0, 0) +
5736 interpolated_dxds(1,
i) * dsbulk_dsface(1, 0);
5739 interior_tangent[
i] = interpolated_dxds(interior_direction,
i);
5753 for (
unsigned i = 0;
i < spatial_dim;
i++)
5755 unit_normal[
i] = full_normal[
i];
5760 for (
unsigned i = 0;
i < spatial_dim;
i++)
5766 tang_vec[0][0] = -unit_normal[1];
5767 tang_vec[0][1] = unit_normal[0];
5781 if (spatial_dim != 3)
5783 std::ostringstream error_stream;
5784 error_stream <<
"There are only " << spatial_dim
5785 <<
"coordinates at the nodes of this 2D FaceElement,\n"
5786 <<
"which must have come from a 3D Bulk element\n";
5788 OOMPH_CURRENT_FUNCTION,
5789 OOMPH_EXCEPTION_LOCATION);
5794 const unsigned n_node = this->
nnode();
5800 Shape psi(n_node, n_position_type);
5801 DShape dpsids(n_node, n_position_type, 2);
5810 for (
unsigned l = 0; l < n_node; l++)
5813 for (
unsigned k = 0; k < n_position_type; k++)
5816 for (
unsigned j = 0; j < 2; j++)
5819 for (
unsigned i = 0;
i < 3;
i++)
5824 interpolated_dxds[j][
i] +=
5834 interpolated_dxds[0], interpolated_dxds[1], unit_normal);
5839 for (
unsigned i = 0;
i < spatial_dim;
i++)
5864 std::ostringstream err_stream;
5865 err_stream <<
"The angle between the unit normal and the \n"
5866 <<
"direction vector is less than 10 degrees.";
5868 OOMPH_CURRENT_FUNCTION,
5869 OOMPH_EXCEPTION_LOCATION);
5883 tang_vec[0][0] = t1_scaling * interpolated_dxds[0][0] +
5884 t2_scaling * interpolated_dxds[1][0];
5885 tang_vec[0][1] = t1_scaling * interpolated_dxds[0][1] +
5886 t2_scaling * interpolated_dxds[1][1];
5887 tang_vec[0][2] = t1_scaling * interpolated_dxds[0][2] +
5888 t2_scaling * interpolated_dxds[1][2];
5895 for (
unsigned vec_i = 0; vec_i < 2; vec_i++)
5900 for (
unsigned dim_i = 0; dim_i < spatial_dim; dim_i++)
5902 tang_vec[vec_i][dim_i] /= tang_length;
5919 if (a != 0.0 || b != 0.0)
5921 double a_sq = a * a;
5922 double b_sq = b * b;
5923 double c_sq = c * c;
5925 tang_vec[0][0] = -b / sqrt(a_sq + b_sq);
5926 tang_vec[0][1] = a / sqrt(a_sq + b_sq);
5929 double z = (a_sq + b_sq) / sqrt(a_sq * c_sq + b_sq * c_sq +
5930 (a_sq + b_sq) * (a_sq + b_sq));
5932 tang_vec[1][0] = -(a * c * z) / (a_sq + b_sq);
5933 tang_vec[1][1] = -(b * c * z) / (a_sq + b_sq);
5942 std::ostringstream warn_stream;
5944 <<
"I have detected that your normal vector is [0,0,1].\n"
5945 <<
"Since this function compares against 0.0, you may\n"
5946 <<
"get discontinuous tangent vectors.";
5948 OOMPH_CURRENT_FUNCTION,
5949 OOMPH_EXCEPTION_LOCATION);
5952 tang_vec[0][0] = 1.0;
5953 tang_vec[0][1] = 0.0;
5954 tang_vec[0][2] = 0.0;
5956 tang_vec[1][0] = 0.0;
5957 tang_vec[1][1] = 1.0;
5958 tang_vec[1][2] = 0.0;
5963 OOMPH_CURRENT_FUNCTION,
5964 OOMPH_EXCEPTION_LOCATION);
5973 "Cannot have a FaceElement with dimension higher than 2",
5974 OOMPH_CURRENT_FUNCTION,
5975 OOMPH_EXCEPTION_LOCATION);
5987 const unsigned& ipt,
5992 const unsigned element_dim =
dim();
5995 for (
unsigned i = 0;
i < element_dim;
i++)
6010 const unsigned element_dim =
dim();
6018 if (
s.size() != element_dim)
6020 std::ostringstream error_stream;
6022 <<
"Local coordinate s passed to outer_unit_normal() has dimension "
6023 <<
s.size() << std::endl
6024 <<
"but element dimension is " << element_dim << std::endl;
6027 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
6031 if (unit_normal.size() != spatial_dim)
6033 std::ostringstream error_stream;
6034 error_stream <<
"Unit normal passed to outer_unit_normal() has dimension "
6035 << unit_normal.size() << std::endl
6036 <<
"but spatial dimension is " << spatial_dim << std::endl;
6039 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
6096 switch (element_dim)
6108 const unsigned n_position_type_bulk =
6119 Shape psi(n_node_bulk, n_position_type_bulk);
6120 DShape dpsids(n_node_bulk, n_position_type_bulk, 1);
6129 for (
unsigned l = 0; l < n_node_bulk; l++)
6132 for (
unsigned k = 0; k < n_position_type_bulk; k++)
6135 for (
unsigned i = 0;
i < spatial_dim;
i++)
6138 interpolated_dxds(0,
i) +=
6146 for (
unsigned i = 0;
i < spatial_dim;
i++)
6148 unit_normal[
i] = interpolated_dxds(0,
i);
6162 const unsigned n_position_type_bulk =
6172 Shape psi(n_node_bulk, n_position_type_bulk);
6173 DShape dpsids(n_node_bulk, n_position_type_bulk, 2);
6182 for (
unsigned l = 0; l < n_node_bulk; l++)
6185 for (
unsigned k = 0; k < n_position_type_bulk; k++)
6188 for (
unsigned j = 0; j < 2; j++)
6191 for (
unsigned i = 0;
i < spatial_dim;
i++)
6194 interpolated_dxds(j,
i) +=
6214 unsigned interior_direction = 0;
6217 for (
unsigned i = 0;
i < spatial_dim;
i++)
6221 tangent[
i] = interpolated_dxds(0,
i) * dsbulk_dsface(0, 0) +
6222 interpolated_dxds(1,
i) * dsbulk_dsface(1, 0);
6225 interior_tangent[
i] = interpolated_dxds(interior_direction,
i);
6239 for (
unsigned i = 0;
i < spatial_dim;
i++)
6241 unit_normal[
i] = full_normal[
i];
6256 if (spatial_dim != 3)
6258 std::ostringstream error_stream;
6259 error_stream <<
"There are only " << spatial_dim
6260 <<
"coordinates at the nodes of this 2D FaceElement,\n"
6261 <<
"which must have come from a 3D Bulk element\n";
6263 OOMPH_CURRENT_FUNCTION,
6264 OOMPH_EXCEPTION_LOCATION);
6269 const unsigned n_node = this->
nnode();
6275 Shape psi(n_node, n_position_type);
6276 DShape dpsids(n_node, n_position_type, 2);
6285 for (
unsigned l = 0; l < n_node; l++)
6288 for (
unsigned k = 0; k < n_position_type; k++)
6291 for (
unsigned j = 0; j < 2; j++)
6294 for (
unsigned i = 0;
i < 3;
i++)
6299 interpolated_dxds[j][
i] +=
6309 interpolated_dxds[0], interpolated_dxds[1], unit_normal);
6316 "Cannot have a FaceElement with dimension higher than 2",
6317 OOMPH_CURRENT_FUNCTION,
6318 OOMPH_EXCEPTION_LOCATION);
6324 for (
unsigned i = 0;
i < spatial_dim;
i++)
6337 const unsigned element_dim =
dim();
6340 for (
unsigned i = 0;
i < element_dim;
i++)
6366 (*Face_to_bulk_coordinate_fct_pt)(
s, s_bulk);
6370 throw OomphLibError(
"Face_to_bulk_coordinate mapping not set",
6371 OOMPH_CURRENT_FUNCTION,
6372 OOMPH_EXCEPTION_LOCATION);
6391 (*Face_to_bulk_coordinate_fct_pt)(
s, s_bulk);
6396 throw OomphLibError(
"Face_to_bulk_coordinate mapping not set",
6397 OOMPH_CURRENT_FUNCTION,
6398 OOMPH_EXCEPTION_LOCATION);
6411 unsigned& interior_direction)
const
6417 (*Bulk_coordinate_derivatives_fct_pt)(
6418 s, dsbulk_dsface, interior_direction);
6424 "No function for derivatives of bulk coords wrt face coords set",
6425 OOMPH_CURRENT_FUNCTION,
6426 OOMPH_EXCEPTION_LOCATION);
6447 unsigned n_dim =
dim();
6459 unsigned n_node = this->
nnode();
6468 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
6471 for (
unsigned i = 0;
i < n_dim;
i++)
6490 for (
unsigned idim = 0; idim < n_dim; idim++)
6492 disp[idim] = x[idim] - xi[idim];
6496 for (
unsigned ii = 0; ii < n_dim; ii++)
6498 el_norm += (disp[ii] * disp[ii]) *
W;
6515 std::ostream& out,
const std::string& current_string)
const
6532 const unsigned el_dim =
dim();
6536 const unsigned n_shape =
nnode();
6543 std::ostringstream error_message;
6544 error_message <<
"Dimension mismatch" << std::endl;
6545 error_message <<
"The elemental dimension: " << el_dim
6546 <<
" must equal the nodal Lagrangian dimension: "
6548 <<
" for the jacobian of the mapping to be well-defined"
6551 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
6556 for (
unsigned i = 0;
i < el_dim;
i++)
6559 for (
unsigned j = 0; j < el_dim; j++)
6562 jacobian(
i, j) = 0.0;
6564 for (
unsigned l = 0; l < n_shape; l++)
6566 for (
unsigned k = 0; k < n_shape_type; k++)
6590 const unsigned el_dim =
dim();
6594 const unsigned n_shape =
nnode();
6597 const unsigned n_row =
N2deriv[el_dim];
6602 for (
unsigned i = 0;
i < n_row;
i++)
6605 for (
unsigned j = 0; j < el_dim; j++)
6608 jacobian2(
i, j) = 0.0;
6610 for (
unsigned l = 0; l < n_shape; l++)
6613 for (
unsigned k = 0; k < n_shape_type; k++)
6649 const unsigned el_dim =
dim();
6653 const unsigned n_shape =
nnode();
6660 for (
unsigned i = 0;
i < el_dim;
i++)
6663 for (
unsigned j = 0; j < el_dim; j++)
6665 jacobian(
i, j) = 0.0;
6666 inverse_jacobian(
i, j) = 0.0;
6670 for (
unsigned l = 0; l < n_shape; l++)
6673 for (
unsigned k = 0; k < n_shape_type; k++)
6684 for (
unsigned i = 0;
i < el_dim;
i++)
6686 det *= jacobian(
i,
i);
6695 for (
unsigned i = 0;
i < el_dim;
i++)
6697 inverse_jacobian(
i,
i) = 1.0 / jacobian(
i,
i);
6715 const unsigned el_dim =
dim();
6742 const unsigned el_dim =
dim();
6787 const unsigned el_dim =
dim();
6789 const unsigned n_deriv =
N2deriv[el_dim];
6807 jacobian, inverse_jacobian, jacobian2, dpsi, d2psi);
6839 const unsigned el_dim =
dim();
6841 const unsigned n_deriv =
N2deriv[el_dim];
6859 jacobian, inverse_jacobian, jacobian2, dpsi, d2psi);
6875 std::ostream& out,
const std::string& current_string)
const
6878 const unsigned n_node =
nnode();
6880 for (
unsigned n = 0; n < n_node; n++)
6884 std::stringstream conversion;
6885 conversion <<
" of Solid Node " << n << current_string;
6899 const bool& store_local_dof_pt)
6902 const unsigned n_node =
nnode();
6918 std::deque<unsigned long> global_eqn_number_queue;
6925 for (
unsigned n = 0; n < n_node; n++)
6931 for (
unsigned j = 0; j < n_position_type; j++)
6934 for (
unsigned k = 0; k < nodal_dim; k++)
6943 global_eqn_number_queue.push_back(
eqn_number);
6945 if (store_local_dof_pt)
6948 &(cast_node_pt->
x_gen(j, k)));
6970 if (store_local_dof_pt)
6992 const unsigned n_node =
nnode();
7009 const unsigned n_dof = this->
ndof();
7016 int local_unknown = 0;
7022 for (
unsigned n = 0; n < n_node; n++)
7025 for (
unsigned k = 0; k < n_position_type; k++)
7028 for (
unsigned i = 0;
i < nodal_dim;
i++)
7032 if (local_unknown >= 0)
7038 const double old_var = *value_pt;
7041 *value_pt += fd_step;
7055 for (
unsigned m = 0; m < n_dof; m++)
7058 jacobian(m, local_unknown) =
7059 (newres[m] - residuals[m]) / fd_step;
7082 *value_pt = old_var;
7105 const unsigned&
i)
const
7108 const unsigned n_node =
nnode();
7114 Shape psi(n_node, n_lagrangian_type);
7123 for (
unsigned l = 0; l < n_node; l++)
7126 for (
unsigned k = 0; k < n_lagrangian_type; k++)
7143 const unsigned n_node =
nnode();
7149 Shape psi(n_node, n_lagrangian_type);
7158 for (
unsigned i = 0;
i < n_lagrangian;
i++)
7164 for (
unsigned l = 0; l < n_node; l++)
7167 for (
unsigned k = 0; k < n_lagrangian_type; k++)
7184 const unsigned n_node =
nnode();
7190 unsigned el_dim =
dim();
7193 Shape psi(n_node, n_lagrangian_type);
7194 DShape dpsi(n_node, n_lagrangian_type, el_dim);
7203 for (
unsigned i = 0;
i < n_lagrangian;
i++)
7205 for (
unsigned j = 0; j < el_dim; j++)
7211 for (
unsigned l = 0; l < n_node; l++)
7214 for (
unsigned k = 0; k < n_lagrangian_type; k++)
7235 std::ostringstream error_stream;
7236 error_stream <<
"Can only call fill_in_jacobian_for_newmark_accel()\n"
7237 <<
"With Solve_for_consistent_newmark_accel_flag:"
7239 error_stream <<
"Solid_ic_pt: " <<
Solid_ic_pt << std::endl;
7242 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
7247 const unsigned n_node =
nnode();
7252 const unsigned n_lagrangian =
dim();
7255 int local_eqn = 0, local_unknown = 0;
7259 Shape psi(n_node, n_position_type);
7263 DShape dpsidxi(n_node, n_position_type, n_lagrangian);
7277 if (timestepper_pt->
type() !=
"Newmark")
7279 std::ostringstream error_stream;
7281 <<
"Assignment of Newmark accelerations obviously only works\n"
7282 <<
"for Newmark timesteppers. You've called me with "
7283 << timestepper_pt->
type() << std::endl;
7286 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
7291 const unsigned ntstorage = timestepper_pt->
ntstorage();
7292 const double accel_weight = timestepper_pt->
weight(2, ntstorage - 1);
7295 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
7298 for (
unsigned i = 0;
i < n_lagrangian;
i++)
7321 for (
unsigned l0 = 0; l0 < n_node; l0++)
7324 for (
unsigned k0 = 0; k0 < n_position_type; k0++)
7327 for (
unsigned i0 = 0; i0 < nodal_dim; i0++)
7334 for (
unsigned l1 = 0; l1 < n_node; l1++)
7338 for (
unsigned k1 = 0; k1 < n_position_type; k1++)
7345 if (local_unknown >= 0)
7350 jacobian(local_eqn, local_unknown) +=
7351 factor * accel_weight * psi(l0, k0) * psi(l1, k1) *
W;
7379 const unsigned& flag)
7382 const unsigned n_node =
nnode();
7392 const unsigned n_lagrangian =
dim();
7396 int local_unknown = 0;
7399 Shape psi(n_node, n_position_type);
7412 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
7415 for (
unsigned i = 0;
i < n_lagrangian;
i++)
7430 for (
unsigned i = 0;
i < n_lagrangian;
i++)
7433 for (
unsigned l = 0; l < n_node; l++)
7436 for (
unsigned k = 0; k < n_lagrangian_type; k++)
7451 for (
unsigned l = 0; l < n_node; l++)
7454 for (
unsigned k = 0; k < n_position_type; k++)
7457 for (
unsigned i = 0;
i < nodal_dim;
i++)
7468 residuals[local_eqn] +=
7476 for (
unsigned ll = 0; ll < n_node; ll++)
7479 for (
unsigned kk = 0; kk < n_position_type; kk++)
7487 if (local_unknown >= 0)
7493 jacobian(local_eqn, local_unknown) +=
7494 psi(ll, kk) * psi(l, k) * w;
7499 <<
"WARNING: You should really free all Data"
7501 <<
" before setup of initial guess" << std::endl
7502 <<
"ll, kk, ii " << ll <<
" " << kk <<
" " << ii
7511 oomph_info <<
"WARNING: You should really free all Data"
7513 <<
" before setup of initial guess"
7515 <<
"l, k, i " << l <<
" " << k <<
" " <<
i
Function-type-object to perform absolute comparison of objects. Apparently this inlines better.
A Class for the derivatives of shape functions The class design is essentially the same as Shape,...
unsigned long nindex2() const
Return the range of index 2 of the derivatives of the shape functions.
unsigned long nindex1() const
Return the range of index 1 of the derivatives of the shape functions.
A class that represents a collection of data; each Data object may contain many different individual ...
long & eqn_number(const unsigned &i)
Return the equation number of the i-th stored variable.
virtual void add_eqn_numbers_to_vector(Vector< long > &vector_of_eqn_numbers)
Add all equation numbers to the vector in the internal storage order.
virtual void describe_dofs(std::ostream &out, const std::string ¤t_string) const
Function to describe the dofs of the Node. The ostream specifies the output stream to which the descr...
virtual void add_value_pt_to_map(std::map< unsigned, double * > &map_of_value_pt)
Add pointers to all unpinned and unconstrained data to a map indexed by (global) equation number.
static long Is_pinned
Static "Magic number" used in place of the equation number to indicate that the value is pinned.
double * value_pt(const unsigned &i) const
Return the pointer to the i-the stored value. Typically this is required when direct access to the st...
virtual void read_values_from_vector(const Vector< double > &vector_of_values, unsigned &index)
Read all data and time history values from the vector starting from index. On return the index will b...
virtual void add_values_to_vector(Vector< double > &vector_of_values)
Add all data and time history values to the vector in the internal storage order.
unsigned nvalue() const
Return number of values stored in data object (incl pinned ones).
double value(const unsigned &i) const
Return i-th stored value. This function is not virtual so that it can be inlined. This means that if ...
virtual void assign_eqn_numbers(unsigned long &global_ndof, Vector< double * > &dof_pt)
Assign global equation numbers; increment global number of unknowns, global_ndof; and add any new dof...
static long Is_unclassified
Static "Magic number" used in place of the equation number to denote a value that hasn't been classif...
virtual void read_eqn_numbers_from_vector(const Vector< long > &vector_of_eqn_numbers, unsigned &index)
Read all equation numbers from the vector starting from index. On return the index will be set to the...
Class of matrices containing doubles, and stored as a DenseMatrix<double>, but with solving functiona...
unsigned long nrow() const
Return the number of rows of the matrix.
unsigned long ncol() const
Return the number of columns of the matrix.
void solve(DoubleVector &rhs)
Complete LU solve (replaces matrix by its LU decomposition and overwrites RHS with solution)....
This is a base class for all elements that require external sources (e.g. FSI, multi-domain problems ...
unsigned nexternal_interaction_geometric_data() const
Return the number of geometric Data items that affect the external interactions in this element: i....
unsigned nexternal_interaction_field_data() const
Return the number of Data items that affect the external interactions in this element....
Vector< Data * > external_interaction_field_data_pt() const
Return vector of pointers to the field Data objects that affect the interactions on the element.
Vector< Data * > external_interaction_geometric_data_pt() const
Return vector of pointers to the geometric Data objects that affect the interactions on the element.
FaceElements are elements that coincide with the faces of higher-dimensional "bulk" elements....
unsigned & bulk_position_type(const unsigned &i)
Return the position type in the "bulk" element that corresponds to position type i on the FaceElement...
CoordinateMappingFctPt & face_to_bulk_coordinate_fct_pt()
Return the pointer to the function that maps the face coordinate to the bulk coordinate.
FiniteElement * Bulk_element_pt
Pointer to the associated higher-dimensional "bulk" element.
void bulk_node_number_resize(const unsigned &i)
Resize the storage for the bulk node numbers.
int & face_index()
Index of the face (a number that uniquely identifies the face in the element)
void outer_unit_normal(const Vector< double > &s, Vector< double > &unit_normal) const
Compute outer unit normal at the specified local coordinate.
unsigned & nbulk_value(const unsigned &n)
Return the number of values originally stored at local node n (before the FaceElement added additiona...
int Normal_sign
Sign of outer unit normal (relative to cross-products of tangent vectors in the corresponding "bulk" ...
BulkCoordinateDerivativesFctPt Bulk_coordinate_derivatives_fct_pt
Pointer to a function that returns the derivatives of the local "bulk" coordinates with respect to th...
Vector< double > local_coordinate_in_bulk(const Vector< double > &s) const
Return vector of local coordinates in bulk element, given the local coordinates in this FaceElement.
Vector< double > * Tangent_direction_pt
A general direction pointer for the tangent vectors. This is used in the function continuous_tangent_...
FiniteElement *& bulk_element_pt()
Pointer to higher-dimensional "bulk" element.
double interpolated_x(const Vector< double > &s, const unsigned &i) const
Return FE interpolated coordinate x[i] at local coordinate s. Overloaded to get information from bulk...
double J_eulerian(const Vector< double > &s) const
Return the Jacobian of mapping from local to global coordinates at local position s....
static bool Ignore_discontinuous_tangent_warning
Ignores the warning when the tangent vectors from continuous_tangent_and_outer_unit_normal may not be...
double J_eulerian_at_knot(const unsigned &ipt) const
Return the Jacobian of the mapping from local to global coordinates at the ipt-th integration point O...
void check_J_eulerian_at_knots(bool &passed) const
Check that Jacobian of mapping between local and Eulerian coordinates at all integration points is po...
BulkCoordinateDerivativesFctPt & bulk_coordinate_derivatives_fct_pt()
Return the pointer to the function that returns the derivatives of the bulk coordinates wrt the face ...
void get_ds_bulk_ds_face(const Vector< double > &s, DenseMatrix< double > &dsbulk_dsface, unsigned &interior_direction) const
Calculate the derivatives of the local coordinates in the bulk element with respect to the local coor...
void continuous_tangent_and_outer_unit_normal(const Vector< double > &s, Vector< Vector< double >> &tang_vec, Vector< double > &unit_normal) const
Compute the tangent vector(s) and the outer unit normal vector at the specified local coordinate....
void get_local_coordinate_in_bulk(const Vector< double > &s, Vector< double > &s_bulk) const
Calculate the vector of local coordinate in the bulk element given the local coordinates in this Face...
CoordinateMappingFctPt Face_to_bulk_coordinate_fct_pt
Pointer to a function that translates the face coordinate to the coordinate in the bulk element.
int & normal_sign()
Sign of outer unit normal (relative to cross-products of tangent vectors in the corresponding "bulk" ...
void output_zeta(std::ostream &outfile, const unsigned &nplot)
Output boundary coordinate zeta.
unsigned & bulk_node_number(const unsigned &n)
Return the bulk node number that corresponds to the n-th local node number.
void nbulk_value_resize(const unsigned &i)
Resize the storage for the number of values originally stored at the local nodes to i entries.
A general Finite Element class.
virtual double J_eulerian(const Vector< double > &s) const
Return the Jacobian of mapping from local to global coordinates at local position s.
virtual int face_outer_unit_normal_sign(const int &face_index) const
Get the sign of the outer unit normal on the face given by face_index.
double d2shape_eulerian(const Vector< double > &s, Shape &psi, DShape &dpsidx, DShape &d2psidx) const
Compute the geometric shape functions and also first and second derivatives w.r.t....
virtual void update_before_nodal_fd()
Function that is called before the finite differencing of any nodal data. This may be overloaded to u...
double dJ_eulerian_at_knot(const unsigned &ipt, Shape &psi, DenseMatrix< double > &djacobian_dX) const
Compute the geometric shape functions (psi) at integration point ipt. Return the determinant of the j...
void set_nodal_dimension(const unsigned &nodal_dim)
Set the dimension of the nodes in the element. This will typically only be required when constructing...
virtual void dshape_local_at_knot(const unsigned &ipt, Shape &psi, DShape &dpsids) const
Return the geometric shape function and its derivative w.r.t. the local coordinates at the ipt-th int...
virtual void local_coordinate_of_node(const unsigned &j, Vector< double > &s) const
Get local coordinates of node j in the element; vector sets its own size (broken virtual)
Integral * Integral_pt
Pointer to the spatial integration scheme.
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
virtual void transform_derivatives(const DenseMatrix< double > &inverse_jacobian, DShape &dbasis) const
Convert derivative w.r.t.local coordinates to derivatives w.r.t the coordinates used to assemble the ...
virtual unsigned get_bulk_node_number(const int &face_index, const unsigned &i) const
Get the number of the ith node on face face_index (in the bulk node vector).
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.
virtual std::string tecplot_zone_string(const unsigned &nplot) const
Return string for tecplot zone header (when plotting nplot points in each "coordinate direction")
virtual double s_min() const
Min value of local coordinate.
virtual double dshape_eulerian_at_knot(const unsigned &ipt, Shape &psi, DShape &dpsidx) const
Return the geometric shape functions and also first derivatives w.r.t. global coordinates at the ipt-...
unsigned nnodal_position_type() const
Return the number of coordinate types that the element requires to interpolate the geometry between t...
virtual void assign_nodal_local_eqn_numbers(const bool &store_local_dof_pt)
Assign the local equation numbers for Data stored at the nodes Virtual so that it can be overloaded b...
virtual void local_fraction_of_node(const unsigned &j, Vector< double > &s_fraction)
Get the local fraction of the node j in the element A dumb, but correct default implementation is pro...
virtual double invert_jacobian_mapping(const DenseMatrix< double > &jacobian, DenseMatrix< double > &inverse_jacobian) const
A template-free interface that takes the matrix passed as jacobian and return its inverse in inverse_...
void interpolated_zeta(const Vector< double > &s, Vector< double > &zeta) const
Calculate the interpolated value of zeta, the intrinsic coordinate of the element when viewed as a co...
virtual void update_in_nodal_fd(const unsigned &i)
Function called within the finite difference loop for nodal data after a change in the i-th nodal val...
double dnodal_position_gen_dt(const unsigned &n, const unsigned &k, const unsigned &i) const
i-th component of time derivative (velocity) of the generalised position, dx(k,i)/dt at local node n....
virtual double local_to_eulerian_mapping_diagonal(const DShape &dpsids, DenseMatrix< double > &jacobian, DenseMatrix< double > &inverse_jacobian) const
Calculate the mapping from local to Eulerian coordinates given the derivatives of the shape functions...
double size() const
Calculate the size of the element (length, area, volume,...) in Eulerian computational coordinates....
static double Tolerance_for_singular_jacobian
Tolerance below which the jacobian is considered singular.
virtual void fill_in_jacobian_from_nodal_by_fd(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Calculate the contributions to the jacobian from the nodal degrees of freedom using finite difference...
void locate_zeta(const Vector< double > &zeta, GeomObject *&geom_object_pt, Vector< double > &s, const bool &use_coordinate_as_initial_guess=false)
For a given value of zeta, the "global" intrinsic coordinate of a mesh of FiniteElements represented ...
void check_jacobian(const double &jacobian) const
Helper function used to check for singular or negative Jacobians in the transform from local to globa...
virtual void d2shape_local_at_knot(const unsigned &ipt, Shape &psi, DShape &dpsids, DShape &d2psids) const
Return the geometric shape function and its first and second derivatives w.r.t. the local coordinates...
virtual void d2shape_local(const Vector< double > &s, Shape &psi, DShape &dpsids, DShape &d2psids) const
Function to compute the geometric shape functions and also first and second derivatives w....
virtual unsigned required_nvalue(const unsigned &n) const
Number of values that must be stored at local node n by the element. The default is 0,...
static const double Node_location_tolerance
Default value for the tolerance to be used when locating nodes via local coordinates.
virtual void shape(const Vector< double > &s, Shape &psi) const =0
Calculate the geometric shape functions at local coordinate s. This function must be overloaded for e...
virtual double interpolated_x(const Vector< double > &s, const unsigned &i) const
Return FE interpolated coordinate x[i] at local coordinate s.
int nodal_local_eqn(const unsigned &n, const unsigned &i) const
Return the local equation number corresponding to the i-th value at the n-th local node.
unsigned dim() const
Return the spatial dimension of the element, i.e. the number of local coordinates required to paramet...
MacroElement * Macro_elem_pt
Pointer to the element's macro element (NULL by default)
virtual void assemble_local_to_eulerian_jacobian(const DShape &dpsids, DenseMatrix< double > &jacobian) const
Assemble the jacobian matrix for the mapping from local to Eulerian coordinates, given the derivative...
double nodal_position_gen(const unsigned &n, const unsigned &k, const unsigned &i) const
Return the value of the k-th type of the i-th positional variable at the local node n.
unsigned nnode() const
Return the number of nodes.
virtual double s_max() const
Max. value of local coordinate.
unsigned Nodal_dimension
The spatial dimension of the nodes in the element. We assume that nodes have the same spatial dimensi...
void(* SteadyExactSolutionFctPt)(const Vector< double > &, Vector< double > &)
Function pointer for function that computes vector-valued steady "exact solution" as .
virtual void reset_in_nodal_fd(const unsigned &i)
Function called within the finite difference loop for nodal data after the i-th nodal values is reset...
Integral *const & integral_pt() const
Return the pointer to the integration scheme (const version)
virtual double interpolated_dxdt(const Vector< double > &s, const unsigned &i, const unsigned &t)
Return t-th time-derivative of the i-th FE-interpolated Eulerian coordinate at local coordinate s.
virtual void identify_field_data_for_interactions(std::set< std::pair< Data *, unsigned >> &paired_field_data)
The purpose of this function is to identify all possible Data that can affect the fields interpolated...
virtual void get_s_plot(const unsigned &i, const unsigned &nplot, Vector< double > &s, const bool &shifted_to_interior=false) const
Get cector of local coordinates of plot point i (when plotting nplot points in each "coordinate direc...
virtual double zeta_nodal(const unsigned &n, const unsigned &k, const unsigned &i) const
Specify the values of the "global" intrinsic coordinate, zeta, of a compound geometric object (a mesh...
Node ** Node_pt
Storage for pointers to the nodes in the element.
virtual double local_to_eulerian_mapping(const DShape &dpsids, DenseMatrix< double > &jacobian, DenseMatrix< double > &inverse_jacobian) const
Calculate the mapping from local to Eulerian coordinates, given the derivatives of the shape function...
virtual BulkCoordinateDerivativesFctPt bulk_coordinate_derivatives_fct_pt(const int &face_index) const
Get a pointer to the derivative of the mapping from face to bulk coordinates.
void get_centre_of_gravity_and_max_radius_in_terms_of_zeta(Vector< double > &cog, double &max_radius) const
Compute centre of gravity of all nodes and radius of node that is furthest from it....
virtual unsigned nplot_points(const unsigned &nplot) const
Return total number of plot points (when plotting nplot points in each "coordinate direction")
virtual void reset_after_nodal_fd()
Function that is call after the finite differencing of the nodal data. This may be overloaded to rese...
double dshape_eulerian(const Vector< double > &s, Shape &psi, DShape &dpsidx) const
Compute the geometric shape functions and also first derivatives w.r.t. global coordinates at local c...
unsigned Elemental_dimension
The spatial dimension of the element, i.e. the number of local coordinates used to parametrize it.
virtual bool local_coord_is_valid(const Vector< double > &s)
Broken assignment operator.
void check_J_eulerian_at_knots(bool &passed) const
Check that Jacobian of mapping between local and Eulerian coordinates at all integration points is po...
virtual void dshape_local(const Vector< double > &s, Shape &psi, DShape &dpsids) const
Function to compute the geometric shape functions and derivatives w.r.t. local coordinates at local c...
virtual void move_local_coord_back_into_element(Vector< double > &s) const
Adjust local coordinates so that they're located inside the element.
virtual void assemble_eulerian_base_vectors(const DShape &dpsids, DenseMatrix< double > &interpolated_G) const
Assemble the covariant Eulerian base vectors, assuming that the derivatives of the shape functions wi...
virtual void assemble_local_to_eulerian_jacobian2(const DShape &d2psids, DenseMatrix< double > &jacobian2) const
Assemble the the "jacobian" matrix of second derivatives of the mapping from local to Eulerian coordi...
virtual void d_dshape_eulerian_dnodal_coordinates(const double &det_jacobian, const DenseMatrix< double > &jacobian, const DenseMatrix< double > &djacobian_dX, const DenseMatrix< double > &inverse_jacobian, const DShape &dpsids, RankFourTensor< double > &d_dpsidx_dX) const
A template-free interface that calculates the derivative w.r.t. the nodal coordinates of the derivat...
virtual double J_eulerian_at_knot(const unsigned &ipt) const
Return the Jacobian of the mapping from local to global coordinates at the ipt-th integration point.
MacroElement * macro_elem_pt()
Access function to pointer to macro element.
void integrate_fct(FiniteElement::SteadyExactSolutionFctPt integrand_fct_pt, Vector< double > &integral)
Evaluate integral of a Vector-valued function over the element.
virtual void describe_local_dofs(std::ostream &out, const std::string ¤t_string) const
Function to describe the local dofs of the element[s]. The ostream specifies the output stream to whi...
virtual void build_face_element(const int &face_index, FaceElement *face_element_pt)
Function for building a lower dimensional FaceElement on the specified face of the FiniteElement....
virtual void transform_second_derivatives(const DenseMatrix< double > &jacobian, const DenseMatrix< double > &inverse_jacobian, const DenseMatrix< double > &jacobian2, DShape &dbasis, DShape &d2basis) const
Convert derivatives and second derivatives w.r.t. local coordiantes to derivatives and second derivat...
virtual void describe_nodal_local_dofs(std::ostream &out, const std::string ¤t_string) const
Function to describe the local dofs of the element[s]. The ostream specifies the output stream to whi...
unsigned nodal_dimension() const
Return the required Eulerian dimension of the nodes in this element.
int ** Nodal_local_eqn
Storage for the local equation numbers associated with the values stored at the nodes.
virtual ~FiniteElement()
The destructor cleans up the static memory allocated for shape function storage. Internal and externa...
virtual void get_x_from_macro_element(const Vector< double > &s, Vector< double > &x) const
Global coordinates as function of local coordinates using macro element representation....
double raw_nodal_position(const unsigned &n, const unsigned &i) const
Return the i-th coordinate at local node n. Do not use the hanging node representation....
virtual void node_update()
Update the positions of all nodes in the element using each node update function. The default impleme...
virtual void write_tecplot_zone_footer(std::ostream &outfile, const unsigned &nplot) const
Add tecplot zone "footer" to output stream (when plotting nplot points in each "coordinate direction"...
unsigned Nnode
Number of nodes in the element.
virtual void set_integration_scheme(Integral *const &integral_pt)
Set the spatial integration scheme.
static const unsigned N2deriv[]
Static array that holds the number of second derivatives as a function of the dimension of the elemen...
static bool Accept_negative_jacobian
Boolean that if set to true allows a negative jacobian in the transform between global and local coor...
void(* UnsteadyExactSolutionFctPt)(const double &, const Vector< double > &, Vector< double > &)
Function pointer for function that computes Vector-valued time-dependent function as .
virtual unsigned nnode_on_face() const
void transform_derivatives_diagonal(const DenseMatrix< double > &inverse_jacobian, DShape &dbasis) const
Convert derivative w.r.t local coordinates to derivatives w.r.t the coordinates used to assemble the ...
double raw_nodal_position_gen(const unsigned &n, const unsigned &k, const unsigned &i) const
Return the value of the k-th type of the i-th positional variable at the local node n....
virtual void get_dresidual_dnodal_coordinates(RankThreeTensor< double > &dresidual_dnodal_coordinates)
Compute derivatives of elemental residual vector with respect to nodal coordinates....
static bool Suppress_output_while_checking_for_inverted_elements
Static boolean to suppress output while checking for inverted elements.
int get_node_number(Node *const &node_pt) const
Return the number of the node *node_pt if this node is in the element, else return -1;.
virtual void shape_at_knot(const unsigned &ipt, Shape &psi) const
Return the geometric shape function at the ipt-th integration point.
virtual double d2shape_eulerian_at_knot(const unsigned &ipt, Shape &psi, DShape &dpsidx, DShape &d2psidx) const
Return the geometric shape functions and also first and second derivatives w.r.t. global coordinates ...
virtual void dJ_eulerian_dnodal_coordinates(const DenseMatrix< double > &jacobian, const DShape &dpsids, DenseMatrix< double > &djacobian_dX) const
A template-free interface that calculates the derivative of the jacobian of a mapping with respect to...
virtual CoordinateMappingFctPt face_to_bulk_coordinate_fct_pt(const int &face_index) const
Get a pointer to the function mapping face coordinates to bulk coordinates.
static const unsigned Default_Initial_Nvalue
Default return value for required_nvalue(n) which gives the number of "data" values required by the e...
virtual unsigned self_test()
Self-test: Check inversion of element & do self-test for GeneralisedElement. Return 0 if OK.
void fill_in_jacobian_from_external_by_fd(Vector< double > &residuals, DenseMatrix< double > &jacobian, const bool &fd_all_data=false)
Calculate the contributions to the jacobian from the external degrees of freedom using finite differe...
unsigned nexternal_data() const
Return the number of external data objects.
virtual void reset_in_external_fd(const unsigned &i)
Function called within the finite difference loop for external data after the values in the i-th exte...
virtual void fill_in_contribution_to_mass_matrix(Vector< double > &residuals, DenseMatrix< double > &mass_matrix)
Add the elemental contribution to the mass matrix matrix. and the residuals vector....
virtual void update_in_internal_fd(const unsigned &i)
Function called within the finite difference loop for internal data after a change in any values in t...
bool is_halo() const
Is this element a halo?
virtual void reset_after_external_fd()
Function that is call after the finite differencing of the external data. This may be overloaded to r...
virtual void update_before_external_fd()
Function that is called before the finite differencing of any external data. This may be overloaded t...
void assign_internal_eqn_numbers(unsigned long &global_number, Vector< double * > &Dof_pt)
Assign the global equation numbers to the internal Data. The arguments are the current highest global...
static double Default_fd_jacobian_step
Double used for the default finite difference step in elemental jacobian calculations.
static bool Suppress_warning_about_repeated_external_data
Static boolean to suppress warnings about repeated external data. Defaults to true.
bool internal_data_fd(const unsigned &i) const
Return the status of the boolean flag indicating whether the internal data is included in the finite ...
unsigned long * Eqn_number
Storage for the global equation numbers represented by the degrees of freedom in the element.
void read_internal_eqn_numbers_from_vector(const Vector< long > &vector_of_eqn_numbers, unsigned &index)
Read all equation numbers associated with internal data from the vector starting from index....
virtual void fill_in_contribution_to_jacobian_and_mass_matrix(Vector< double > &residuals, DenseMatrix< double > &jacobian, DenseMatrix< double > &mass_matrix)
Add the elemental contribution to the jacobian matrix, mass matrix and the residuals vector....
virtual void fill_in_contribution_to_djacobian_and_dmass_matrix_dparameter(double *const ¶meter_pt, Vector< double > &dres_dparam, DenseMatrix< double > &djac_dparam, DenseMatrix< double > &dmass_matrix_dparam)
Add the elemental contribution to the derivative of the jacobian matrix, mass matrix and the residual...
virtual void fill_in_contribution_to_inner_product_vectors(Vector< unsigned > const &history_index, Vector< Vector< double >> &inner_product_vector)
Fill in the contributions to the vectors that when taken as dot product with other history values giv...
void fill_in_jacobian_from_internal_by_fd(Vector< double > &residuals, DenseMatrix< double > &jacobian, const bool &fd_all_data=false)
Calculate the contributions to the jacobian from the internal degrees of freedom using finite differe...
bool external_data_fd(const unsigned &i) const
Return the status of the boolean flag indicating whether the external data is included in the finite ...
virtual void assign_all_generic_local_eqn_numbers(const bool &store_local_dof_pt)
Assign all the local equation numbering schemes that can be applied generically for the element....
unsigned add_internal_data(Data *const &data_pt, const bool &fd=true)
Add a (pointer to an) internal data object to the element and return the index required to obtain it ...
unsigned ndof() const
Return the number of equations/dofs in the element.
unsigned long eqn_number(const unsigned &ieqn_local) const
Return the global equation number corresponding to the ieqn_local-th local equation number.
int ** Data_local_eqn
Pointer to array storage for local equation numbers associated with internal and external data....
int local_eqn_number(const unsigned long &ieqn_global) const
Return the local equation number corresponding to the ieqn_global-th global equation number....
Data *& external_data_pt(const unsigned &i)
Return a pointer to i-th external data object.
void add_internal_data_values_to_vector(Vector< double > &vector_of_values)
Add all internal data and time history values to the vector in the internal storage order.
Data *& internal_data_pt(const unsigned &i)
Return a pointer to i-th internal data object.
static DenseMatrix< double > Dummy_matrix
Empty dense matrix used as a dummy argument to combined residual and jacobian functions in the case w...
virtual void assign_additional_local_eqn_numbers()
Setup any additional look-up schemes for local equation numbers. Examples of use include using local ...
virtual void get_residuals(Vector< double > &residuals)
Calculate the vector of residuals of the equations in the element. By default initialise the vector t...
virtual void fill_in_contribution_to_dresiduals_dparameter(double *const ¶meter_pt, Vector< double > &dres_dparam)
Add the elemental contribution to the derivatives of the residuals with respect to a parameter....
unsigned ninternal_data() const
Return the number of internal data objects.
int Non_halo_proc_ID
Non-halo processor ID for Data; -1 if it's not a halo.
void clear_global_eqn_numbers()
Clear the storage for the global equation numbers and pointers to dofs (if stored)
unsigned Ninternal_data
Number of internal data.
unsigned Nexternal_data
Number of external data.
void add_internal_value_pt_to_map(std::map< unsigned, double * > &map_of_value_pt)
Add pointers to the internal data values to map indexed by the global equation number.
void add_global_eqn_numbers(std::deque< unsigned long > const &global_eqn_numbers, std::deque< double * > const &global_dof_pt)
Add the contents of the queue global_eqn_numbers to the local storage for the local-to-global transla...
virtual void update_before_internal_fd()
Function that is called before the finite differencing of any internal data. This may be overloaded t...
virtual void fill_in_contribution_to_inner_products(Vector< std::pair< unsigned, unsigned >> const &history_index, Vector< double > &inner_product)
Fill in the contribution to the inner products between given pairs of history values.
virtual void reset_in_internal_fd(const unsigned &i)
Function called within the finite difference loop for internal data after the values in the i-th exte...
virtual void fill_in_contribution_to_djacobian_dparameter(double *const ¶meter_pt, Vector< double > &dres_dparam, DenseMatrix< double > &djac_dparam)
Add the elemental contribution to the derivatives of the elemental Jacobian matrix and residuals with...
virtual void fill_in_contribution_to_hessian_vector_products(Vector< double > const &Y, DenseMatrix< double > const &C, DenseMatrix< double > &product)
Fill in contribution to the product of the Hessian (derivative of Jacobian with respect to all variab...
unsigned Ndof
Number of degrees of freedom.
int internal_local_eqn(const unsigned &i, const unsigned &j) const
Return the local equation number corresponding to the j-th value stored at the i-th internal data.
virtual void describe_local_dofs(std::ostream &out, const std::string ¤t_string) const
Function to describe the local dofs of the element. The ostream specifies the output stream to which ...
static std::deque< double * > Dof_pt_deque
Static storage for deque used to add_global_equation_numbers when pointers to the dofs in each elemen...
virtual void assign_internal_and_external_local_eqn_numbers(const bool &store_local_dof_pt)
Assign the local equation numbers for the internal and external Data This must be called after the gl...
void set_halo(const unsigned &non_halo_proc_ID)
Label the element as halo and specify processor that holds non-halo counterpart.
void add_internal_eqn_numbers_to_vector(Vector< long > &vector_of_eqn_numbers)
Add all equation numbers associated with internal data to the vector in the internal storage order.
virtual void reset_after_internal_fd()
Function that is call after the finite differencing of the internal data. This may be overloaded to r...
virtual unsigned self_test()
Self-test: Have all internal values been classified as pinned/unpinned? Return 0 if OK.
virtual void assign_local_eqn_numbers(const bool &store_local_dof_pt)
Setup the arrays of local equation numbers for the element. If the optional boolean argument is true,...
Data ** Data_pt
Storage for pointers to internal and external data. The data is of the same type and so can be addres...
static bool Suppress_warning_about_repeated_internal_data
Static boolean to suppress warnings about repeated internal data. Defaults to false.
double ** Dof_pt
Storage for array of pointers to degrees of freedom ordered by local equation number....
int external_local_eqn(const unsigned &i, const unsigned &j)
Return the local equation number corresponding to the j-th value stored at the i-th external data.
void describe_dofs(std::ostream &out, const std::string ¤t_string) const
Function to describe the dofs of the element. The ostream specifies the output stream to which the de...
std::vector< bool > Data_fd
Storage for boolean flags of size Ninternal_data + Nexternal_data that correspond to the data used in...
void flush_external_data()
Flush all external data.
void read_internal_data_values_from_vector(const Vector< double > &vector_of_values, unsigned &index)
Read all internal data and time history values from the vector starting from index....
virtual void update_in_external_fd(const unsigned &i)
Function called within the finite difference loop for external data after a change in any values in t...
unsigned add_external_data(Data *const &data_pt, const bool &fd=true)
Add a (pointer to an) external data object to the element and return its index (i....
/////////////////////////////////////////////////////////////////////
virtual void dposition_dt(const Vector< double > &zeta, const unsigned &j, Vector< double > &drdt)
j-th time-derivative on object at current time: .
Generic class for numerical integration schemes:
virtual double knot(const unsigned &i, const unsigned &j) const =0
Return local coordinate s[j] of i-th integration point.
virtual unsigned nweight() const =0
Return the number of integration points of the scheme.
virtual double weight(const unsigned &i) const =0
Return weight of i-th integration point.
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
double & x(const unsigned &i)
Return the i-th nodal coordinate.
double & x_gen(const unsigned &k, const unsigned &i)
Reference to the generalised position x(k,i). ‘Type’: k; Coordinate direction: i.
void perform_auxiliary_node_update_fct()
Execute auxiliary update function (if any) – this can be used to update any nodal values following th...
unsigned ndim() const
Return (Eulerian) spatial dimension of the node.
TimeStepper *& position_time_stepper_pt()
Return a pointer to the position timestepper.
virtual void node_update(const bool &update_all_time_levels_for_new_node=false)
Interface for functions that update the nodal position using algebraic remeshing strategies....
An OomphLibError object which should be thrown when an run-time error is encountered....
void disable_error_message()
Suppress issueing of the error message in destructor (useful if error is caught successfully!...
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
An OomphLibWarning object which should be created as a temporary object to issue a warning....
void shape(const Vector< double > &s, Shape &psi) const
Broken assignment operator.
static PointIntegral Default_integration_scheme
Return spatial dimension of element (=number of local coordinates needed to parametrise the element)
Broken pseudo-integration scheme for points elements: Iit's not clear in general what this integratio...
////////////////////////////////////////////////////////////////// //////////////////////////////////...
unsigned long nindex4() const
Return the range of index 4 of the tensor.
unsigned long nindex2() const
Return the range of index 2 of the tensor.
unsigned long nindex1() const
Return the range of index 1 of the tensor.
unsigned long nindex3() const
Return the range of index 3 of the tensor.
////////////////////////////////////////////////////////////////// //////////////////////////////////...
A Class for shape functions. In simple cases, the shape functions have only one index that can be tho...
unsigned lagrangian_dimension() const
Return the number of Lagrangian coordinates that the element requires at all nodes....
void describe_solid_local_dofs(std::ostream &out, const std::string ¤t_string) const
Classifies dofs locally for solid specific aspects.
double lagrangian_position_gen(const unsigned &n, const unsigned &k, const unsigned &i) const
Return Generalised Lagrangian coordinate at local node n. ‘Direction’ i, ‘Type’ k.
double raw_lagrangian_position_gen(const unsigned &n, const unsigned &k, const unsigned &i) const
Return Generalised Lagrangian coordinate at local node n. ‘Direction’ i, ‘Type’ k....
int * Position_local_eqn
Array to hold the local equation number information for the solid equations, whatever they may be.
virtual void assemble_local_to_lagrangian_jacobian2(const DShape &d2psids, DenseMatrix< double > &jacobian2) const
Assemble the the "jacobian" matrix of second derivatives, given the second derivatives of the shape f...
virtual void assign_solid_local_eqn_numbers(const bool &store_local_dof)
Assigns local equation numbers for the generic solid local equation numbering schemes....
double dshape_lagrangian(const Vector< double > &s, Shape &psi, DShape &dpsidxi) const
Calculate shape functions and derivatives w.r.t. Lagrangian coordinates at local coordinate s....
unsigned nnodal_lagrangian_type() const
Return the number of types of (generalised) nodal Lagrangian coordinates required to interpolate the ...
unsigned Lagrangian_dimension
The Lagrangian dimension of the nodes stored in the element, / i.e. the number of Lagrangian coordina...
virtual void update_before_solid_position_fd()
Function that is called before the finite differencing of any solid position data....
bool Solve_for_consistent_newmark_accel_flag
Flag to indicate which system of equations to solve when assigning initial conditions for time-depend...
SolidInitialCondition * Solid_ic_pt
Pointer to object that specifies the initial condition.
virtual double d2shape_lagrangian_at_knot(const unsigned &ipt, Shape &psi, DShape &dpsidxi, DShape &d2psidxi) const
Return the geometric shape functions and also first and second derivatives w.r.t. Lagrangian coordina...
void fill_in_generic_jacobian_for_solid_ic(Vector< double > &residuals, DenseMatrix< double > &jacobian, const unsigned &flag)
Helper function to fill in the residuals and (if flag==1) the Jacobian for the setup of an initial co...
virtual double local_to_lagrangian_mapping_diagonal(const DShape &dpsids, DenseMatrix< double > &jacobian, DenseMatrix< double > &inverse_jacobian) const
Calculate the mapping from local to Lagrangian coordinates given the derivatives of the shape functio...
virtual void update_in_solid_position_fd(const unsigned &i)
Function called within the finite difference loop for the solid position dat after a change in any va...
int position_local_eqn(const unsigned &n, const unsigned &k, const unsigned &j) const
Access function that returns the local equation number that corresponds to the j-th coordinate of the...
virtual double local_to_lagrangian_mapping(const DShape &dpsids, DenseMatrix< double > &jacobian, DenseMatrix< double > &inverse_jacobian) const
Calculate the mapping from local to lagrangian coordinates, given the derivatives of the shape functi...
virtual void assemble_local_to_lagrangian_jacobian(const DShape &dpsids, DenseMatrix< double > &jacobian) const
Assemble the jacobian matrix for the mapping from local to lagrangian coordinates,...
virtual double interpolated_xi(const Vector< double > &s, const unsigned &i) const
Return i-th FE-interpolated Lagrangian coordinate xi[i] at local coordinate s.
virtual void reset_in_solid_position_fd(const unsigned &i)
Function called within the finite difference loop for solid position data after the values in the i-t...
virtual void interpolated_dxids(const Vector< double > &s, DenseMatrix< double > &dxids) const
Compute derivatives of FE-interpolated Lagrangian coordinates xi with respect to local coordinates: d...
virtual double dshape_lagrangian_at_knot(const unsigned &ipt, Shape &psi, DShape &dpsidxi) const
Return the geometric shape functions and also first derivatives w.r.t. Lagrangian coordinates at ipt-...
virtual void fill_in_jacobian_from_solid_position_by_fd(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Use finite differences to calculate the Jacobian entries corresponding to the solid positions....
double multiplier(const Vector< double > &xi)
Access to the "multiplier" for the inertia terms in the consistent determination of the initial condi...
double d2shape_lagrangian(const Vector< double > &s, Shape &psi, DShape &dpsidxi, DShape &d2psidxi) const
Compute the geometric shape functions and also first and second derivatives w.r.t....
void compute_norm(double &el_norm)
Calculate the L2 norm of the displacement u=R-r to overload the compute_norm function in the Generali...
void describe_local_dofs(std::ostream &out, const std::string ¤t_string) const
Function to describe the local dofs of the element. The ostream specifies the output stream to which ...
virtual ~SolidFiniteElement()
Destructor to clean up any allocated memory.
void fill_in_jacobian_for_newmark_accel(DenseMatrix< double > &jacobian)
Fill in the contributions of the Jacobian matrix for the consistent assignment of the initial "accele...
virtual void reset_after_solid_position_fd()
Function that is call after the finite differencing of the solid position data. This may be overloade...
GeomObject *& geom_object_pt()
(Reference to) pointer to geom object that specifies the initial condition
unsigned & ic_time_deriv()
Which time derivative are we currently assigning?
A Class for nodes that deform elastically (i.e. position is an unknown in the problem)....
const long & position_eqn_number(const unsigned &k, const unsigned &i) const
Return the equation number for generalised Eulerian coordinate: type of coordinate: k,...
void describe_dofs(std::ostream &out, const std::string ¤t_string) const
Function to describe the dofs of the Node. The ostream specifies the output stream to which the descr...
Data *const & variable_position_pt() const
Pointer to variable_position data (const version)
////////////////////////////////////////////////////////////////////// //////////////////////////////...
unsigned ntstorage() const
Return the number of doubles required to represent history (one for steady)
virtual double weight(const unsigned &i, const unsigned &j) const
Access function for j-th weight for the i-th derivative.
std::string type() const
Return string that indicates the type of the timestepper (e.g. "BDF", "Newmark", etc....
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
unsigned Max_newton_iterations
Maximum number of newton iterations.
double Newton_tolerance
Convergence tolerance for the newton solver.
unsigned N_local_points
Number of points along one dimension of each element used to create coordinates within the element in...
double Radius_multiplier_for_fast_exit_from_locate_zeta
Multiplier for (zeta-based) outer radius of element used for deciding that point is outside element....
const double Pi
50 digits from maple
double dot(const Vector< double > &a, const Vector< double > &b)
Probably not always best/fastest because not optimised for dimension but useful...
void cross(const Vector< double > &A, const Vector< double > &B, Vector< double > &C)
Cross product using "proper" output (move semantics means this is ok nowadays).
double angle(const Vector< double > &a, const Vector< double > &b)
Get the angle between two vector.
double magnitude(const Vector< double > &a)
Get the magnitude of a vector.
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
OomphInfo oomph_info
Single (global) instantiation of the OomphInfo object – this is used throughout the library as a "rep...