28#ifndef OOMPH_PROJECTION_HEADER
29#define OOMPH_PROJECTION_HEADER
34#include "multi_domain.h"
36#include "element_with_external_element.h"
37#include "linear_solver.h"
40#ifdef OOMPH_HAS_TRILINOS
41#include "trilinos_solver.h"
43#include "iterative_linear_solver.h"
46#include "preconditioner.h"
47#include "general_purpose_preconditioners.h"
133 const unsigned& fld) = 0;
164 const Vector<double>& s,
171 const Vector<double>& s) = 0;
179 template<
class ELEMENT>
182 public virtual ElementWithExternalElement
192 residuals, GeneralisedElement::Dummy_matrix, 0);
197 ELEMENT::fill_in_contribution_to_residuals(residuals);
210 const std::string& current_string)
const
212 ElementWithExternalElement::describe_local_dofs(out, current_string);
213 ELEMENT::describe_local_dofs(out, current_string);
218 DenseMatrix<double>& jacobian)
227 ELEMENT::fill_in_contribution_to_jacobian(residuals, jacobian);
241 DenseMatrix<double>& jacobian,
242 const unsigned& flag)
245 SolidFiniteElement* solid_el_pt =
dynamic_cast<SolidFiniteElement*
>(
this);
247 unsigned n_dim = dim();
250 Vector<double> s(n_dim);
256 const unsigned n_node = this->nnode();
258 const unsigned n_position_type = this->nnodal_position_type();
264 const unsigned n_intpt = integral_pt()->nweight();
267 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
270 for (
unsigned i = 0; i < n_dim; i++) s[i] = integral_pt()->knot(ipt, i);
273 double w = integral_pt()->weight(ipt);
276 FiniteElement* other_el_pt = 0;
277 other_el_pt = this->external_element_pt(0, ipt);
278 Vector<double> other_s(n_dim);
279 other_s = this->external_element_local_coord(0, ipt);
285 int local_eqn = 0, local_unknown = 0;
293 if (solid_el_pt == 0)
295 throw OomphLibError(
"Trying to project Lagrangian coordinates in "
296 "non-SolidElement\n",
297 OOMPH_CURRENT_FUNCTION,
298 OOMPH_EXCEPTION_LOCATION);
302 Shape psi(n_node, n_position_type);
306 double J = this->J_eulerian(s);
314 double interpolated_xi_proj = this->interpolated_x(s, 0);
317 double interpolated_xi_bar =
318 dynamic_cast<SolidFiniteElement*
>(cast_el_pt)
322 for (
unsigned l = 0; l < n_node; ++l)
325 for (
unsigned k = 0; k < n_position_type; ++k)
329 local_eqn = solid_el_pt->position_local_eqn(l, k, 0);
335 residuals[local_eqn] +=
336 (interpolated_xi_proj - interpolated_xi_bar) * psi(l, k) *
342 for (
unsigned l2 = 0; l2 < n_node; l2++)
345 for (
unsigned k2 = 0; k2 < n_position_type; k2++)
348 solid_el_pt->position_local_eqn(l2, k2, 0);
349 if (local_unknown >= 0)
351 jacobian(local_eqn, local_unknown) +=
352 psi(l2, k2) * psi(l, k) * W;
368 Shape psi(n_node, n_position_type);
372 double J = this->J_eulerian(s);
379 double interpolated_x_proj = 0.0;
381 if (solid_el_pt != 0)
383 interpolated_x_proj =
389 interpolated_x_proj = this->
get_field(0, fld, s);
393 double interpolated_x_bar = cast_el_pt->interpolated_x(
397 for (
unsigned l = 0; l < n_node; ++l)
400 for (
unsigned k = 0; k < n_position_type; ++k)
403 if (solid_el_pt != 0)
417 if (n_position_type != 1)
419 throw OomphLibError(
"Trying to project generalised "
420 "positions not in SolidElement\n",
421 OOMPH_CURRENT_FUNCTION,
422 OOMPH_EXCEPTION_LOCATION);
431 residuals[local_eqn] +=
432 (interpolated_x_proj - interpolated_x_bar) * psi(l, k) * W;
437 for (
unsigned l2 = 0; l2 < n_node; l2++)
440 for (
unsigned k2 = 0; k2 < n_position_type; k2++)
443 if (solid_el_pt != 0)
445 local_unknown = solid_el_pt->position_local_eqn(
453 if (local_unknown >= 0)
455 jacobian(local_eqn, local_unknown) +=
456 psi(l2, k2) * psi(l, k) * W;
482 double interpolated_value_proj = this->
get_field(now, fld, s);
485 double interpolated_value_bar =
489 for (
unsigned l = 0; l < n_value; l++)
495 residuals[local_eqn] +=
496 (interpolated_value_proj - interpolated_value_bar) * psi[l] *
502 for (
unsigned l2 = 0; l2 < n_value; l2++)
505 if (local_unknown >= 0)
507 jacobian(local_eqn, local_unknown) +=
508 psi[l2] * psi[l] * W;
518 throw OomphLibError(
"Wrong type specificied in Projection_type. "
519 "This should never happen\n",
520 OOMPH_CURRENT_FUNCTION,
521 OOMPH_EXCEPTION_LOCATION);
533 const unsigned& i)
const
537 return nodal_position_gen(n, k, i);
541 return ELEMENT::zeta_nodal(n, k, i);
554 if (add_external_geometric_data())
564 if (add_external_interaction_data())
575 ignore_external_geometric_data();
576 ignore_external_interaction_data();
591 include_external_geometric_data();
595 ignore_external_geometric_data();
601 include_external_interaction_data();
605 ignore_external_interaction_data();
665 template<
class ELEMENT>
667 :
public virtual FaceGeometry<ELEMENT>
693 template<
class PROJECTABLE_ELEMENT>
699 template<
class FRIEND_PROJECTABLE_ELEMENT>
701 template<
class FRIEND_PROJECTABLE_ELEMENT>
703 template<
class FRIEND_PROJECTABLE_ELEMENT>
705 template<
class FRIEND_PROJECTABLE_ELEMENT>
755#ifdef OOMPH_HAS_TRILINOS
757 if (MPI_Helpers::mpi_has_been_initialised())
782 if (!(MPI_Helpers::mpi_has_been_initialised()))
825 unsigned n_element = Problem::mesh_pt()->nelement();
827 unsigned n_node = Problem::mesh_pt()->nnode();
831 oomph_info <<
"\n=============================\n";
836 oomph_info <<
"=============================\n\n";
847 oomph_info <<
"Very odd -- no elements in target mesh; "
848 <<
" not doing anything in ProjectionProblem::project()\n";
853 unsigned nnod = Problem::mesh_pt()->nnode();
858 <<
"Mesh has no nodes! Please populate the Node_pt vector\n"
859 <<
"otherwise projection won't work!\n";
868 ->nfields_for_projection();
871 unsigned n_dim = Problem::mesh_pt()->node_pt(0)->ndim();
883 el_pt->enable_projection();
895 el_pt->enable_projection();
905 double t_start = TimingHelpers::timer();
906 Multi_domain_functions::setup_multi_domain_interaction<
911 <<
"CPU for setup of multi-domain interaction for projection: "
912 << TimingHelpers::timer() -
t_start << std::endl;
914 t_start = TimingHelpers::timer();
942 dynamic_cast<SolidNode*
>(Problem::mesh_pt()->node_pt(0))
951 <<
"\n\n=============================================\n";
952 oomph_info <<
"Projecting values for Lagrangian coordinate " <<
i
954 oomph_info <<
"=============================================\n\n";
964 oomph_info <<
"Number of equations for projection of Lagrangian "
966 <<
" : " << ndof_tmp << std::endl
975 <<
"Solid mechanics problems will break if "
976 "Problem_is_nonlinear is\n"
977 <<
"set to true in the projection problem because we're using "
979 <<
"actual nodal positions to store the values of the "
981 <<
"coords. There shouldn't be any need for \n"
982 <<
"Problem_is_nonlinear=true anyway, apart from debugging in "
984 <<
"which case you now know why this case will break!\n";
992 Problem::newton_solve();
995 unsigned n_node = Problem::mesh_pt()->nnode();
1000 dynamic_cast<SolidNode*
>(Problem::mesh_pt()->node_pt(
n));
1012 <<
"The number of generalised position dofs "
1014 <<
"\n not the same as the number of generalised lagrangian "
1017 <<
"Projection cannot be done at the moment, sorry.\n";
1043 Problem::mesh_pt()->element_pt(0))
1044 ->nhistory_values_for_coordinate_projection();
1049 for (
unsigned i = 0;
i <
n_dim;
i++)
1054 <<
"\n\n=============================================\n";
1055 oomph_info <<
"Projecting history values for coordinate " <<
i
1058 <<
"=============================================\n\n";
1079 <<
"Number of equations for projection of coordinate " <<
i
1086 Problem::newton_solve();
1089 unsigned n_node = Problem::mesh_pt()->nnode();
1130 unsigned n_element = Problem::mesh_pt()->nelement();
1135 for (
unsigned j = 0;
j <
nnod;
j++)
1138 if (
nod_pt->nvalue() == 0)
1143 for (
unsigned i = 0;
i <
n;
i++)
1148 <<
"\nhas no values. Projection (of coordinates) doesn't "
1150 <<
"for such cases (at the moment), sorry! Send us the code\n"
1151 <<
"where the problem arises and we'll try to implement "
1153 <<
"(up to now unnecessary) capability...\n";
1165 Problem::mesh_pt()->element_pt(0))
1166 ->nhistory_values_for_coordinate_projection();
1171 for (
unsigned i = 0;
i <
n_dim;
i++)
1176 <<
"\n\n=============================================\n";
1177 oomph_info <<
"Projecting history values for coordinate " <<
i
1180 <<
"=============================================\n\n";
1200 <<
"Number of equations for projection of coordinate " <<
i
1207 Problem::newton_solve();
1210 unsigned n_element = Problem::mesh_pt()->nelement();
1215 Problem::mesh_pt()->element_pt(
e));
1244 PROJECTABLE_ELEMENT*
el_pt =
1247 el_pt->set_project_values();
1264 ->nhistory_values_for_projection(
fld);
1273 oomph_info <<
"\n=========================================\n";
1274 oomph_info <<
"Projecting field " <<
fld <<
" at time level "
1276 oomph_info <<
"========================================\n";
1286 oomph_info <<
"Number of equations for projection of field " <<
fld
1293 Problem::newton_solve();
1304 Problem::mesh_pt()->element_pt(
e));
1330 new_el_pt->flush_all_external_element_storage();
1341 el_pt->flush_all_external_element_storage();
1344 el_pt->disable_projection();
1376 if (backed_up_doc_time_enabled)
1429 if (Problem::mesh_pt()->
nelement() == 0)
return;
1441 const unsigned n_dim = this->
mesh_pt()->node_pt(0)->ndim();
1443 this->
mesh_pt()->node_pt(0)->nposition_type();
1453 for (
unsigned i = 0;
i <
n_dim;
i++)
1470 if (Problem::mesh_pt()->
nelement() == 0)
return;
1481 const unsigned n_dim = this->
mesh_pt()->node_pt(0)->ndim();
1483 this->
mesh_pt()->node_pt(0)->nposition_type();
1491 for (
unsigned i = 0;
i <
n_dim;
i++)
1507 if (Problem::mesh_pt()->
nelement() == 0)
return;
1510 const unsigned n_element = Problem::mesh_pt()->nelement();
1514 unsigned nint =
el_pt->ninternal_data();
1515 for (
unsigned j = 0;
j <
nint;
j++)
1519 for (
unsigned i = 0;
i <
nval;
i++)
1526 for (
unsigned j = 0;
j <
nnod;
j++)
1530 for (
unsigned i = 0;
i <
nval;
i++)
1551 const unsigned n_dim = this->
mesh_pt()->node_pt(0)->ndim();
1553 this->
mesh_pt()->node_pt(0)->nposition_type();
1560 for (
unsigned i = 0;
i <
n_dim;
i++)
1564 solid_nod_pt->pin_position(
k,
i);
1577 if (Problem::mesh_pt()->
nelement() == 0)
return;
1580 const unsigned n_element = Problem::mesh_pt()->nelement();
1618 const unsigned n_dim = this->
mesh_pt()->node_pt(0)->ndim();
1620 this->
mesh_pt()->node_pt(0)->nposition_type();
1627 for (
unsigned i = 0;
i <
n_dim;
i++)
1631 solid_nod_pt->unpin_position(
k,
i);
1642 const unsigned n_node = Problem::mesh_pt()->nnode();
1651 Problem::mesh_pt()->node_pt(0)->nposition_type();
1657 static_cast<SolidNode*
>(Problem::mesh_pt()->node_pt(
n));
1670 const unsigned n_node = Problem::mesh_pt()->nnode();
1679 Problem::mesh_pt()->node_pt(0)->nposition_type();
1685 static_cast<SolidNode*
>(Problem::mesh_pt()->node_pt(
n));
1698 unsigned n_element = Problem::mesh_pt()->nelement();
1718 unsigned n_element = Problem::mesh_pt()->nelement();
1738 unsigned n_element = Problem::mesh_pt()->nelement();
1752 unsigned n_element = Problem::mesh_pt()->nelement();
1769 unsigned n_element = Problem::mesh_pt()->nelement();
1779 new_el_pt->projected_lagrangian_coordinate() =
i;
1786 unsigned n_element = Problem::mesh_pt()->nelement();
Template-free Base class for projectable elements.
bool Backup_external_interaction_data
Remember if the element includes external data when used in non-projection mode (this is temporarily ...
unsigned Projected_lagrangian
When projecting the Lagrangain coordinates indicate which coordiante is to be projected.
Projection_Type Projection_type
Variable to indicate if we're projecting the history values of the nodal coordinates (Coordinate) the...
virtual unsigned nvalue_of_field(const unsigned &fld)=0
Return number of values (pinned or not) associated with field fld within the element....
virtual Vector< std::pair< Data *, unsigned > > data_values_of_field(const unsigned &fld)=0
Pure virtual function in which the element writer must specify the values associated with field fld....
virtual unsigned nfields_for_projection()=0
Number of fields of the problem, so e.g. for 2D Navier Stokes this would be 3 (for the two velocities...
unsigned Time_level_for_projection
Time level we are projecting (0=current values; >0: history values)
unsigned Backup_ninteraction
Store number of "external" interactions that were assigned to the element before doing the projection...
virtual ~ProjectableElementBase()
Virtual destructor.
ProjectableElementBase()
Constructor: Initialise data so that we don't project but solve the "normal" equations associated wit...
bool Do_projection
Bool to know if we do projection or not. If false (the default) we solve the element's "real" equatio...
bool Backup_external_geometric_data
Remember if the element includes external geometric data when used in non-projection mode (this is te...
Projection_Type
Enumerated collection to specify which projection problem is to be solved.
unsigned Projected_field
Field that is currently being projected.
virtual unsigned nhistory_values_for_coordinate_projection()=0
Number of history values to be stored when projecting the history values of the nodal coordinates (in...
unsigned Projected_coordinate
When projecting the history values of the nodal coordinates, this is the coordinate we're projecting.
virtual int local_equation(const unsigned &fld, const unsigned &ivalue)=0
Return local equation numbers associated with value ivalue of field fld within the element.
virtual unsigned nhistory_values_for_projection(const unsigned &fld)=0
Number of history values to be stored for fld-th field (includes current value!)
virtual double jacobian_and_shape_of_field(const unsigned &fld, const Vector< double > &s, Shape &psi)=0
Return Jacobian of mapping and the shape functions associated with field fld. The number of shape fun...
virtual double get_field(const unsigned &time, const unsigned &fld, const Vector< double > &s)=0
Return the fld-th field at local coordinates s at time-level time (time=0: current value; time>0: his...
Wrapper class for projectable elements. Adds "projectability" to the underlying ELEMENT.
void enable_projection()
Backup the element's state and switch it to projection mode.
ProjectableElement()
Constructor [this was only required explicitly from gcc 4.5.2 onwards...].
virtual void residual_for_projection(Vector< double > &residuals, DenseMatrix< double > &jacobian, const unsigned &flag)
Residual for the projection step. Flag indicates if we want the Jacobian (1) or not (0)....
void set_project_values()
Project (history values of) values.
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Overloaded version of fill_in_contribution_to_jacobian.
unsigned & projected_field()
Field that is currently being projected.
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 ...
unsigned & projected_lagrangian_coordinate()
When projecting the Lagrangian coordinates this is the coordinate that is being projected.
void set_project_coordinates()
Project (history values of) coordintes.
unsigned & time_level_for_projection()
Which history value are we projecting?
void set_project_lagrangian()
Project (current and only values of) lagrangian coordinates.
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Overloaded version of fill_in_contribution_to_residuals.
double zeta_nodal(const unsigned &n, const unsigned &k, const unsigned &i) const
Use Eulerian coordinates for matching in locate_zeta when doing projection.
void disable_projection()
Helper function to restore the element to the state it was in before we entered the projection mode a...
unsigned & projected_coordinate()
When projecting the history values of the nodal coordinates, this is the coordinate we're projecting.
Projection problem. This is created during the adaptation of unstructured meshes and it is assumed th...
friend class BackupMeshForProjection
friend class RefineableTriangleMesh
void unpin_dofs_of_field(const unsigned &fld)
Helper function to unpin dofs of fld-th field.
void enable_suppress_output_during_projection()
Suppress all output during projection phases.
ProjectionProblem()
Default constructor (made this private so only the friend class can call the constructor)
void unpin_dofs_of_coordinate(const unsigned &coord)
Helper function to unpin the values of coordinate coord.
void store_positions()
Helper function to store positions (the only things that have been set before doing projection.
bool use_iterative_solver_for_projection()
Return the value of the flag about using an iterative solver for projection.
void set_current_field_for_projection(const unsigned &fld)
Set current field for projection.
bool Output_during_projection_suppressed
Flag to suppress output during projection.
IterativeLinearSolver * Iterative_solver_projection_pt
bool Use_iterative_solver_for_projection
friend class RefineableGmshTetMesh
void set_time_level_for_projection(const unsigned &time_level)
Helper function to set time level for projection.
void set_lagrangian_coordinate_for_projection(const unsigned &i)
Set the Lagrangian coordinate for projection.
friend class RefineableTetgenMesh
void pin_all()
Pin all the field values and position unknowns (bit inefficient)
void disable_use_iterative_solver_for_projection()
Disbales the use of an iterative solver for projection.
void disable_suppress_output_during_projection()
Undo suppression of all output during projection phases.
void unpin_all()
Unpin all the field values and position unknowns (bit inefficient)
Preconditioner * Preconditioner_projection_pt
void pin_dofs_of_field(const unsigned &fld)
Helper function to unpin dofs of fld-th field.
void set_coordinate_for_projection(const unsigned &i)
Set the coordinate for projection.
void project(Mesh *base_mesh_pt, const bool &dont_project_positions=false)
Project from base into the problem's own mesh.
void pin_dofs_of_coordinate(const unsigned &coord)
Helper function to unpin the values of coordinate coord.
void restore_positions()
Helper function to restore positions (the only things that have been set before doing projection.
void enable_use_iterative_solver_for_projection()
Enables the use of an iterative solver for projection.
Vector< DenseMatrix< double > > Solid_backup
Backup for pin status of solid node's position Data.