Constraint definition
Moderators: silvia, selimgunay, Moderators
-
- Posts: 20
- Joined: Fri Dec 23, 2005 3:17 am
- Location: Middle East Technical University
Constraint definition
I have a 2 story single bay frame and want to perform a nonlinear dynamic analysis on this frame. However, for a special condition that I want to check, I have to define a constraint that will force the first story move equal to 80% of the second story's displacement at each time step. Actually, this value will come from the eigen analysis (first mode shape) and I want the frame system to behave in its fundamental mode always!!! (To make it clear, according to this example, eigenvalues for this frame will be 0.8 for the master node at the first story and 1.0 for the master node at the second story.)
Is it possible to define such a constraint with current constraint handlers???
Is it possible to define such a constraint with current constraint handlers???
-
- Posts: 20
- Joined: Fri Dec 23, 2005 3:17 am
- Location: Middle East Technical University
-
- Posts: 20
- Joined: Fri Dec 23, 2005 3:17 am
- Location: Middle East Technical University
-
- Posts: 20
- Joined: Fri Dec 23, 2005 3:17 am
- Location: Middle East Technical University
I tried using large damping values for higher modes to prevent the contribution of these modes. However, I couldn't get what I want. Therefore, I want to implement a command similar to "equalDOF". But for this command, let's say equal2DOF, the parameters will be like:
I examined the source code and I think a short code can be added into MP_constraint.cpp and MP_constraint.h (to modify the constraint matrix that will take 'coefficient' into account) and for the implementation of the "equal2DOF" command, command.cpp must be modified.
Is it so straight to implement a new command? Or are there any other things that I've missed?
In this command, as I indicated before, the relation will be like:equal2DOF $retainedNode $constrainedNode $dof $coefficient
u_{1,x}=$coefficient*u_{2,x} where 1 & 2 are the nodes considered and x is the specified dof.
Actually, $coefficient will be the simplest constraint matrix!
Ex: u_{1,x}=0.8*u_{2,x}
I examined the source code and I think a short code can be added into MP_constraint.cpp and MP_constraint.h (to modify the constraint matrix that will take 'coefficient' into account) and for the implementation of the "equal2DOF" command, command.cpp must be modified.
Is it so straight to implement a new command? Or are there any other things that I've missed?
you caould only use multi-support if you know ahead of time the displacements you wish
to impose .. you cannot do what you describe with the current version of OpenSees .. the
only way you could do it would be to introduce a new type of time-varying multi-point constraint or a new penalty type element.
to impose .. you cannot do what you describe with the current version of OpenSees .. the
only way you could do it would be to introduce a new type of time-varying multi-point constraint or a new penalty type element.
-
- Posts: 20
- Joined: Fri Dec 23, 2005 3:17 am
- Location: Middle East Technical University
Is it because of the fact that the time invariant MP constraint does not update the system matrix although the constraint matrix is constant (which is always equal to $coefficient during the excitation)??
I've thought that;
...Though it's a dynamic analysis, since the coefficient is constant always, I don't have to define a time-varying MP constraint. If you say so, I'm a bit in trouble
I've thought that;
...Though it's a dynamic analysis, since the coefficient is constant always, I don't have to define a time-varying MP constraint. If you say so, I'm a bit in trouble

-
- Posts: 20
- Joined: Fri Dec 23, 2005 3:17 am
- Location: Middle East Technical University
Well, what I have previously asked about modifying MP_constraint.cpp and .h was a wrong attempt I think.
I examined the rigidBeam.cpp and .h that are called by "rigidlink" command through tcl command interpreter and I saw that the constraint matrix is formed in rigidbeam.cpp. Therefore, I think I should add a new command (like "equal2DOF" which I previously expressed) that will call a ?.cpp which will form the constraint matrix Ccr according to the coefficient entered at the command level and then, will call MP_constraint to apply the constraint.
Also, I (again) don't think this is related with time varying issues, since the coefficient is constant always...
Am I wrong again?

I examined the rigidBeam.cpp and .h that are called by "rigidlink" command through tcl command interpreter and I saw that the constraint matrix is formed in rigidbeam.cpp. Therefore, I think I should add a new command (like "equal2DOF" which I previously expressed) that will call a ?.cpp which will form the constraint matrix Ccr according to the coefficient entered at the command level and then, will call MP_constraint to apply the constraint.
Also, I (again) don't think this is related with time varying issues, since the coefficient is constant always...
Am I wrong again?

-
- Posts: 20
- Joined: Fri Dec 23, 2005 3:17 am
- Location: Middle East Technical University
-
- Posts: 20
- Joined: Fri Dec 23, 2005 3:17 am
- Location: Middle East Technical University
For last few days, I was trying to compile the current version with VS. NET, but I had so many errors. Finally, I succeeded. However, there is an error in implementing my own code into OpenSees.
I chose "relativeDOF" as the new command name that will do what I have expressed in my previous messages. (usage of the command will be: relativeDOF $retainednode $constrainednode $constraintcoefficient) (At the moment, I assumed only horizontal displacements @specified nodes will be constrained with using specified coefficients). I added RelativeDOF.cpp and RelativeDOF.h into project (I modified RigidRod.* files in order to create these files) and necessary codes into mycommands.cpp. I successfully compiled the new project and I can access to the command relativeDOF (I can get the error messages of the command if I mis-use the command). However, when I use the command in nonlinear time history analysis, the program gives an error(actually, VStudio Debugger asks whether to ignore it or not). If I ignore the error, OpenSees program gives another error like (constraint matrix not identity, ignoring constraint for node ##, non-varying assumed).
I am also sending the codes that I have implemented. What can be the error related with? Can it be constrainthandler?
RelativeDOF.cpp
RelativeDOF.h
mycommands.cpp
I chose "relativeDOF" as the new command name that will do what I have expressed in my previous messages. (usage of the command will be: relativeDOF $retainednode $constrainednode $constraintcoefficient) (At the moment, I assumed only horizontal displacements @specified nodes will be constrained with using specified coefficients). I added RelativeDOF.cpp and RelativeDOF.h into project (I modified RigidRod.* files in order to create these files) and necessary codes into mycommands.cpp. I successfully compiled the new project and I can access to the command relativeDOF (I can get the error messages of the command if I mis-use the command). However, when I use the command in nonlinear time history analysis, the program gives an error(actually, VStudio Debugger asks whether to ignore it or not). If I ignore the error, OpenSees program gives another error like (constraint matrix not identity, ignoring constraint for node ##, non-varying assumed).
I am also sending the codes that I have implemented. What can be the error related with? Can it be constrainthandler?
RelativeDOF.cpp
Code: Select all
#include <stdlib.h>
#include <OPS_Globals.h>
#include <Domain.h>
#include <Node.h>
#include <MP_Constraint.h>
#include <Matrix.h>
#include <ID.h>
#include <RelativeDOF.h>
RelativeDOF::RelativeDOF(Domain &theDomain, int nR, int nC, double ccoefficient, int mPtag) {
// get a pointer to the retained node and constrained nodes - ensure these exist
Node *nodeR = theDomain.getNode(nR);
if (nodeR == 0) {
opserr << "RelativeDOF::RelativeDOF - retained Node" << nR << "not in domain\n";
return;
}
Node *nodeC = theDomain.getNode(nC);
if (nodeR == 0) {
opserr << "RelativeDOF::RelativeDOF - constrained Node" << nC << "not in domain\n";
return;
}
// get the coordinates of the two nodes - check dimensions are the same
const Vector &crdR = nodeR->getCrds();
const Vector &crdC = nodeC->getCrds();
int dimR = crdR.Size();
int dimC = crdC.Size();
if (dimR != dimC) {
opserr << "RelativeDOF::RelativeDOF - mismatch in dimension " <<
"between constrained Node " << nC << " and Retained node " << nR << endln;
return;
}
// check the number of dof at each node is the same
int numDOF = nodeR->getNumberDOF();
if (numDOF != nodeC->getNumberDOF()){
opserr << "RelativeDOF::RelativeDOF - mismatch in numDOF " <<
"between constrained Node " << nC << " and Retained node " << nR << endln;
return;
}
// check the number of dof at the nodes >= dimension of problem
if(numDOF < dimR){
opserr << "RelativeDOF::RelativeDOF - numDOF at nodes " << nR << " and " << nC <<
"must be >= dimension of problem\n";
return;
}
// create the ID to identify the constrained dof
ID id(dimR);
// construct the tranformation matrix Ccr, where Uc = Ccr Ur & set the diag
Matrix mat(dimR,dimR);
mat.Zero();
// set the values
id(0)=0;
id(1)=1;
id(2)=2;
mat(0,0)=ccoefficient;
// create the MP_Constraint
MP_Constraint *newC = new MP_Constraint(mPtag, nR, nC, mat, id, id);
if (newC == 0) {
opserr << "RelativeDOF::RelativeDOF - for nodes " << nR << " and " << nC << " out of memory\n";
exit(-1);
} else {
// add the constraint to the domain
if (theDomain.addMP_Constraint(newC) == false) {
opserr << "RelativeDOF::RelativeDOF - for nodes " << nC << " and " << nR << " could not add to domain\n",
delete newC;
}
}
}
RelativeDOF::~RelativeDOF()
{
// does nothing
}
RelativeDOF.h
Code: Select all
#ifndef RelativeDOF_h
#define RelativeDOF_h
class Domain;
class ID;
class RelativeDOF
{
public:
RelativeDOF(Domain &theDomain, int nodeR, int nodeC, double conscoefficient,int startMPtag);
virtual ~RelativeDOF();
protected:
private:
};
#endif
Code: Select all
#include <Domain.h>
#include "TclModelBuilder.h"
#include "TclUniaxialMaterialTester.h"
#include <tcl.h>
#include <tk.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <RelativeDOF.h>
extern ModelBuilder *theBuilder;
extern Domain theDomain;
int
specifyModelBuilder(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv);
int
relativeDOF(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv);
int myCommands(Tcl_Interp *interp) {
Tcl_CreateCommand(interp, "model", specifyModelBuilder,
(ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
Tcl_CreateCommand(interp, "relativeDOF", &relativeDOF,
(ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
return 0;
}
int
relativeDOF(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv)
{
if (argc < 4) {
opserr << "WARNING relativeDOF rNode? Node? Ccoefficient?\n";
return TCL_ERROR;
}
int numMPs = theDomain.getNumMPs();
int rNode, cNode;
double coefficientC;
if (Tcl_GetInt(interp, argv[1], &rNode) != TCL_OK) {
opserr << "WARNING relativeDOF rNode? Node? Ccoefficient? - could not read rNode \n";
return TCL_ERROR;
}
if (Tcl_GetInt(interp, argv[2], &cNode) != TCL_OK) {
opserr << "WARNING relativeDOF rNode? Node? Ccoefficient? - could not read CNode \n";
return TCL_ERROR;
}
if (Tcl_GetDouble(interp, argv[3], &coefficientC) != TCL_OK) {
opserr << "WARNING relativeDOF rNode? Node? Ccoefficient? - could not read Coefficient \n";
return TCL_ERROR;
}
// construct a special constraint
RelativeDOF(theDomain, rNode, cNode,coefficientC, numMPs);
return TCL_OK;
}
int
specifyModelBuilder(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv)
{
// make sure at least one other argument to contain model builder type given
if (argc < 2) {
opserr << "WARNING need to specify a model type, valid types:\n";
opserr << "\tBasicBuilder\n";
return TCL_ERROR;
}
// invoke the descructor on the old builder
if (theBuilder != 0) {
delete theBuilder;
theBuilder = 0;
}
// check argv[1] for type of ModelBuilder and create the object
if (strcmp(argv[1],"basic") == 0 || strcmp(argv[1],"BasicBuilder") == 0) {
int ndm =0;
int ndf = 0;
if (argc < 4) {
opserr << "WARNING incorrect number of command arguments\n";
opserr << "model modelBuilderType -ndm ndm? <-ndf ndf?> \n";
return TCL_ERROR;
}
int argPos = 2;
while (argPos < argc) {
if (strcmp(argv[argPos],"-ndm") == 0 ||
strcmp(argv[argPos],"-NDM") == 0) {
argPos++;
if (argPos < argc)
if (Tcl_GetInt(interp, argv[argPos], &ndm) != TCL_OK) {
opserr << "WARNING error reading ndm: " << argv[argPos];
opserr << "\nmodel modelBuilderType -ndm ndm? <-ndf ndf?>\n";
return TCL_ERROR;
}
argPos++;
}
else if (strcmp(argv[argPos],"-ndf") == 0 ||
strcmp(argv[argPos],"-NDF") == 0) {
argPos++;
if (argPos < argc)
if (Tcl_GetInt(interp, argv[argPos], &ndf) != TCL_OK) {
opserr << "WARNING error reading ndf: " << argv[argPos];
opserr << "\nmodel modelBuilderType -ndm ndm? <-ndf ndf?>\n";
return TCL_ERROR;
}
argPos++;
}
else // Advance to next input argument if there are no matches -- MHS
argPos++;
}
// check that ndm was specified
if (ndm == 0) {
opserr << "WARNING need to specify ndm\n";
opserr << "model modelBuilderType -ndm ndm? <-ndf ndf?>\n";
return TCL_ERROR;
}
// check for ndf, if not assume one
if (ndf == 0) {
if (ndm == 1)
ndf = 1;
else if (ndm == 2)
ndf = 3;
else if (ndm == 3)
ndf = 6;
else {
opserr << "WARNING specified ndm, " << ndm << ", will not work\n";
opserr << "with any elements in BasicBuilder\n";
return TCL_ERROR;
}
}
// create the model builder
theBuilder = new TclModelBuilder(theDomain, interp, ndm, ndf);
if (theBuilder == 0) {
opserr << "WARNING ran out of memory in creating BasicBuilder model\n";
return TCL_ERROR;
}
}
else if (strcmp(argv[1],"test") == 0 || strcmp(argv[1],"TestUniaxial") == 0) {
int count = 1;
if (argc == 3) {
if (Tcl_GetInt(interp, argv[2], &count) != TCL_OK) {
return TCL_ERROR;
}
}
theBuilder = new TclUniaxialMaterialTester(theDomain, interp, count);
if (theBuilder == 0) {
opserr << "WARNING ran out of memory in creating TclUniaxialMAterialTester model\n";
return TCL_ERROR;
}
}
else
{
Tcl_SetResult(interp, "WARNING unknown model builder type", TCL_STATIC);
opserr << "WARNING model builder type " << argv[1]
<< " not supported\n";
return TCL_ERROR;
}
return TCL_OK;
}
-
- Posts: 20
- Joined: Fri Dec 23, 2005 3:17 am
- Location: Middle East Technical University
To overcome the error, I changed a small part in RelativeDOF.cpp as:
Debugger does not give any error, but the error related with constrainthandler remained as it was. So, I changed my constrainthandler (for dynamic analysis) to Penalty (It was Plain before) with both parameters 1e12. I think, at last, I can get the correct results that I want.
By the way, I know last messages are related with Framework rather than OpenSees.exe Users. Sorry for that!
Thanks again for invaluable help!!!
Code: Select all
// set the values
for (int i=0; i<dimR; i++) {
mat(0,0)=ccoefficient;
id(i) = i;
}

By the way, I know last messages are related with Framework rather than OpenSees.exe Users. Sorry for that!
Thanks again for invaluable help!!!
for your case dimR should be 1 .. your matrix and id only need be of size 1 .. you only want to constrain the first dof, the other dof's need to be unconstrained. For using other transformation constraint handlers (will work with Penalty) you may need to redo the code to sepcify the id(0) = 0; mat(0,0)=coefficient and the size of dimR as 1.
-
- Posts: 20
- Joined: Fri Dec 23, 2005 3:17 am
- Location: Middle East Technical University