Constraint definition

Forum for OpenSees users to post questions, comments, etc. on the use of the OpenSees interpreter, OpenSees.exe

Moderators: silvia, selimgunay, Moderators

Post Reply
stealth_mode
Posts: 20
Joined: Fri Dec 23, 2005 3:17 am
Location: Middle East Technical University

Constraint definition

Post by stealth_mode »

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???
silvia
Posts: 3909
Joined: Tue Jan 11, 2005 7:44 am
Location: Degenkolb Engineers
Contact:

Post by silvia »

you could use the multiple-support excitation which imposes different displacement histories at specified nodes.

would this work for you?
Silvia Mazzoni, PhD
Structural Consultant
Degenkolb Engineers
235 Montgomery Street, Suite 500
San Francisco, CA. 94104
stealth_mode
Posts: 20
Joined: Fri Dec 23, 2005 3:17 am
Location: Middle East Technical University

Post by stealth_mode »

Silvia, Thank you for your quick reply :)

Actually, the thing I want to try is to force the frame to respond an earthquake in its first mode of vibration during the earthquake. So, I don't think your suggestion would work for my case. Do you have any other suggestions?
silvia
Posts: 3909
Joined: Tue Jan 11, 2005 7:44 am
Location: Degenkolb Engineers
Contact:

Post by silvia »

tough one, I think, unless you manage to put some sort of springs to control your shape.
otherwise, you might try using really large damping on the higher modes...
Silvia Mazzoni, PhD
Structural Consultant
Degenkolb Engineers
235 Montgomery Street, Suite 500
San Francisco, CA. 94104
stealth_mode
Posts: 20
Joined: Fri Dec 23, 2005 3:17 am
Location: Middle East Technical University

Post by stealth_mode »

I can't figure out how I can use springs to control my shape during response history analysis, but using large damping values for higher modes might be a possible way to handle this constraint problem. I will try for this suggestion and I hope it works...

Thanks a lot, Silvia, for your suggestions!
stealth_mode
Posts: 20
Joined: Fri Dec 23, 2005 3:17 am
Location: Middle East Technical University

Post by stealth_mode »

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:
equal2DOF $retainedNode $constrainedNode $dof $coefficient
In this command, as I indicated before, the relation will be like:
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?
fmk
Site Admin
Posts: 5884
Joined: Fri Jun 11, 2004 2:33 pm
Location: UC Berkeley
Contact:

Post by fmk »

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.
stealth_mode
Posts: 20
Joined: Fri Dec 23, 2005 3:17 am
Location: Middle East Technical University

Post by stealth_mode »

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 :(
stealth_mode
Posts: 20
Joined: Fri Dec 23, 2005 3:17 am
Location: Middle East Technical University

Post by stealth_mode »

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? :?
fmk
Site Admin
Posts: 5884
Joined: Fri Jun 11, 2004 2:33 pm
Location: UC Berkeley
Contact:

Post by fmk »

you are correct .. if the ratio is constant throughout you do not need a time varying MP_Constraint .. instead of creating a new command equal2DOF, i suggest you come up with a better name that is more reflective of what the command is doing.
stealth_mode
Posts: 20
Joined: Fri Dec 23, 2005 3:17 am
Location: Middle East Technical University

Post by stealth_mode »

I see your point about choosing a better name :idea: What about "relativeDOF"?

By the way, Thanks a lot for the suggestions, Frank!
stealth_mode
Posts: 20
Joined: Fri Dec 23, 2005 3:17 am
Location: Middle East Technical University

Post by stealth_mode »

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

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
mycommands.cpp

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;
}


stealth_mode
Posts: 20
Joined: Fri Dec 23, 2005 3:17 am
Location: Middle East Technical University

Post by stealth_mode »

To overcome the error, I changed a small part in RelativeDOF.cpp as:

Code: Select all

// set the values
	for (int i=0; i<dimR; i++) {
      mat(0,0)=ccoefficient;
      id(i) = i;
    }
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. :D

By the way, I know last messages are related with Framework rather than OpenSees.exe Users. Sorry for that!

Thanks again for invaluable help!!!
fmk
Site Admin
Posts: 5884
Joined: Fri Jun 11, 2004 2:33 pm
Location: UC Berkeley
Contact:

Post by fmk »

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.
stealth_mode
Posts: 20
Joined: Fri Dec 23, 2005 3:17 am
Location: Middle East Technical University

Post by stealth_mode »

Thank you for your comments, I will modify my code according to your suggestions.
Post Reply