% File: ~/OOP/analysis/fe_ele/penalty/PenaltyMP_FE.tex 
%What: "@(#) PenaltyMP_FE.tex, revA"

\noindent {\bf Files}   \\
\indent \#include $<\tilde{ }$/analysis/fe\_ele/penalty/PenaltyMP\_FE.h$>$  \\

\noindent {\bf Class Declaration}  \\
\indent class PenaltyMP\_FE: public FE\_Element ;  \\

\noindent {\bf Class Hierarchy}  \\
\indent FE\_Element \\
\indent\indent {\bf PenaltyMP\_FE} \\ 

\noindent {\bf Description}  \\
\indent PenaltyMP\_FE is a subclass of FE\_Element used to enforce a
multi point constraint, of the form $\U_c = \C_{cr} \U_r$, where $\U_c$ are
the constrained degrees-of-freedom at the constrained node, $\U_r$ are
the retained degrees-of-freedom at the retained node and $\C_{cr}$ a
matrix defining the relationship between these degrees-of-freedom. 

To enforce the constraint a matrix $\alpha \C^T \C$ is added to the
tangent for the degrees-of-freedom $[\U_c$ $\U_r]$, where $\C = [-\I$ 
$\C_{cr}]$. Nothing is added to the residual. \\  

\noindent {\bf Class Interface}  \\
\indent\indent // Constructor  \\
\indent\indent {\em PenaltyMP\_FE(Domain \&theDomain, MP\_Constraint
\&theMP, double alpha);} \\ \\
\indent\indent // Destructor  \\
\indent\indent {\em virtual~ $\tilde{}$PenaltyMP\_FE();}  \\ \\
\indent\indent // Public Methods \\
\indent\indent {\em virtual void setID(void);} \\ 
\indent\indent {\em virtual const Matrix \&getTangent(Integrator
*theIntegrator);} \\  
\indent\indent {\em virtual const Vector \&getResidual(Integrator
*theIntegrator);} \\ 
\indent\indent {\em virtual const Vector \&getTangForce(const Vector
\&disp, double fact = 1.0);    }\\

\noindent {\bf Constructor}  \\
\indent {\em PenaltyMP\_FE(Domain \&theDomain, MP\_Constraint \&theMP,
double alpha);}\\
To construct a PenaltyMP\_FE element to enforce the constraint
specified by the MP\_Constraint {\em theMP} using a default value for
$\alpha$ of $alpha$. The FE\_Element class constructor is called with
the integers $2$ and the size of the {\em retainedID} plus the size of
the {\em constrainedID} at the MP\_Constraint {\em theMP}. A Matrix
and a Vector object are created for adding the contributions to the
tangent and the residual. The residual is zeroed. A Matrix is created
to store the $C$ Matrix. If the MP\_Constraint is not time varying,
the components of this Matrix are determined, then the contribution
to the tangent $\alpha C^TC$ is determined and finally the $C$ matrix
is destroyed. Links are set to the retained and constrained nodes.
A warning message is printed and the program is terminated if
either not enough memory is available for the Matrices and Vector or the
constrained and retained Nodes do not exist in the Domain.  \\


\noindent {\bf Destructor}  \\
\indent {\em virtual~ $\tilde{}$PenaltyMP\_FE();}  \\
Invokes delete on any Matrix or Vector objects created in the
constructor that have not yet been destroyed. \\

\noindent {\bf Public Methods}  \\
\indent {\em virtual void setID(void);} \\
Causes the PenaltyMP\_FE to determine the mapping between it's equation
numbers and the degrees-of-freedom. This information is obtained by
using the mapping information at the DOF\_Group objects associated with
the constrained and retained nodes to determine the mappings between
the degrees-of-freedom identified in the {\em constrainedID} and the
{\em retainedID} at the MP\_Constraint {\em theMP}. Returns $0$ if
successful. Prints a warning message and returns a negative number if
an error occurs: $-2$ if the
Node has no associated DOF\_Group, $-3$ if the constrained DOF
specified is invalid for this Node (sets corresponding ID component to
$-1$ so nothing is added to the tangent) and $-4$ if the ID in the
DOF\_Group is too small for the Node (again setting corresponding ID
component to $-1$). \\ 


\indent {\em virtual Matrix \&getTangent(Integrator *theIntegrator);} \\
If the MP\_Constraint is time-varying, from the MP\_Constraint
{\em theMP} it obtains the current $C_{cr}$ matrix; it then forms the
$C$ matrix and finally it sets the tangent matrix to be $\alpha
C^TC$. Returns the tangent matrix. \\

\indent {\em virtual const Vector \&getResidual(Integrator *theIntegrator);} \\
Returns the residual, a $\zero$ Vector. \\

{\em virtual const Vector \&getTangForce(const Vector \&disp, double
fact = 1.0);    }\\
CURRENTLY just returns the $0$ residual. THIS WILL NEED TO CHANGE FOR
ELE-BY-ELE SOLVERS. 

