Subversion Repositories OpenSees

Rev

Rev 4070 | Rev 4591 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4070 Rev 4431
Line 1... Line -...
1
/* ****************************************************************** **
-
 
2
**    OpenSees - Open System for Earthquake Engineering Simulation    **
-
 
3
**          Pacific Earthquake Engineering Research Center            **
-
 
4
**                                                                    **
-
 
5
**                                                                    **
-
 
6
** (C) Copyright 1999, The Regents of the University of California    **
-
 
7
** All Rights Reserved.                                               **
-
 
8
**                                                                    **
-
 
9
** Commercial use of this program without express permission of the   **
-
 
10
** University of California, Berkeley, is strictly prohibited.  See   **
-
 
11
** file 'COPYRIGHT'  in main directory for information on usage and   **
-
 
12
** redistribution,  and for a DISCLAIMER OF ALL WARRANTIES.           **
-
 
13
**                                                                    **
-
 
14
** Developed by:                                                      **
-
 
15
**   Frank McKenna (fmckenna@ce.berkeley.edu)                         **
-
 
16
**   Gregory L. Fenves (fenves@ce.berkeley.edu)                       **
-
 
17
**   Filip C. Filippou (filippou@ce.berkeley.edu)                     **
-
 
18
**                                                                    **
-
 
19
** ****************************************************************** */
-
 
20
-
 
21
// $Revision: 1.2 $
-
 
22
// $Date: 2009-11-03 23:12:33 $
-
 
23
// $Source: /usr/local/cvs/OpenSees/SRC/element/frictionBearing/FlatSliderSimple2d.cpp,v $
-
 
24
-
 
25
// Written: Andreas Schellenberg (andreas.schellenberg@gmx.net)
-
 
26
// Created: 02/06
-
 
27
// Revision: A
-
 
28
//
-
 
29
// Description: This file contains the implementation of the
-
 
30
// FlatSliderSimple2d class.
-
 
31
-
 
32
#include "FlatSliderSimple2d.h"
-
 
33
-
 
34
#include <Domain.h>
-
 
35
#include <Node.h>
-
 
36
#include <Channel.h>
-
 
37
#include <FEM_ObjectBroker.h>
-
 
38
#include <Renderer.h>
-
 
39
#include <Information.h>
-
 
40
#include <ElementResponse.h>
-
 
41
#include <FrictionModel.h>
-
 
42
#include <UniaxialMaterial.h>
-
 
43
-
 
44
#include <float.h>
-
 
45
#include <math.h>
-
 
46
#include <stdlib.h>
-
 
47
#include <string.h>
-
 
48
-
 
49
-
 
50
// initialize the class wide variables
-
 
51
Matrix FlatSliderSimple2d::theMatrix(6,6);
-
 
52
Vector FlatSliderSimple2d::theVector(6);
-
 
53
Vector FlatSliderSimple2d::theLoad(6);
-
 
54
-
 
55
-
 
56
FlatSliderSimple2d::FlatSliderSimple2d(int tag, int Nd1, int Nd2,
-
 
57
    FrictionModel &thefrnmdl, double _uy, UniaxialMaterial **materials,
-
 
58
    const Vector _y, const Vector _x, double m, int maxiter, double _tol)
-
 
59
    : Element(tag, ELE_TAG_FlatSliderSimple2d),
-
 
60
    connectedExternalNodes(2), theFrnMdl(0),
-
 
61
    uy(_uy), x(_x), y(_y), mass(m), maxIter(maxiter), tol(_tol),
-
 
62
    L(0.0), ub(3), ubPlastic(0.0), qb(3), kb(3,3), ul(6),
-
 
63
    Tgl(6,6), Tlb(3,6), ubPlasticC(0.0), kbInit(3,3)
-
 
64
{
-
 
65
    // ensure the connectedExternalNode ID is of correct size & set values
-
 
66
    if (connectedExternalNodes.Size() != 2)  {
-
 
67
        opserr << "FlatSliderSimple2d::FlatSliderSimple2d() - element: "
-
 
68
            << this->getTag() << " failed to create an ID of size 2\n";
-
 
69
    }
-
 
70
   
-
 
71
    connectedExternalNodes(0) = Nd1;
-
 
72
    connectedExternalNodes(1) = Nd2;
-
 
73
   
-
 
74
    // set node pointers to NULL
-
 
75
    for (int i=0; i<2; i++)
-
 
76
        theNodes[i] = 0;
-
 
77
   
-
 
78
    // get a copy of the friction model
-
 
79
        theFrnMdl = thefrnmdl.getCopy();
-
 
80
        if (theFrnMdl == 0)  {
-
 
81
                opserr << "FlatSliderSimple2d::FlatSliderSimple2d() - "
-
 
82
                        << "failed to get copy of the friction model.\n";
-
 
83
                exit(-1);
-
 
84
        }
-
 
85
   
-
 
86
    // check material input
-
 
87
    if (materials == 0)  {
-
 
88
        opserr << "FlatSliderSimple2d::FlatSliderSimple2d() - "
-
 
89
            << "null material array passed.\n";
-
 
90
        exit(-1);
-
 
91
    }
-
 
92
   
-
 
93
    // get copies of the uniaxial materials
-
 
94
    for (int i=0; i<2; i++)  {
-
 
95
        if (materials[i] == 0) {
-
 
96
            opserr << "FlatSliderSimple2d::FlatSliderSimple2d() - "
-
 
97
                "null uniaxial material pointer passed.\n";
-
 
98
            exit(-1);
-
 
99
        }
-
 
100
        theMaterials[i] = materials[i]->getCopy();
-
 
101
        if (theMaterials[i] == 0) {
-
 
102
            opserr << "FlatSliderSimple2d::FlatSliderSimple2d() - "
-
 
103
                << "failed to copy uniaxial material.\n";
-
 
104
            exit(-1);
-
 
105
        }
-
 
106
    }
-
 
107
   
-
 
108
    // initialize initial stiffness matrix
-
 
109
    kbInit.Zero();
-
 
110
    kbInit(0,0) = theMaterials[0]->getInitialTangent();
-
 
111
    kbInit(1,1) = kbInit(0,0)*DBL_EPSILON;
-
 
112
    kbInit(2,2) = theMaterials[1]->getInitialTangent();
-
 
113
   
-
 
114
    // initialize other variables
-
 
115
    this->revertToStart();
-
 
116
}
-
 
117
-
 
118
-
 
119
FlatSliderSimple2d::FlatSliderSimple2d()
-
 
120
    : Element(0, ELE_TAG_FlatSliderSimple2d),
-
 
121
    connectedExternalNodes(2), theFrnMdl(0),
-
 
122
    uy(0.0), x(0), y(0), mass(0.0), maxIter(20), tol(1E-8),
-
 
123
    L(0.0), ub(3), ubPlastic(0.0), qb(3), kb(3,3), ul(6),
-
 
124
    Tgl(6,6), Tlb(3,6), ubPlasticC(0.0), kbInit(3,3)
-
 
125
{      
-
 
126
    // ensure the connectedExternalNode ID is of correct size
-
 
127
        if (connectedExternalNodes.Size() != 2)  {
-
 
128
                opserr << "FlatSliderSimple2d::FlatSliderSimple2d() - "
-
 
129
                        <<  "failed to create an ID of size 2\n";
-
 
130
                exit(-1);
-
 
131
    }
-
 
132
   
-
 
133
    // set node pointers to NULL
-
 
134
        for (int i=0; i<2; i++)
-
 
135
                theNodes[i] = 0;
-
 
136
   
-
 
137
    // set material pointers to NULL
-
 
138
        for (int i=0; i<2; i++)
-
 
139
                theMaterials[i] = 0;
-
 
140
}
-
 
141
-
 
142
-
 
143
FlatSliderSimple2d::~FlatSliderSimple2d()
-
 
144
{
-
 
145
    // invoke the destructor on any objects created by the object
-
 
146
    // that the object still holds a pointer to
-
 
147
    if (theFrnMdl)
-
 
148
                delete theFrnMdl;
-
 
149
   
-
 
150
    for (int i=0; i<2; i++)
-
 
151
        if (theMaterials[i] != 0)
-
 
152
            delete theMaterials[i];
-
 
153
}
-
 
154
-
 
155
-
 
156
int FlatSliderSimple2d::getNumExternalNodes() const
-
 
157
{
-
 
158
    return 2;
-
 
159
}
-
 
160
-
 
161
-
 
162
const ID& FlatSliderSimple2d::getExternalNodes()
-
 
163
{
-
 
164
    return connectedExternalNodes;
-
 
165
}
-
 
166
-
 
167
-
 
168
Node** FlatSliderSimple2d::getNodePtrs()
-
 
169
{
-
 
170
        return theNodes;
-
 
171
}
-
 
172
-
 
173
-
 
174
int FlatSliderSimple2d::getNumDOF()
-
 
175
{
-
 
176
    return 6;
-
 
177
}
-
 
178
-
 
179
-
 
180
void FlatSliderSimple2d::setDomain(Domain *theDomain)
-
 
181
{
-
 
182
    // check Domain is not null - invoked when object removed from a domain
-
 
183
    if (!theDomain)  {
-
 
184
                theNodes[0] = 0;
-
 
185
                theNodes[1] = 0;
-
 
186
-
 
187
                return;
-
 
188
    }
-
 
189
   
-
 
190
    // first set the node pointers
-
 
191
    theNodes[0] = theDomain->getNode(connectedExternalNodes(0));
-
 
192
    theNodes[1] = theDomain->getNode(connectedExternalNodes(1));       
-
 
193
       
-
 
194
    // if can't find both - send a warning message
-
 
195
    if (!theNodes[0] || !theNodes[1])  {
-
 
196
                if (!theNodes[0])  {
-
 
197
                        opserr << "WARNING FlatSliderSimple2d::setDomain() - Nd1: "
-
 
198
                                << connectedExternalNodes(0) << " does not exist in the model for ";
-
 
199
                } else  {
-
 
200
                        opserr << "WARNING FlatSliderSimple2d::setDomain() - Nd2: "
-
 
201
                                << connectedExternalNodes(1) << " does not exist in the model for ";
-
 
202
                }
-
 
203
                opserr << "FlatSliderSimple2d ele: " << this->getTag() << endln;
-
 
204
               
-
 
205
                return;
-
 
206
    }
-
 
207
       
-
 
208
        // now determine the number of dof and the dimension    
-
 
209
        int dofNd1 = theNodes[0]->getNumberDOF();
-
 
210
        int dofNd2 = theNodes[1]->getNumberDOF();      
-
 
211
       
-
 
212
        // if differing dof at the ends - print a warning message
-
 
213
    if (dofNd1 != 3)  {
-
 
214
                opserr << "FlatSliderSimple2d::setDomain() - node 1: "
-
 
215
                        << connectedExternalNodes(0) << " has incorrect number of DOF (not 3)\n";
-
 
216
                return;
-
 
217
    }
-
 
218
    if (dofNd2 != 3)  {
-
 
219
                opserr << "FlatSliderSimple2d::setDomain() - node 2: "
-
 
220
                        << connectedExternalNodes(1) << " has incorrect number of DOF (not 3)\n";
-
 
221
                return;
-
 
222
    }
-
 
223
       
-
 
224
    // call the base class method
-
 
225
    this->DomainComponent::setDomain(theDomain);
-
 
226
   
-
 
227
    // set up the transformation matrix for orientation
-
 
228
    this->setUp();
-
 
229
}
-
 
230
-
 
231
-
 
232
int FlatSliderSimple2d::commitState()
-
 
233
{
-
 
234
        int errCode = 0;
-
 
235
   
-
 
236
    // commit trial history variables
-
 
237
    ubPlasticC = ubPlastic;
-
 
238
       
-
 
239
    // commit friction model
-
 
240
        errCode += theFrnMdl->commitState();
-
 
241
   
-
 
242
    // commit material models
-
 
243
    for (int i=0; i<2; i++)
-
 
244
            errCode += theMaterials[i]->commitState();
-
 
245
   
-
 
246
    return errCode;
-
 
247
}
-
 
248
-
 
249
-
 
250
int FlatSliderSimple2d::revertToLastCommit()
-
 
251
{
-
 
252
    int errCode = 0;
-
 
253
   
-
 
254
    // revert friction model
-
 
255
        errCode += theFrnMdl->revertToLastCommit();
-
 
256
   
-
 
257
    // revert material models
-
 
258
    for (int i=0; i<2; i++)
-
 
259
            errCode += theMaterials[i]->revertToLastCommit();
-
 
260
   
-
 
261
    return errCode;
-
 
262
}
-
 
263
-
 
264
-
 
265
int FlatSliderSimple2d::revertToStart()
-
 
266
{  
-
 
267
    int errCode = 0;
-
 
268
   
-
 
269
    // reset trial history variables
-
 
270
    ub.Zero();
-
 
271
    ubPlastic = 0.0;
-
 
272
    qb.Zero();
-
 
273
   
-
 
274
    // reset committed history variables
-
 
275
    ubPlasticC = 0.0;
-
 
276
   
-
 
277
    // reset stiffness matrix in basic system
-
 
278
    kb = kbInit;
-
 
279
   
-
 
280
    // revert friction model
-
 
281
    errCode += theFrnMdl->revertToStart();
-
 
282
   
-
 
283
    // revert material models
-
 
284
    for (int i=0; i<2; i++)
-
 
285
        errCode += theMaterials[i]->revertToStart();
-
 
286
   
-
 
287
    return errCode;
-
 
288
}
-
 
289
-
 
290
-
 
291
int FlatSliderSimple2d::update()
-
 
292
{
-
 
293
    // get global trial displacements and velocities
-
 
294
    const Vector &dsp1 = theNodes[0]->getTrialDisp();
-
 
295
    const Vector &dsp2 = theNodes[1]->getTrialDisp();
-
 
296
    const Vector &vel1 = theNodes[0]->getTrialVel();
-
 
297
    const Vector &vel2 = theNodes[1]->getTrialVel();
-
 
298
   
-
 
299
    static Vector ug(6), ugdot(6), uldot(6), ubdot(3);
-
 
300
    for (int i=0; i<3; i++)  {
-
 
301
        ug(i)   = dsp1(i);  ugdot(i)   = vel1(i);
-
 
302
        ug(i+3) = dsp2(i);  ugdot(i+3) = vel2(i);
-
 
303
    }
-
 
304
   
-
 
305
    // transform response from the global to the local system
-
 
306
    ul = Tgl*ug;
-
 
307
    uldot = Tgl*ugdot;
-
 
308
   
-
 
309
    // transform response from the local to the basic system
-
 
310
    ub = Tlb*ul;
-
 
311
    ubdot = Tlb*uldot;
-
 
312
   
-
 
313
    // get absolute velocity
-
 
314
    double ubdotAbs = ubdot(1);
-
 
315
   
-
 
316
    // 1) get axial force and stiffness in basic x-direction
-
 
317
    double ub0Old = theMaterials[0]->getStrain();
-
 
318
    theMaterials[0]->setTrialStrain(ub(0),ubdot(0));
-
 
319
    qb(0) = theMaterials[0]->getStress();
-
 
320
    kb(0,0) = theMaterials[0]->getTangent();
-
 
321
   
-
 
322
    // check for uplift
-
 
323
    if (qb(0) >= 0.0)  {
-
 
324
        kb = kbInit;
-
 
325
        if (qb(0) > 0.0)  {
-
 
326
            theMaterials[0]->setTrialStrain(ub0Old,0.0);
-
 
327
            kb(0,0) *= DBL_EPSILON;
-
 
328
        }
-
 
329
        qb.Zero();
-
 
330
        return 0;
-
 
331
    }
-
 
332
   
-
 
333
    // 2) calculate shear force and stiffness in basic y-direction
-
 
334
    int iter = 0;
-
 
335
    double qb1Old = 0.0;
-
 
336
    do  {
-
 
337
        // save old shear force
-
 
338
        qb1Old = qb(1);
-
 
339
       
-
 
340
        // get normal and friction (yield) forces
-
 
341
        double N = -qb(0) - qb(1)*ul(2);
-
 
342
        theFrnMdl->setTrial(N, ubdotAbs);
-
 
343
        double qYield = (theFrnMdl->getFrictionForce());
-
 
344
       
-
 
345
        // get initial stiffness of hysteretic component
-
 
346
        double k0 = qYield/uy;
-
 
347
       
-
 
348
        // get trial shear force of hysteretic component
-
 
349
        double qTrial = k0*(ub(1) - ubPlasticC);
-
 
350
       
-
 
351
        // compute yield criterion of hysteretic component
-
 
352
        double qTrialNorm = fabs(qTrial);
-
 
353
        double Y = qTrialNorm - qYield;
-
 
354
       
-
 
355
        // elastic step -> no updates required
-
 
356
        if (Y <= 0.0)  {
-
 
357
            // set shear force
-
 
358
            qb(1) = qTrial - N*ul(2);
-
 
359
            // set tangent stiffness
-
 
360
            kb(1,1) = k0;
-
 
361
        }
-
 
362
        // plastic step -> return mapping
-
 
363
        else  {
-
 
364
            // compute consistency parameter
-
 
365
            double dGamma = Y/k0;
-
 
366
            // update plastic displacement
-
 
367
            ubPlastic = ubPlasticC + dGamma*qTrial/qTrialNorm;
-
 
368
            // set shear force
-
 
369
            qb(1) = qYield*qTrial/qTrialNorm - N*ul(2);
-
 
370
            // set tangent stiffness
-
 
371
            kb(1,1) = 0.0;
-
 
372
        }
-
 
373
        iter++;
-
 
374
    } while ((fabs(qb(1)-qb1Old) >= tol) && (iter <= maxIter));
-
 
375
   
-
 
376
    // issue warning if iteration did not converge
-
 
377
    if (iter >= maxIter)  {
-
 
378
        opserr << "WARNING: FlatSliderSimple2d::update() - did not find the shear force after "
-
 
379
            << iter << " iterations and norm: " << fabs(qb(1)-qb1Old) << endln;
-
 
380
        return -1;
-
 
381
    }
-
 
382
   
-
 
383
    // 3) get moment and stiffness in basic z-direction
-
 
384
    theMaterials[1]->setTrialStrain(ub(2),ubdot(2));
-
 
385
    qb(2) = theMaterials[1]->getStress();
-
 
386
    kb(2,2) = theMaterials[1]->getTangent();
-
 
387
   
-
 
388
    return 0;
-
 
389
}
-
 
390
-
 
391
-
 
392
const Matrix& FlatSliderSimple2d::getTangentStiff()
-
 
393
{
-
 
394
    // zero the matrix
-
 
395
    theMatrix.Zero();
-
 
396
   
-
 
397
    // transform from basic to local system
-
 
398
    static Matrix kl(6,6);
-
 
399
    kl.addMatrixTripleProduct(0.0, Tlb, kb, 1.0);
-
 
400
   
-
 
401
    // add geometric stiffness to local stiffness
-
 
402
    kl(2,1) -= 1.0*qb(0);
-
 
403
    kl(2,4) += 1.0*qb(0);
-
 
404
    //kl(5,1) -= 0.0*qb(0);
-
 
405
    //kl(5,4) += 0.0*qb(0);
-
 
406
   
-
 
407
    // transform from local to global system
-
 
408
    theMatrix.addMatrixTripleProduct(0.0, Tgl, kl, 1.0);
-
 
409
   
-
 
410
    return theMatrix;
-
 
411
}
-
 
412
-
 
413
-
 
414
const Matrix& FlatSliderSimple2d::getInitialStiff()
-
 
415
{
-
 
416
    // zero the matrix
-
 
417
    theMatrix.Zero();
-
 
418
   
-
 
419
    // transform from basic to local system
-
 
420
    static Matrix kl(6,6);
-
 
421
    kl.addMatrixTripleProduct(0.0, Tlb, kbInit, 1.0);
-
 
422
   
-
 
423
    // transform from local to global system
-
 
424
    theMatrix.addMatrixTripleProduct(0.0, Tgl, kl, 1.0);
-
 
425
   
-
 
426
    return theMatrix;
-
 
427
}
-
 
428
-
 
429
-
 
430
const Matrix& FlatSliderSimple2d::getMass()
-
 
431
{
-
 
432
        // zero the matrix
-
 
433
    theMatrix.Zero();
-
 
434
   
-
 
435
        // check for quick return
-
 
436
        if (mass == 0.0)  {
-
 
437
                return theMatrix;
-
 
438
        }
-
 
439
   
-
 
440
        double m = 0.5*mass;
-
 
441
        for (int i=0; i<2; i++)  {
-
 
442
                theMatrix(i,i)     = m;
-
 
443
                theMatrix(i+3,i+3) = m;
-
 
444
        }
-
 
445
       
-
 
446
    return theMatrix;
-
 
447
}
-
 
448
-
 
449
-
 
450
void FlatSliderSimple2d::zeroLoad()
-
 
451
{
-
 
452
    theLoad.Zero();
-
 
453
}
-
 
454
-
 
455
-
 
456
int FlatSliderSimple2d::addLoad(ElementalLoad *theLoad, double loadFactor)
-
 
457
{  
-
 
458
        opserr <<"FlatSliderSimple2d::addLoad() - "
-
 
459
                << "load type unknown for element: "
-
 
460
                << this->getTag() << endln;
-
 
461
-
 
462
        return -1;
-
 
463
}
-
 
464
-
 
465
-
 
466
int FlatSliderSimple2d::addInertiaLoadToUnbalance(const Vector &accel)
-
 
467
{
-
 
468
        // check for quick return
-
 
469
        if (mass == 0.0)  {
-
 
470
                return 0;
-
 
471
        }    
-
 
472
   
-
 
473
        // get R * accel from the nodes
-
 
474
        const Vector &Raccel1 = theNodes[0]->getRV(accel);
-
 
475
        const Vector &Raccel2 = theNodes[1]->getRV(accel);
-
 
476
       
-
 
477
        if (3 != Raccel1.Size() || 3 != Raccel2.Size())  {
-
 
478
                opserr << "FlatSliderSimple2d::addInertiaLoadToUnbalance() - "
-
 
479
                        << "matrix and vector sizes are incompatible\n";
-
 
480
                return -1;
-
 
481
        }
-
 
482
   
-
 
483
        // want to add ( - fact * M R * accel ) to unbalance
-
 
484
        // take advantage of lumped mass matrix
-
 
485
        double m = 0.5*mass;
-
 
486
    for (int i=0; i<2; i++)  {
-
 
487
        theLoad(i)   -= m * Raccel1(i);
-
 
488
        theLoad(i+3) -= m * Raccel2(i);
-
 
489
    }
-
 
490
   
-
 
491
        return 0;
-
 
492
}
-
 
493
-
 
494
-
 
495
const Vector& FlatSliderSimple2d::getResistingForce()
-
 
496
{
-
 
497
    // zero the residual
-
 
498
    theVector.Zero();
-
 
499
   
-
 
500
    // determine resisting forces in local system
-
 
501
    static Vector ql(6);
-
 
502
    ql = Tlb^qb;
-
 
503
   
-
 
504
    // add P-Delta moments to local forces
-
 
505
    double MpDelta = qb(0)*(ul(4)-ul(1));
-
 
506
    ql(2) += 1.0*MpDelta;
-
 
507
    //ql(5) += 0.0*MpDelta;
-
 
508
   
-
 
509
    // determine resisting forces in global system
-
 
510
    theVector = Tgl^ql;
-
 
511
   
-
 
512
    // subtract external load
-
 
513
    theVector.addVector(1.0, theLoad, -1.0);
-
 
514
   
-
 
515
    return theVector;
-
 
516
}
-
 
517
-
 
518
-
 
519
const Vector& FlatSliderSimple2d::getResistingForceIncInertia()
-
 
520
{      
-
 
521
        theVector = this->getResistingForce();
-
 
522
       
-
 
523
        // add the damping forces if rayleigh damping
-
 
524
        if (alphaM != 0.0 || betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0)
-
 
525
                theVector += this->getRayleighDampingForces();
-
 
526
   
-
 
527
        // now include the mass portion
-
 
528
        if (mass != 0.0)  {
-
 
529
                const Vector &accel1 = theNodes[0]->getTrialAccel();
-
 
530
                const Vector &accel2 = theNodes[1]->getTrialAccel();    
-
 
531
               
-
 
532
                double m = 0.5*mass;
-
 
533
                for (int i=0; i<2; i++)  {
-
 
534
                        theVector(i)   += m * accel1(i);
-
 
535
                        theVector(i+3) += m * accel2(i);
-
 
536
                }
-
 
537
        }
-
 
538
       
-
 
539
        return theVector;
-
 
540
}
-
 
541
-
 
542
-
 
543
int FlatSliderSimple2d::sendSelf(int commitTag, Channel &sChannel)
-
 
544
{
-
 
545
    // send element parameters
-
 
546
    static Vector data(7);
-
 
547
    data(0) = this->getTag();
-
 
548
    data(1) = uy;
-
 
549
    data(2) = mass;
-
 
550
    data(3) = maxIter;
-
 
551
    data(4) = tol;
-
 
552
    data(5) = x.Size();
-
 
553
    data(6) = y.Size();
-
 
554
    sChannel.sendVector(0, commitTag, data);
-
 
555
   
-
 
556
    // send the two end nodes
-
 
557
    sChannel.sendID(0, commitTag, connectedExternalNodes);
-
 
558
   
-
 
559
    // send the friction model class tag
-
 
560
    ID frnClassTag(1);
-
 
561
    frnClassTag(0) = theFrnMdl->getClassTag();
-
 
562
    sChannel.sendID(0, commitTag, frnClassTag);
-
 
563
   
-
 
564
    // send the friction model
-
 
565
    theFrnMdl->sendSelf(commitTag, sChannel);
-
 
566
   
-
 
567
    // send the material class tags
-
 
568
    ID matClassTags(2);
-
 
569
    for (int i=0; i<2; i++)
-
 
570
        matClassTags(i) = theMaterials[i]->getClassTag();
-
 
571
    sChannel.sendID(0, commitTag, matClassTags);
-
 
572
   
-
 
573
    // send the material models
-
 
574
    for (int i=0; i<2; i++)
-
 
575
        theMaterials[i]->sendSelf(commitTag, sChannel);
-
 
576
   
-
 
577
    // send remaining data
-
 
578
    if (x.Size() == 3)
-
 
579
        sChannel.sendVector(0, commitTag, x);
-
 
580
    if (y.Size() == 3)
-
 
581
        sChannel.sendVector(0, commitTag, y);
-
 
582
   
-
 
583
    return 0;
-
 
584
}
-
 
585
-
 
586
-
 
587
int FlatSliderSimple2d::recvSelf(int commitTag, Channel &rChannel,
-
 
588
    FEM_ObjectBroker &theBroker)
-
 
589
{
-
 
590
    // delete material memory
-
 
591
    for (int i=0; i<2; i++)
-
 
592
        if (theMaterials[i] != 0)
-
 
593
            delete theMaterials[i];
-
 
594
   
-
 
595
    // receive element parameters
-
 
596
    static Vector data(7);
-
 
597
    rChannel.recvVector(0, commitTag, data);
-
 
598
    this->setTag((int)data(0));
-
 
599
    uy = data(1);
-
 
600
    mass = data(2);
-
 
601
    maxIter = (int)data(3);
-
 
602
    tol = data(4);
-
 
603
   
-
 
604
    // receive the two end nodes
-
 
605
    rChannel.recvID(0, commitTag, connectedExternalNodes);
-
 
606
   
-
 
607
    // receive the friction model class tag
-
 
608
    ID frnClassTag(1);
-
 
609
    rChannel.recvID(0, commitTag, frnClassTag);
-
 
610
   
-
 
611
    // receive the friction model
-
 
612
    theFrnMdl = theBroker.getNewFrictionModel(frnClassTag(0));
-
 
613
    if (theFrnMdl == 0) {
-
 
614
        opserr << "FlatSliderSimple2d::recvSelf() - "
-
 
615
            << "failed to get blank friction model.\n";
-
 
616
        return -1;
-
 
617
    }
-
 
618
    theFrnMdl->recvSelf(commitTag, rChannel, theBroker);
-
 
619
   
-
 
620
    // receive the material class tags
-
 
621
    ID matClassTags(2);
-
 
622
    rChannel.recvID(0, commitTag, matClassTags);
-
 
623
   
-
 
624
    // receive the material models
-
 
625
    for (int i=0; i<2; i++)  {
-
 
626
        theMaterials[i] = theBroker.getNewUniaxialMaterial(matClassTags(i));
-
 
627
        if (theMaterials[i] == 0) {
-
 
628
            opserr << "FlatSliderSimple2d::recvSelf() - "
-
 
629
                << "failed to get blank uniaxial material.\n";
-
 
630
            return -2;
-
 
631
        }
-
 
632
        theMaterials[i]->recvSelf(commitTag, rChannel, theBroker);
-
 
633
    }
-
 
634
   
-
 
635
    // receive remaining data
-
 
636
    if ((int)data(5) == 3)  {
-
 
637
        x.resize(3);
-
 
638
        rChannel.recvVector(0, commitTag, x);
-
 
639
    }
-
 
640
    if ((int)data(6) == 3)  {
-
 
641
        y.resize(3);
-
 
642
        rChannel.recvVector(0, commitTag, y);
-
 
643
    }
-
 
644
   
-
 
645
    // initialize initial stiffness matrix
-
 
646
    kbInit.Zero();
-
 
647
    kbInit(0,0) = theMaterials[0]->getInitialTangent();
-
 
648
    kbInit(1,1) = kbInit(0,0)*DBL_EPSILON;
-
 
649
    kbInit(2,2) = theMaterials[1]->getInitialTangent();
-
 
650
   
-
 
651
    // initialize other variables
-
 
652
    this->revertToStart();
-
 
653
   
-
 
654
    return 0;
-
 
655
}
-
 
656
-
 
657
-
 
658
int FlatSliderSimple2d::displaySelf(Renderer &theViewer,
-
 
659
    int displayMode, float fact)
-
 
660
{
-
 
661
    // first determine the end points of the element based on
-
 
662
    // the display factor (a measure of the distorted image)
-
 
663
    const Vector &end1Crd = theNodes[0]->getCrds();
-
 
664
    const Vector &end2Crd = theNodes[1]->getCrds();    
-
 
665
   
-
 
666
    const Vector &end1Disp = theNodes[0]->getDisp();
-
 
667
    const Vector &end2Disp = theNodes[1]->getDisp();
-
 
668
   
-
 
669
    static Vector v1(3);
-
 
670
    static Vector v2(3);
-
 
671
   
-
 
672
    for (int i=0; i<2; i++)  {
-
 
673
        v1(i) = end1Crd(i) + end1Disp(i)*fact;
-
 
674
        v2(i) = end2Crd(i) + end2Disp(i)*fact;    
-
 
675
    }
-
 
676
   
-
 
677
    return theViewer.drawLine (v1, v2, 1.0, 1.0);
-
 
678
}
-
 
679
-
 
680
-
 
681
void FlatSliderSimple2d::Print(OPS_Stream &s, int flag)
-
 
682
{
-
 
683
    if (flag == 0)  {
-
 
684
        // print everything
-
 
685
                s << "Element: " << this->getTag();
-
 
686
                s << "  type: FlatSliderSimple2d  iNode: " << connectedExternalNodes(0);
-
 
687
                s << "  jNode: " << connectedExternalNodes(1) << endln;
-
 
688
        s << "  FrictionModel: " << theFrnMdl->getTag() << endln;
-
 
689
        s << "  uy: " << uy << endln;
-
 
690
        s << "  Material ux: " << theMaterials[0]->getTag() << endln;
-
 
691
        s << "  Material rz: " << theMaterials[1]->getTag() << endln;
-
 
692
        s << "  mass: " << mass << "  maxIter: " << maxIter << "  tol: " << tol << endln;
-
 
693
        // determine resisting forces in global system
-
 
694
        s << "  resisting force: " << this->getResistingForce() << endln;
-
 
695
    } else if (flag == 1)  {
-
 
696
                // does nothing
-
 
697
    }
-
 
698
}
-
 
699
-
 
700
-
 
701
Response* FlatSliderSimple2d::setResponse(const char **argv, int argc,
-
 
702
    OPS_Stream &output)
-
 
703
{
-
 
704
    Response *theResponse = 0;
-
 
705
-
 
706
    output.tag("ElementOutput");
-
 
707
    output.attr("eleType","FlatSliderSimple2d");
-
 
708
    output.attr("eleTag",this->getTag());
-
 
709
    output.attr("node1",connectedExternalNodes[0]);
-
 
710
    output.attr("node2",connectedExternalNodes[1]);
-
 
711
-
 
712
    // global forces
-
 
713
    if (strcmp(argv[0],"force") == 0 ||
-
 
714
        strcmp(argv[0],"forces") == 0 ||
-
 
715
        strcmp(argv[0],"globalForce") == 0 ||
-
 
716
        strcmp(argv[0],"globalForces") == 0)
-
 
717
    {
-
 
718
        output.tag("ResponseType","Px_1");
-
 
719
        output.tag("ResponseType","Py_1");
-
 
720
        output.tag("ResponseType","Mz_1");
-
 
721
        output.tag("ResponseType","Px_2");
-
 
722
        output.tag("ResponseType","Py_2");
-
 
723
        output.tag("ResponseType","Mz_2");
-
 
724
-
 
725
        theResponse = new ElementResponse(this, 1, theVector);
-
 
726
    }
-
 
727
    // local forces
-
 
728
    else if (strcmp(argv[0],"localForce") == 0 ||
-
 
729
        strcmp(argv[0],"localForces") == 0)
-
 
730
    {
-
 
731
        output.tag("ResponseType","N_1");
-
 
732
        output.tag("ResponseType","V_1");
-
 
733
        output.tag("ResponseType","M_1");
-
 
734
        output.tag("ResponseType","N_2");
-
 
735
        output.tag("ResponseType","V_2");
-
 
736
        output.tag("ResponseType","M_2");
-
 
737
-
 
738
        theResponse = new ElementResponse(this, 2, theVector);
-
 
739
    }
-
 
740
    // basic forces
-
 
741
    else if (strcmp(argv[0],"basicForce") == 0 ||
-
 
742
        strcmp(argv[0],"basicForces") == 0)
-
 
743
    {
-
 
744
        output.tag("ResponseType","qb1");
-
 
745
        output.tag("ResponseType","qb2");
-
 
746
        output.tag("ResponseType","qb3");
-
 
747
-
 
748
        theResponse = new ElementResponse(this, 3, Vector(3));
-
 
749
    }
-
 
750
        // local displacements
-
 
751
    else if (strcmp(argv[0],"localDisplacement") == 0 ||
-
 
752
        strcmp(argv[0],"localDisplacements") == 0)
-
 
753
    {
-
 
754
        output.tag("ResponseType","ux_1");
-
 
755
        output.tag("ResponseType","uy_1");
-
 
756
        output.tag("ResponseType","rz_1");
-
 
757
        output.tag("ResponseType","ux_2");
-
 
758
        output.tag("ResponseType","uy_2");
-
 
759
        output.tag("ResponseType","rz_2");
-
 
760
       
-
 
761
        theResponse = new ElementResponse(this, 4, theVector);
-
 
762
    }
-
 
763
        // basic displacements
-
 
764
    else if (strcmp(argv[0],"deformation") == 0 ||
-
 
765
        strcmp(argv[0],"deformations") == 0 ||
-
 
766
        strcmp(argv[0],"basicDeformation") == 0 ||
-
 
767
        strcmp(argv[0],"basicDeformations") == 0 ||
-
 
768
        strcmp(argv[0],"basicDisplacement") == 0 ||
-
 
769
        strcmp(argv[0],"basicDisplacements") == 0)
-
 
770
    {
-
 
771
        output.tag("ResponseType","ub1");
-
 
772
        output.tag("ResponseType","ub2");
-
 
773
        output.tag("ResponseType","ub3");
-
 
774
       
-
 
775
        theResponse = new ElementResponse(this, 5, Vector(3));
-
 
776
    }
-
 
777
    // material output
-
 
778
    else if (strcmp(argv[0],"material") == 0)  {
-
 
779
        if (argc > 2)  {
-
 
780
            int matNum = atoi(argv[1]);
-
 
781
            if (matNum >= 1 && matNum <= 2)
-
 
782
                theResponse =  theMaterials[matNum-1]->setResponse(&argv[2], argc-2, output);
-
 
783
        }
-
 
784
    }
-
 
785
   
-
 
786
    output.endTag(); // ElementOutput
-
 
787
   
-
 
788
    return theResponse;
-
 
789
}
-
 
790
-
 
791
-
 
792
int FlatSliderSimple2d::getResponse(int responseID, Information &eleInfo)
-
 
793
{
-
 
794
    double MpDelta;
-
 
795
-
 
796
        switch (responseID)  {
-
 
797
        case 1:  // global forces
-
 
798
        return eleInfo.setVector(this->getResistingForce());
-
 
799
       
-
 
800
        case 2:  // local forces
-
 
801
        theVector.Zero();
-
 
802
        // determine resisting forces in local system
-
 
803
        theVector = Tlb^qb;
-
 
804
        // add P-Delta moments
-
 
805
        MpDelta = qb(0)*(ul(4)-ul(1));
-
 
806
        theVector(2) += 1.0*MpDelta;
-
 
807
        //theVector(5) += 0.0*MpDelta;
-
 
808
       
-
 
809
        return eleInfo.setVector(theVector);
-
 
810
       
-
 
811
        case 3:  // basic forces
-
 
812
        return eleInfo.setVector(qb);
-
 
813
       
-
 
814
        case 4:  // local displacements
-
 
815
        return eleInfo.setVector(ul);
-
 
816
       
-
 
817
        case 5:  // basic displacements
-
 
818
        return eleInfo.setVector(ub);
-
 
819
       
-
 
820
    default:
-
 
821
                return -1;
-
 
822
        }
-
 
823
}
-
 
824
-
 
825
-
 
826
// establish the external nodes and set up the transformation matrix for orientation
-
 
827
void FlatSliderSimple2d::setUp()
-
 
828
{
-
 
829
    const Vector &end1Crd = theNodes[0]->getCrds();
-
 
830
    const Vector &end2Crd = theNodes[1]->getCrds();    
-
 
831
    Vector xp = end2Crd - end1Crd;
-
 
832
    L = xp.Norm();
-
 
833
   
-
 
834
    if (L > DBL_EPSILON)  {
-
 
835
        if (x.Size() == 0)  {
-
 
836
            x.resize(3);
-
 
837
            x(0) = xp(0);  x(1) = xp(1);  x(2) = 0.0;
-
 
838
            y.resize(3);
-
 
839
            y(0) = -x(1);  y(1) = x(0);  y(2) = 0.0;
-
 
840
        } else  {
-
 
841
            opserr << "WARNING FlatSliderSimple2d::setUp() - "
-
 
842
                << "element: " << this->getTag() << endln
-
 
843
                << "ignoring nodes and using specified "
-
 
844
                << "local x vector to determine orientation\n";
-
 
845
        }
-
 
846
    }
-
 
847
    // check that vectors for orientation are of correct size
-
 
848
    if (x.Size() != 3 || y.Size() != 3)  {
-
 
849
        opserr << "FlatSliderSimple2d::setUp() - "
-
 
850
            << "element: " << this->getTag() << endln
-
 
851
            << "incorrect dimension of orientation vectors\n";
-
 
852
        exit(-1);
-
 
853
    }
-
 
854
   
-
 
855
    // establish orientation of element for the tranformation matrix
-
 
856
    // z = x cross y
-
 
857
    Vector z(3);
-
 
858
    z(0) = x(1)*y(2) - x(2)*y(1);
-
 
859
    z(1) = x(2)*y(0) - x(0)*y(2);
-
 
860
    z(2) = x(0)*y(1) - x(1)*y(0);
-
 
861
   
-
 
862
    // y = z cross x
-
 
863
    y(0) = z(1)*x(2) - z(2)*x(1);
-
 
864
    y(1) = z(2)*x(0) - z(0)*x(2);
-
 
865
    y(2) = z(0)*x(1) - z(1)*x(0);
-
 
866
   
-
 
867
    // compute length(norm) of vectors
-
 
868
    double xn = x.Norm();
-
 
869
    double yn = y.Norm();
-
 
870
    double zn = z.Norm();
-
 
871
   
-
 
872
    // check valid x and y vectors, i.e. not parallel and of zero length
-
 
873
    if (xn == 0 || yn == 0 || zn == 0)  {
-
 
874
        opserr << "FlatSliderSimple2d::setUp() - "
-
 
875
            << "element: " << this->getTag() << endln
-
 
876
            << "invalid orientation vectors\n";
-
 
877
        exit(-1);
-
 
878
    }
-
 
879
   
-
 
880
    // create transformation matrix from global to local system
-
 
881
    Tgl.Zero();
-
 
882
    Tgl(0,0) = Tgl(3,3) = x(0)/xn;
-
 
883
    Tgl(0,1) = Tgl(3,4) = x(1)/xn;
-
 
884
    Tgl(1,0) = Tgl(4,3) = y(0)/yn;
-
 
885
    Tgl(1,1) = Tgl(4,4) = y(1)/yn;
-
 
886
    Tgl(2,2) = Tgl(5,5) = z(2)/zn;
-
 
887
   
-
 
888
    // create transformation matrix from local to basic system (linear)
-
 
889
    Tlb.Zero();
-
 
890
    Tlb(0,0) = Tlb(1,1) = Tlb(2,2) = -1.0;
-
 
891
    Tlb(0,3) = Tlb(1,4) = Tlb(2,5) = 1.0;
-
 
892
    Tlb(1,5) = -L;    
-
 
893
}
-
 
894
-
 
895
-
 
896
double FlatSliderSimple2d::sgn(double x)
-
 
897
{
-
 
898
    if (x > 0)
-
 
899
        return 1.0;
-
 
900
    else if (x < 0)
-
 
901
        return -1.0;
-
 
902
    else
-
 
903
        return 0.0;
-
 
904
}
-
 
-
 
1
/* ****************************************************************** **
-
 
2
**    OpenSees - Open System for Earthquake Engineering Simulation    **
-
 
3
**          Pacific Earthquake Engineering Research Center            **
-
 
4
**                                                                    **
-
 
5
**                                                                    **
-
 
6
** (C) Copyright 1999, The Regents of the University of California    **
-
 
7
** All Rights Reserved.                                               **
-
 
8
**                                                                    **
-
 
9
** Commercial use of this program without express permission of the   **
-
 
10
** University of California, Berkeley, is strictly prohibited.  See   **
-
 
11
** file 'COPYRIGHT'  in main directory for information on usage and   **
-
 
12
** redistribution,  and for a DISCLAIMER OF ALL WARRANTIES.           **
-
 
13
**                                                                    **
-
 
14
** Developed by:                                                      **
-
 
15
**   Frank McKenna (fmckenna@ce.berkeley.edu)                         **
-
 
16
**   Gregory L. Fenves (fenves@ce.berkeley.edu)                       **
-
 
17
**   Filip C. Filippou (filippou@ce.berkeley.edu)                     **
-
 
18
**                                                                    **
-
 
19
** ****************************************************************** */
-
 
20
-
 
21
// $Revision: 4431 $
-
 
22
// $Date: 2011-03-02 08:03:33 -0800 (Wed, 02 Mar 2011) $
-
 
23
// $URL: file:///usr/local/svn/OpenSees/trunk/SRC/element/frictionBearing/FlatSliderSimple2d.cpp $
-
 
24
-
 
25
// Written: Andreas Schellenberg (andreas.schellenberg@gmx.net)
-
 
26
// Created: 02/06
-
 
27
// Revision: A
-
 
28
//
-
 
29
// Description: This file contains the implementation of the
-
 
30
// FlatSliderSimple2d class.
-
 
31
-
 
32
#include "FlatSliderSimple2d.h"
-
 
33
-
 
34
#include <Domain.h>
-
 
35
#include <Node.h>
-
 
36
#include <Channel.h>
-
 
37
#include <FEM_ObjectBroker.h>
-
 
38
#include <Renderer.h>
-
 
39
#include <Information.h>
-
 
40
#include <ElementResponse.h>
-
 
41
#include <FrictionModel.h>
-
 
42
#include <UniaxialMaterial.h>
-
 
43
-
 
44
#include <float.h>
-
 
45
#include <math.h>
-
 
46
#include <stdlib.h>
-
 
47
#include <string.h>
-
 
48
-
 
49
-
 
50
// initialize the class wide variables
-
 
51
Matrix FlatSliderSimple2d::theMatrix(6,6);
-
 
52
Vector FlatSliderSimple2d::theVector(6);
-
 
53
Vector FlatSliderSimple2d::theLoad(6);
-
 
54
-
 
55
-
 
56
FlatSliderSimple2d::FlatSliderSimple2d(int tag, int Nd1, int Nd2,
-
 
57
    FrictionModel &thefrnmdl, double _uy, UniaxialMaterial **materials,
-
 
58
    const Vector _y, const Vector _x, double m, int maxiter, double _tol)
-
 
59
    : Element(tag, ELE_TAG_FlatSliderSimple2d),
-
 
60
    connectedExternalNodes(2), theFrnMdl(0),
-
 
61
    uy(_uy), x(_x), y(_y), mass(m), maxIter(maxiter), tol(_tol),
-
 
62
    L(0.0), ub(3), ubPlastic(0.0), qb(3), kb(3,3), ul(6),
-
 
63
    Tgl(6,6), Tlb(3,6), ubPlasticC(0.0), kbInit(3,3)
-
 
64
{
-
 
65
    // ensure the connectedExternalNode ID is of correct size & set values
-
 
66
    if (connectedExternalNodes.Size() != 2)  {
-
 
67
        opserr << "FlatSliderSimple2d::FlatSliderSimple2d() - element: "
-
 
68
            << this->getTag() << " failed to create an ID of size 2\n";
-
 
69
    }
-
 
70
   
-
 
71
    connectedExternalNodes(0) = Nd1;
-
 
72
    connectedExternalNodes(1) = Nd2;
-
 
73
   
-
 
74
    // set node pointers to NULL
-
 
75
    for (int i=0; i<2; i++)
-
 
76
        theNodes[i] = 0;
-
 
77
   
-
 
78
    // get a copy of the friction model
-
 
79
        theFrnMdl = thefrnmdl.getCopy();
-
 
80
        if (theFrnMdl == 0)  {
-
 
81
                opserr << "FlatSliderSimple2d::FlatSliderSimple2d() - "
-
 
82
                        << "failed to get copy of the friction model.\n";
-
 
83
                exit(-1);
-
 
84
        }
-
 
85
   
-
 
86
    // check material input
-
 
87
    if (materials == 0)  {
-
 
88
        opserr << "FlatSliderSimple2d::FlatSliderSimple2d() - "
-
 
89
            << "null material array passed.\n";
-
 
90
        exit(-1);
-
 
91
    }
-
 
92
   
-
 
93
    // get copies of the uniaxial materials
-
 
94
    for (int i=0; i<2; i++)  {
-
 
95
        if (materials[i] == 0) {
-
 
96
            opserr << "FlatSliderSimple2d::FlatSliderSimple2d() - "
-
 
97
                "null uniaxial material pointer passed.\n";
-
 
98
            exit(-1);
-
 
99
        }
-
 
100
        theMaterials[i] = materials[i]->getCopy();
-
 
101
        if (theMaterials[i] == 0) {
-
 
102
            opserr << "FlatSliderSimple2d::FlatSliderSimple2d() - "
-
 
103
                << "failed to copy uniaxial material.\n";
-
 
104
            exit(-1);
-
 
105
        }
-
 
106
    }
-
 
107
   
-
 
108
    // initialize initial stiffness matrix
-
 
109
    kbInit.Zero();
-
 
110
    kbInit(0,0) = theMaterials[0]->getInitialTangent();
-
 
111
    kbInit(1,1) = kbInit(0,0)*DBL_EPSILON;
-
 
112
    kbInit(2,2) = theMaterials[1]->getInitialTangent();
-
 
113
   
-
 
114
    // initialize other variables
-
 
115
    this->revertToStart();
-
 
116
}
-
 
117
-
 
118
-
 
119
FlatSliderSimple2d::FlatSliderSimple2d()
-
 
120
    : Element(0, ELE_TAG_FlatSliderSimple2d),
-
 
121
    connectedExternalNodes(2), theFrnMdl(0),
-
 
122
    uy(0.0), x(0), y(0), mass(0.0), maxIter(20), tol(1E-8),
-
 
123
    L(0.0), ub(3), ubPlastic(0.0), qb(3), kb(3,3), ul(6),
-
 
124
    Tgl(6,6), Tlb(3,6), ubPlasticC(0.0), kbInit(3,3)
-
 
125
{      
-
 
126
    // ensure the connectedExternalNode ID is of correct size
-
 
127
        if (connectedExternalNodes.Size() != 2)  {
-
 
128
                opserr << "FlatSliderSimple2d::FlatSliderSimple2d() - "
-
 
129
                        <<  "failed to create an ID of size 2\n";
-
 
130
                exit(-1);
-
 
131
    }
-
 
132
   
-
 
133
    // set node pointers to NULL
-
 
134
        for (int i=0; i<2; i++)
-
 
135
                theNodes[i] = 0;
-
 
136
   
-
 
137
    // set material pointers to NULL
-
 
138
        for (int i=0; i<2; i++)
-
 
139
                theMaterials[i] = 0;
-
 
140
}
-
 
141
-
 
142
-
 
143
FlatSliderSimple2d::~FlatSliderSimple2d()
-
 
144
{
-
 
145
    // invoke the destructor on any objects created by the object
-
 
146
    // that the object still holds a pointer to
-
 
147
    if (theFrnMdl)
-
 
148
                delete theFrnMdl;
-
 
149
   
-
 
150
    for (int i=0; i<2; i++)
-
 
151
        if (theMaterials[i] != 0)
-
 
152
            delete theMaterials[i];
-
 
153
}
-
 
154
-
 
155
-
 
156
int FlatSliderSimple2d::getNumExternalNodes() const
-
 
157
{
-
 
158
    return 2;
-
 
159
}
-
 
160
-
 
161
-
 
162
const ID& FlatSliderSimple2d::getExternalNodes()
-
 
163
{
-
 
164
    return connectedExternalNodes;
-
 
165
}
-
 
166
-
 
167
-
 
168
Node** FlatSliderSimple2d::getNodePtrs()
-
 
169
{
-
 
170
        return theNodes;
-
 
171
}
-
 
172
-
 
173
-
 
174
int FlatSliderSimple2d::getNumDOF()
-
 
175
{
-
 
176
    return 6;
-
 
177
}
-
 
178
-
 
179
-
 
180
void FlatSliderSimple2d::setDomain(Domain *theDomain)
-
 
181
{
-
 
182
    // check Domain is not null - invoked when object removed from a domain
-
 
183
    if (!theDomain)  {
-
 
184
                theNodes[0] = 0;
-
 
185
                theNodes[1] = 0;
-
 
186
-
 
187
                return;
-
 
188
    }
-
 
189
   
-
 
190
    // first set the node pointers
-
 
191
    theNodes[0] = theDomain->getNode(connectedExternalNodes(0));
-
 
192
    theNodes[1] = theDomain->getNode(connectedExternalNodes(1));       
-
 
193
       
-
 
194
    // if can't find both - send a warning message
-
 
195
    if (!theNodes[0] || !theNodes[1])  {
-
 
196
                if (!theNodes[0])  {
-
 
197
                        opserr << "WARNING FlatSliderSimple2d::setDomain() - Nd1: "
-
 
198
                                << connectedExternalNodes(0) << " does not exist in the model for ";
-
 
199
                } else  {
-
 
200
                        opserr << "WARNING FlatSliderSimple2d::setDomain() - Nd2: "
-
 
201
                                << connectedExternalNodes(1) << " does not exist in the model for ";
-
 
202
                }
-
 
203
                opserr << "FlatSliderSimple2d ele: " << this->getTag() << endln;
-
 
204
               
-
 
205
                return;
-
 
206
    }
-
 
207
       
-
 
208
        // now determine the number of dof and the dimension    
-
 
209
        int dofNd1 = theNodes[0]->getNumberDOF();
-
 
210
        int dofNd2 = theNodes[1]->getNumberDOF();      
-
 
211
       
-
 
212
        // if differing dof at the ends - print a warning message
-
 
213
    if (dofNd1 != 3)  {
-
 
214
                opserr << "FlatSliderSimple2d::setDomain() - node 1: "
-
 
215
                        << connectedExternalNodes(0) << " has incorrect number of DOF (not 3)\n";
-
 
216
                return;
-
 
217
    }
-
 
218
    if (dofNd2 != 3)  {
-
 
219
                opserr << "FlatSliderSimple2d::setDomain() - node 2: "
-
 
220
                        << connectedExternalNodes(1) << " has incorrect number of DOF (not 3)\n";
-
 
221
                return;
-
 
222
    }
-
 
223
       
-
 
224
    // call the base class method
-
 
225
    this->DomainComponent::setDomain(theDomain);
-
 
226
   
-
 
227
    // set up the transformation matrix for orientation
-
 
228
    this->setUp();
-
 
229
}
-
 
230
-
 
231
-
 
232
int FlatSliderSimple2d::commitState()
-
 
233
{
-
 
234
        int errCode = 0;
-
 
235
   
-
 
236
    // commit trial history variables
-
 
237
    ubPlasticC = ubPlastic;
-
 
238
       
-
 
239
    // commit friction model
-
 
240
        errCode += theFrnMdl->commitState();
-
 
241
   
-
 
242
    // commit material models
-
 
243
    for (int i=0; i<2; i++)
-
 
244
            errCode += theMaterials[i]->commitState();
-
 
245
   
-
 
246
    return errCode;
-
 
247
}
-
 
248
-
 
249
-
 
250
int FlatSliderSimple2d::revertToLastCommit()
-
 
251
{
-
 
252
    int errCode = 0;
-
 
253
   
-
 
254
    // revert friction model
-
 
255
        errCode += theFrnMdl->revertToLastCommit();
-
 
256
   
-
 
257
    // revert material models
-
 
258
    for (int i=0; i<2; i++)
-
 
259
            errCode += theMaterials[i]->revertToLastCommit();
-
 
260
   
-
 
261
    return errCode;
-
 
262
}
-
 
263
-
 
264
-
 
265
int FlatSliderSimple2d::revertToStart()
-
 
266
{  
-
 
267
    int errCode = 0;
-
 
268
   
-
 
269
    // reset trial history variables
-
 
270
    ub.Zero();
-
 
271
    ubPlastic = 0.0;
-
 
272
    qb.Zero();
-
 
273
   
-
 
274
    // reset committed history variables
-
 
275
    ubPlasticC = 0.0;
-
 
276
   
-
 
277
    // reset stiffness matrix in basic system
-
 
278
    kb = kbInit;
-
 
279
   
-
 
280
    // revert friction model
-
 
281
    errCode += theFrnMdl->revertToStart();
-
 
282
   
-
 
283
    // revert material models
-
 
284
    for (int i=0; i<2; i++)
-
 
285
        errCode += theMaterials[i]->revertToStart();
-
 
286
   
-
 
287
    return errCode;
-
 
288
}
-
 
289
-
 
290
-
 
291
int FlatSliderSimple2d::update()
-
 
292
{
-
 
293
    // get global trial displacements and velocities
-
 
294
    const Vector &dsp1 = theNodes[0]->getTrialDisp();
-
 
295
    const Vector &dsp2 = theNodes[1]->getTrialDisp();
-
 
296
    const Vector &vel1 = theNodes[0]->getTrialVel();
-
 
297
    const Vector &vel2 = theNodes[1]->getTrialVel();
-
 
298
   
-
 
299
    static Vector ug(6), ugdot(6), uldot(6), ubdot(3);
-
 
300
    for (int i=0; i<3; i++)  {
-
 
301
        ug(i)   = dsp1(i);  ugdot(i)   = vel1(i);
-
 
302
        ug(i+3) = dsp2(i);  ugdot(i+3) = vel2(i);
-
 
303
    }
-
 
304
   
-
 
305
    // transform response from the global to the local system
-
 
306
    ul = Tgl*ug;
-
 
307
    uldot = Tgl*ugdot;
-
 
308
   
-
 
309
    // transform response from the local to the basic system
-
 
310
    ub = Tlb*ul;
-
 
311
    ubdot = Tlb*uldot;
-
 
312
   
-
 
313
    // get absolute velocity
-
 
314
    double ubdotAbs = ubdot(1);
-
 
315
   
-
 
316
    // 1) get axial force and stiffness in basic x-direction
-
 
317
    double ub0Old = theMaterials[0]->getStrain();
-
 
318
    theMaterials[0]->setTrialStrain(ub(0),ubdot(0));
-
 
319
    qb(0) = theMaterials[0]->getStress();
-
 
320
    kb(0,0) = theMaterials[0]->getTangent();
-
 
321
   
-
 
322
    // check for uplift
-
 
323
    if (qb(0) >= 0.0)  {
-
 
324
        kb = kbInit;
-
 
325
        if (qb(0) > 0.0)  {
-
 
326
            theMaterials[0]->setTrialStrain(ub0Old,0.0);
-
 
327
            kb(0,0) *= DBL_EPSILON;
-
 
328
            kb(2,2) *= DBL_EPSILON;
-
 
329
            // update plastic displacement
-
 
330
            ubPlastic = ub(1);
-
 
331
        }
-
 
332
        qb.Zero();
-
 
333
        return 0;
-
 
334
    }
-
 
335
   
-
 
336
    // 2) calculate shear force and stiffness in basic y-direction
-
 
337
    int iter = 0;
-
 
338
    double qb1Old = 0.0;
-
 
339
    do  {
-
 
340
        // save old shear force
-
 
341
        qb1Old = qb(1);
-
 
342
       
-
 
343
        // get normal and friction (yield) forces
-
 
344
        double N = -qb(0) - qb(1)*ul(2);
-
 
345
        theFrnMdl->setTrial(N, ubdotAbs);
-
 
346
        double qYield = (theFrnMdl->getFrictionForce());
-
 
347
       
-
 
348
        // get initial stiffness of hysteretic component
-
 
349
        double k0 = qYield/uy;
-
 
350
       
-
 
351
        // get trial shear force of hysteretic component
-
 
352
        double qTrial = k0*(ub(1) - ubPlasticC);
-
 
353
       
-
 
354
        // compute yield criterion of hysteretic component
-
 
355
        double qTrialNorm = fabs(qTrial);
-
 
356
        double Y = qTrialNorm - qYield;
-
 
357
       
-
 
358
        // elastic step -> no updates required
-
 
359
        if (Y <= 0.0)  {
-
 
360
            // set shear force
-
 
361
            qb(1) = qTrial - N*ul(2);
-
 
362
            // set tangent stiffness
-
 
363
            kb(1,1) = k0;
-
 
364
        }
-
 
365
        // plastic step -> return mapping
-
 
366
        else  {
-
 
367
            // compute consistency parameter
-
 
368
            double dGamma = Y/k0;
-
 
369
            // update plastic displacement
-
 
370
            ubPlastic = ubPlasticC + dGamma*qTrial/qTrialNorm;
-
 
371
            // set shear force
-
 
372
            qb(1) = qYield*qTrial/qTrialNorm - N*ul(2);
-
 
373
            // set tangent stiffness
-
 
374
            kb(1,1) = 0.0;
-
 
375
        }
-
 
376
        iter++;
-
 
377
    } while ((fabs(qb(1)-qb1Old) >= tol) && (iter <= maxIter));
-
 
378
   
-
 
379
    // issue warning if iteration did not converge
-
 
380
    if (iter >= maxIter)  {
-
 
381
        opserr << "WARNING: FlatSliderSimple2d::update() - did not find the shear force after "
-
 
382
            << iter << " iterations and norm: " << fabs(qb(1)-qb1Old) << endln;
-
 
383
        return -1;
-
 
384
    }
-
 
385
   
-
 
386
    // 3) get moment and stiffness in basic z-direction
-
 
387
    theMaterials[1]->setTrialStrain(ub(2),ubdot(2));
-
 
388
    qb(2) = theMaterials[1]->getStress();
-
 
389
    kb(2,2) = theMaterials[1]->getTangent();
-
 
390
   
-
 
391
    return 0;
-
 
392
}
-
 
393
-
 
394
-
 
395
const Matrix& FlatSliderSimple2d::getTangentStiff()
-
 
396
{
-
 
397
    // zero the matrix
-
 
398
    theMatrix.Zero();
-
 
399
   
-
 
400
    // transform from basic to local system
-
 
401
    static Matrix kl(6,6);
-
 
402
    kl.addMatrixTripleProduct(0.0, Tlb, kb, 1.0);
-
 
403
   
-
 
404
    // add geometric stiffness to local stiffness
-
 
405
    kl(2,1) -= 1.0*qb(0);
-
 
406
    kl(2,4) += 1.0*qb(0);
-
 
407
    //kl(5,1) -= 0.0*qb(0);
-
 
408
    //kl(5,4) += 0.0*qb(0);
-
 
409
   
-
 
410
    // transform from local to global system
-
 
411
    theMatrix.addMatrixTripleProduct(0.0, Tgl, kl, 1.0);
-
 
412
   
-
 
413
    return theMatrix;
-
 
414
}
-
 
415
-
 
416
-
 
417
const Matrix& FlatSliderSimple2d::getInitialStiff()
-
 
418
{
-
 
419
    // zero the matrix
-
 
420
    theMatrix.Zero();
-
 
421
   
-
 
422
    // transform from basic to local system
-
 
423
    static Matrix kl(6,6);
-
 
424
    kl.addMatrixTripleProduct(0.0, Tlb, kbInit, 1.0);
-
 
425
   
-
 
426
    // transform from local to global system
-
 
427
    theMatrix.addMatrixTripleProduct(0.0, Tgl, kl, 1.0);
-
 
428
   
-
 
429
    return theMatrix;
-
 
430
}
-
 
431
-
 
432
-
 
433
const Matrix& FlatSliderSimple2d::getMass()
-
 
434
{
-
 
435
        // zero the matrix
-
 
436
    theMatrix.Zero();
-
 
437
   
-
 
438
        // check for quick return
-
 
439
        if (mass == 0.0)  {
-
 
440
                return theMatrix;
-
 
441
        }
-
 
442
   
-
 
443
        double m = 0.5*mass;
-
 
444
        for (int i=0; i<2; i++)  {
-
 
445
                theMatrix(i,i)     = m;
-
 
446
                theMatrix(i+3,i+3) = m;
-
 
447
        }
-
 
448
       
-
 
449
    return theMatrix;
-
 
450
}
-
 
451
-
 
452
-
 
453
void FlatSliderSimple2d::zeroLoad()
-
 
454
{
-
 
455
    theLoad.Zero();
-
 
456
}
-
 
457
-
 
458
-
 
459
int FlatSliderSimple2d::addLoad(ElementalLoad *theLoad, double loadFactor)
-
 
460
{  
-
 
461
        opserr <<"FlatSliderSimple2d::addLoad() - "
-
 
462
                << "load type unknown for element: "
-
 
463
                << this->getTag() << endln;
-
 
464
-
 
465
        return -1;
-
 
466
}
-
 
467
-
 
468
-
 
469
int FlatSliderSimple2d::addInertiaLoadToUnbalance(const Vector &accel)
-
 
470
{
-
 
471
        // check for quick return
-
 
472
        if (mass == 0.0)  {
-
 
473
                return 0;
-
 
474
        }    
-
 
475
   
-
 
476
        // get R * accel from the nodes
-
 
477
        const Vector &Raccel1 = theNodes[0]->getRV(accel);
-
 
478
        const Vector &Raccel2 = theNodes[1]->getRV(accel);
-
 
479
       
-
 
480
        if (3 != Raccel1.Size() || 3 != Raccel2.Size())  {
-
 
481
                opserr << "FlatSliderSimple2d::addInertiaLoadToUnbalance() - "
-
 
482
                        << "matrix and vector sizes are incompatible\n";
-
 
483
                return -1;
-
 
484
        }
-
 
485
   
-
 
486
        // want to add ( - fact * M R * accel ) to unbalance
-
 
487
        // take advantage of lumped mass matrix
-
 
488
        double m = 0.5*mass;
-
 
489
    for (int i=0; i<2; i++)  {
-
 
490
        theLoad(i)   -= m * Raccel1(i);
-
 
491
        theLoad(i+3) -= m * Raccel2(i);
-
 
492
    }
-
 
493
   
-
 
494
        return 0;
-
 
495
}
-
 
496
-
 
497
-
 
498
const Vector& FlatSliderSimple2d::getResistingForce()
-
 
499
{
-
 
500
    // zero the residual
-
 
501
    theVector.Zero();
-
 
502
   
-
 
503
    // determine resisting forces in local system
-
 
504
    static Vector ql(6);
-
 
505
    ql = Tlb^qb;
-
 
506
   
-
 
507
    // add P-Delta moments to local forces
-
 
508
    double MpDelta = qb(0)*(ul(4)-ul(1));
-
 
509
    ql(2) += 1.0*MpDelta;
-
 
510
    //ql(5) += 0.0*MpDelta;
-
 
511
   
-
 
512
    // determine resisting forces in global system
-
 
513
    theVector = Tgl^ql;
-
 
514
   
-
 
515
    // subtract external load
-
 
516
    theVector.addVector(1.0, theLoad, -1.0);
-
 
517
   
-
 
518
    return theVector;
-
 
519
}
-
 
520
-
 
521
-
 
522
const Vector& FlatSliderSimple2d::getResistingForceIncInertia()
-
 
523
{      
-
 
524
        theVector = this->getResistingForce();
-
 
525
       
-
 
526
        // add the damping forces if rayleigh damping
-
 
527
        if (alphaM != 0.0 || betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0)
-
 
528
                theVector += this->getRayleighDampingForces();
-
 
529
   
-
 
530
        // now include the mass portion
-
 
531
        if (mass != 0.0)  {
-
 
532
                const Vector &accel1 = theNodes[0]->getTrialAccel();
-
 
533
                const Vector &accel2 = theNodes[1]->getTrialAccel();    
-
 
534
               
-
 
535
                double m = 0.5*mass;
-
 
536
                for (int i=0; i<2; i++)  {
-
 
537
                        theVector(i)   += m * accel1(i);
-
 
538
                        theVector(i+3) += m * accel2(i);
-
 
539
                }
-
 
540
        }
-
 
541
       
-
 
542
        return theVector;
-
 
543
}
-
 
544
-
 
545
-
 
546
int FlatSliderSimple2d::sendSelf(int commitTag, Channel &sChannel)
-
 
547
{
-
 
548
    // send element parameters
-
 
549
    static Vector data(7);
-
 
550
    data(0) = this->getTag();
-
 
551
    data(1) = uy;
-
 
552
    data(2) = mass;
-
 
553
    data(3) = maxIter;
-
 
554
    data(4) = tol;
-
 
555
    data(5) = x.Size();
-
 
556
    data(6) = y.Size();
-
 
557
    sChannel.sendVector(0, commitTag, data);
-
 
558
   
-
 
559
    // send the two end nodes
-
 
560
    sChannel.sendID(0, commitTag, connectedExternalNodes);
-
 
561
   
-
 
562
    // send the friction model class tag
-
 
563
    ID frnClassTag(1);
-
 
564
    frnClassTag(0) = theFrnMdl->getClassTag();
-
 
565
    sChannel.sendID(0, commitTag, frnClassTag);
-
 
566
   
-
 
567
    // send the friction model
-
 
568
    theFrnMdl->sendSelf(commitTag, sChannel);
-
 
569
   
-
 
570
    // send the material class tags
-
 
571
    ID matClassTags(2);
-
 
572
    for (int i=0; i<2; i++)
-
 
573
        matClassTags(i) = theMaterials[i]->getClassTag();
-
 
574
    sChannel.sendID(0, commitTag, matClassTags);
-
 
575
   
-
 
576
    // send the material models
-
 
577
    for (int i=0; i<2; i++)
-
 
578
        theMaterials[i]->sendSelf(commitTag, sChannel);
-
 
579
   
-
 
580
    // send remaining data
-
 
581
    if (x.Size() == 3)
-
 
582
        sChannel.sendVector(0, commitTag, x);
-
 
583
    if (y.Size() == 3)
-
 
584
        sChannel.sendVector(0, commitTag, y);
-
 
585
   
-
 
586
    return 0;
-
 
587
}
-
 
588
-
 
589
-
 
590
int FlatSliderSimple2d::recvSelf(int commitTag, Channel &rChannel,
-
 
591
    FEM_ObjectBroker &theBroker)
-
 
592
{
-
 
593
    // delete material memory
-
 
594
    for (int i=0; i<2; i++)
-
 
595
        if (theMaterials[i] != 0)
-
 
596
            delete theMaterials[i];
-
 
597
   
-
 
598
    // receive element parameters
-
 
599
    static Vector data(7);
-
 
600
    rChannel.recvVector(0, commitTag, data);
-
 
601
    this->setTag((int)data(0));
-
 
602
    uy = data(1);
-
 
603
    mass = data(2);
-
 
604
    maxIter = (int)data(3);
-
 
605
    tol = data(4);
-
 
606
   
-
 
607
    // receive the two end nodes
-
 
608
    rChannel.recvID(0, commitTag, connectedExternalNodes);
-
 
609
   
-
 
610
    // receive the friction model class tag
-
 
611
    ID frnClassTag(1);
-
 
612
    rChannel.recvID(0, commitTag, frnClassTag);
-
 
613
   
-
 
614
    // receive the friction model
-
 
615
    theFrnMdl = theBroker.getNewFrictionModel(frnClassTag(0));
-
 
616
    if (theFrnMdl == 0) {
-
 
617
        opserr << "FlatSliderSimple2d::recvSelf() - "
-
 
618
            << "failed to get blank friction model.\n";
-
 
619
        return -1;
-
 
620
    }
-
 
621
    theFrnMdl->recvSelf(commitTag, rChannel, theBroker);
-
 
622
   
-
 
623
    // receive the material class tags
-
 
624
    ID matClassTags(2);
-
 
625
    rChannel.recvID(0, commitTag, matClassTags);
-
 
626
   
-
 
627
    // receive the material models
-
 
628
    for (int i=0; i<2; i++)  {
-
 
629
        theMaterials[i] = theBroker.getNewUniaxialMaterial(matClassTags(i));
-
 
630
        if (theMaterials[i] == 0) {
-
 
631
            opserr << "FlatSliderSimple2d::recvSelf() - "
-
 
632
                << "failed to get blank uniaxial material.\n";
-
 
633
            return -2;
-
 
634
        }
-
 
635
        theMaterials[i]->recvSelf(commitTag, rChannel, theBroker);
-
 
636
    }
-
 
637
   
-
 
638
    // receive remaining data
-
 
639
    if ((int)data(5) == 3)  {
-
 
640
        x.resize(3);
-
 
641
        rChannel.recvVector(0, commitTag, x);
-
 
642
    }
-
 
643
    if ((int)data(6) == 3)  {
-
 
644
        y.resize(3);
-
 
645
        rChannel.recvVector(0, commitTag, y);
-
 
646
    }
-
 
647
   
-
 
648
    // initialize initial stiffness matrix
-
 
649
    kbInit.Zero();
-
 
650
    kbInit(0,0) = theMaterials[0]->getInitialTangent();
-
 
651
    kbInit(1,1) = kbInit(0,0)*DBL_EPSILON;
-
 
652
    kbInit(2,2) = theMaterials[1]->getInitialTangent();
-
 
653
   
-
 
654
    // initialize other variables
-
 
655
    this->revertToStart();
-
 
656
   
-
 
657
    return 0;
-
 
658
}
-
 
659
-
 
660
-
 
661
int FlatSliderSimple2d::displaySelf(Renderer &theViewer,
-
 
662
    int displayMode, float fact)
-
 
663
{
-
 
664
    // first determine the end points of the element based on
-
 
665
    // the display factor (a measure of the distorted image)
-
 
666
    const Vector &end1Crd = theNodes[0]->getCrds();
-
 
667
    const Vector &end2Crd = theNodes[1]->getCrds();    
-
 
668
   
-
 
669
    const Vector &end1Disp = theNodes[0]->getDisp();
-
 
670
    const Vector &end2Disp = theNodes[1]->getDisp();
-
 
671
   
-
 
672
    static Vector v1(3);
-
 
673
    static Vector v2(3);
-
 
674
   
-
 
675
    for (int i=0; i<2; i++)  {
-
 
676
        v1(i) = end1Crd(i) + end1Disp(i)*fact;
-
 
677
        v2(i) = end2Crd(i) + end2Disp(i)*fact;    
-
 
678
    }
-
 
679
   
-
 
680
    return theViewer.drawLine (v1, v2, 1.0, 1.0);
-
 
681
}
-
 
682
-
 
683
-
 
684
void FlatSliderSimple2d::Print(OPS_Stream &s, int flag)
-
 
685
{
-
 
686
    if (flag == 0)  {
-
 
687
        // print everything
-
 
688
                s << "Element: " << this->getTag();
-
 
689
                s << "  type: FlatSliderSimple2d  iNode: " << connectedExternalNodes(0);
-
 
690
                s << "  jNode: " << connectedExternalNodes(1) << endln;
-
 
691
        s << "  FrictionModel: " << theFrnMdl->getTag() << endln;
-
 
692
        s << "  uy: " << uy << endln;
-
 
693
        s << "  Material ux: " << theMaterials[0]->getTag() << endln;
-
 
694
        s << "  Material rz: " << theMaterials[1]->getTag() << endln;
-
 
695
        s << "  mass: " << mass << "  maxIter: " << maxIter << "  tol: " << tol << endln;
-
 
696
        // determine resisting forces in global system
-
 
697
        s << "  resisting force: " << this->getResistingForce() << endln;
-
 
698
    } else if (flag == 1)  {
-
 
699
                // does nothing
-
 
700
    }
-
 
701
}
-
 
702
-
 
703
-
 
704
Response* FlatSliderSimple2d::setResponse(const char **argv, int argc,
-
 
705
    OPS_Stream &output)
-
 
706
{
-
 
707
    Response *theResponse = 0;
-
 
708
-
 
709
    output.tag("ElementOutput");
-
 
710
    output.attr("eleType","FlatSliderSimple2d");
-
 
711
    output.attr("eleTag",this->getTag());
-
 
712
    output.attr("node1",connectedExternalNodes[0]);
-
 
713
    output.attr("node2",connectedExternalNodes[1]);
-
 
714
-
 
715
    // global forces
-
 
716
    if (strcmp(argv[0],"force") == 0 ||
-
 
717
        strcmp(argv[0],"forces") == 0 ||
-
 
718
        strcmp(argv[0],"globalForce") == 0 ||
-
 
719
        strcmp(argv[0],"globalForces") == 0)
-
 
720
    {
-
 
721
        output.tag("ResponseType","Px_1");
-
 
722
        output.tag("ResponseType","Py_1");
-
 
723
        output.tag("ResponseType","Mz_1");
-
 
724
        output.tag("ResponseType","Px_2");
-
 
725
        output.tag("ResponseType","Py_2");
-
 
726
        output.tag("ResponseType","Mz_2");
-
 
727
-
 
728
        theResponse = new ElementResponse(this, 1, theVector);
-
 
729
    }
-
 
730
    // local forces
-
 
731
    else if (strcmp(argv[0],"localForce") == 0 ||
-
 
732
        strcmp(argv[0],"localForces") == 0)
-
 
733
    {
-
 
734
        output.tag("ResponseType","N_1");
-
 
735
        output.tag("ResponseType","V_1");
-
 
736
        output.tag("ResponseType","M_1");
-
 
737
        output.tag("ResponseType","N_2");
-
 
738
        output.tag("ResponseType","V_2");
-
 
739
        output.tag("ResponseType","M_2");
-
 
740
-
 
741
        theResponse = new ElementResponse(this, 2, theVector);
-
 
742
    }
-
 
743
    // basic forces
-
 
744
    else if (strcmp(argv[0],"basicForce") == 0 ||
-
 
745
        strcmp(argv[0],"basicForces") == 0)
-
 
746
    {
-
 
747
        output.tag("ResponseType","qb1");
-
 
748
        output.tag("ResponseType","qb2");
-
 
749
        output.tag("ResponseType","qb3");
-
 
750
-
 
751
        theResponse = new ElementResponse(this, 3, Vector(3));
-
 
752
    }
-
 
753
        // local displacements
-
 
754
    else if (strcmp(argv[0],"localDisplacement") == 0 ||
-
 
755
        strcmp(argv[0],"localDisplacements") == 0)
-
 
756
    {
-
 
757
        output.tag("ResponseType","ux_1");
-
 
758
        output.tag("ResponseType","uy_1");
-
 
759
        output.tag("ResponseType","rz_1");
-
 
760
        output.tag("ResponseType","ux_2");
-
 
761
        output.tag("ResponseType","uy_2");
-
 
762
        output.tag("ResponseType","rz_2");
-
 
763
       
-
 
764
        theResponse = new ElementResponse(this, 4, theVector);
-
 
765
    }
-
 
766
        // basic displacements
-
 
767
    else if (strcmp(argv[0],"deformation") == 0 ||
-
 
768
        strcmp(argv[0],"deformations") == 0 ||
-
 
769
        strcmp(argv[0],"basicDeformation") == 0 ||
-
 
770
        strcmp(argv[0],"basicDeformations") == 0 ||
-
 
771
        strcmp(argv[0],"basicDisplacement") == 0 ||
-
 
772
        strcmp(argv[0],"basicDisplacements") == 0)
-
 
773
    {
-
 
774
        output.tag("ResponseType","ub1");
-
 
775
        output.tag("ResponseType","ub2");
-
 
776
        output.tag("ResponseType","ub3");
-
 
777
       
-
 
778
        theResponse = new ElementResponse(this, 5, Vector(3));
-
 
779
    }
-
 
780
    // material output
-
 
781
    else if (strcmp(argv[0],"material") == 0)  {
-
 
782
        if (argc > 2)  {
-
 
783
            int matNum = atoi(argv[1]);
-
 
784
            if (matNum >= 1 && matNum <= 2)
-
 
785
                theResponse =  theMaterials[matNum-1]->setResponse(&argv[2], argc-2, output);
-
 
786
        }
-
 
787
    }
-
 
788
   
-
 
789
    output.endTag(); // ElementOutput
-
 
790
   
-
 
791
    return theResponse;
-
 
792
}
-
 
793
-
 
794
-
 
795
int FlatSliderSimple2d::getResponse(int responseID, Information &eleInfo)
-
 
796
{
-
 
797
    double MpDelta;
-
 
798
-
 
799
        switch (responseID)  {
-
 
800
        case 1:  // global forces
-
 
801
        return eleInfo.setVector(this->getResistingForce());
-
 
802
       
-
 
803
        case 2:  // local forces
-
 
804
        theVector.Zero();
-
 
805
        // determine resisting forces in local system
-
 
806
        theVector = Tlb^qb;
-
 
807
        // add P-Delta moments
-
 
808
        MpDelta = qb(0)*(ul(4)-ul(1));
-
 
809
        theVector(2) += 1.0*MpDelta;
-
 
810
        //theVector(5) += 0.0*MpDelta;
-
 
811
       
-
 
812
        return eleInfo.setVector(theVector);
-
 
813
       
-
 
814
        case 3:  // basic forces
-
 
815
        return eleInfo.setVector(qb);
-
 
816
       
-
 
817
        case 4:  // local displacements
-
 
818
        return eleInfo.setVector(ul);
-
 
819
       
-
 
820
        case 5:  // basic displacements
-
 
821
        return eleInfo.setVector(ub);
-
 
822
       
-
 
823
    default:
-
 
824
                return -1;
-
 
825
        }
-
 
826
}
-
 
827
-
 
828
-
 
829
// establish the external nodes and set up the transformation matrix for orientation
-
 
830
void FlatSliderSimple2d::setUp()
-
 
831
{
-
 
832
    const Vector &end1Crd = theNodes[0]->getCrds();
-
 
833
    const Vector &end2Crd = theNodes[1]->getCrds();    
-
 
834
    Vector xp = end2Crd - end1Crd;
-
 
835
    L = xp.Norm();
-
 
836
   
-
 
837
    if (L > DBL_EPSILON)  {
-
 
838
        if (x.Size() == 0)  {
-
 
839
            x.resize(3);
-
 
840
            x(0) = xp(0);  x(1) = xp(1);  x(2) = 0.0;
-
 
841
            y.resize(3);
-
 
842
            y(0) = -x(1);  y(1) = x(0);  y(2) = 0.0;
-
 
843
        } else  {
-
 
844
            opserr << "WARNING FlatSliderSimple2d::setUp() - "
-
 
845
                << "element: " << this->getTag() << endln
-
 
846
                << "ignoring nodes and using specified "
-
 
847
                << "local x vector to determine orientation\n";
-
 
848
        }
-
 
849
    }
-
 
850
    // check that vectors for orientation are of correct size
-
 
851
    if (x.Size() != 3 || y.Size() != 3)  {
-
 
852
        opserr << "FlatSliderSimple2d::setUp() - "
-
 
853
            << "element: " << this->getTag() << endln
-
 
854
            << "incorrect dimension of orientation vectors\n";
-
 
855
        exit(-1);
-
 
856
    }
-
 
857
   
-
 
858
    // establish orientation of element for the tranformation matrix
-
 
859
    // z = x cross y
-
 
860
    Vector z(3);
-
 
861
    z(0) = x(1)*y(2) - x(2)*y(1);
-
 
862
    z(1) = x(2)*y(0) - x(0)*y(2);
-
 
863
    z(2) = x(0)*y(1) - x(1)*y(0);
-
 
864
   
-
 
865
    // y = z cross x
-
 
866
    y(0) = z(1)*x(2) - z(2)*x(1);
-
 
867
    y(1) = z(2)*x(0) - z(0)*x(2);
-
 
868
    y(2) = z(0)*x(1) - z(1)*x(0);
-
 
869
   
-
 
870
    // compute length(norm) of vectors
-
 
871
    double xn = x.Norm();
-
 
872
    double yn = y.Norm();
-
 
873
    double zn = z.Norm();
-
 
874
   
-
 
875
    // check valid x and y vectors, i.e. not parallel and of zero length
-
 
876
    if (xn == 0 || yn == 0 || zn == 0)  {
-
 
877
        opserr << "FlatSliderSimple2d::setUp() - "
-
 
878
            << "element: " << this->getTag() << endln
-
 
879
            << "invalid orientation vectors\n";
-
 
880
        exit(-1);
-
 
881
    }
-
 
882
   
-
 
883
    // create transformation matrix from global to local system
-
 
884
    Tgl.Zero();
-
 
885
    Tgl(0,0) = Tgl(3,3) = x(0)/xn;
-
 
886
    Tgl(0,1) = Tgl(3,4) = x(1)/xn;
-
 
887
    Tgl(1,0) = Tgl(4,3) = y(0)/yn;
-
 
888
    Tgl(1,1) = Tgl(4,4) = y(1)/yn;
-
 
889
    Tgl(2,2) = Tgl(5,5) = z(2)/zn;
-
 
890
   
-
 
891
    // create transformation matrix from local to basic system (linear)
-
 
892
    Tlb.Zero();
-
 
893
    Tlb(0,0) = Tlb(1,1) = Tlb(2,2) = -1.0;
-
 
894
    Tlb(0,3) = Tlb(1,4) = Tlb(2,5) = 1.0;
-
 
895
    Tlb(1,5) = -L;    
-
 
896
}
-
 
897
-
 
898
-
 
899
double FlatSliderSimple2d::sgn(double x)
-
 
900
{
-
 
901
    if (x > 0)
-
 
902
        return 1.0;
-
 
903
    else if (x < 0)
-
 
904
        return -1.0;
-
 
905
    else
-
 
906
        return 0.0;
-
 
907
}