Subversion Repositories OpenSees

Rev

Rev 2175 | Rev 2824 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 fmk 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
 
2418 fmk 21
// $Revision: 1.11 $
22
// $Date: 2006-05-26 18:19:16 $
2 fmk 23
// $Source: /usr/local/cvs/OpenSees/SRC/matrix/ID.cpp,v $
24
 
25
 
26
// Written: fmk 
27
// Revision: A
28
//
29
// Description: This file contains the class implementation for ID.
30
//
31
// What: "@(#) ID.C, revA"
32
 
33
#include "ID.h"
34
#include <stdlib.h>
35
 
36
 
37
int ID::ID_NOT_VALID_ENTRY = 0;
38
 
39
// ID():
40
//      Standard constructor, sets size = 0;
41
 
42
ID::ID()
947 mhscott 43
  :sz(0), data(0), arraySize(0), fromFree(0)
2 fmk 44
{
45
 
46
}
47
 
48
 
49
// ID(int size):
50
//      Constructor used to allocate a ID of size size.
51
 
52
ID::ID(int size)
947 mhscott 53
  :sz(size), data(0), arraySize(size), fromFree(0)
2 fmk 54
{
55
 
56
#ifdef _G3DEBUG
57
  if (sz <= 0) {
1276 fmk 58
    opserr << "ID::ID(int) - size " << size << " specified <= 0\n";
2 fmk 59
    sz = 1;
60
    arraySize = 1;
61
  }
62
#endif    
63
 
64
  // create the space for the data & check space was available
1745 fmk 65
  //  data = (int *)malloc(size*sizeof(int));
66
  data = new int[size];
2 fmk 67
  if (data == 0) {
1271 fmk 68
    opserr << "ID::ID(int): ran out of memory with size " << size << endln;
2 fmk 69
    exit(-1);
70
  }
71
 
72
  // zero the data
73
  for (int i=0; i<size; i++)
74
    data[i] = 0;
75
}
76
 
77
 
78
// ID(int size):
79
//      Constructor used to allocate a ID of size size.
80
 
81
ID::ID(int size, int arraySz)
947 mhscott 82
  :sz(size), data(0), arraySize(arraySz), fromFree(0)
2 fmk 83
{
84
#ifdef _G3DEBUG
85
  if (sz < 0) {
1276 fmk 86
    opserr << "ID::ID(size, arraySize) - size " << size << " specified < 0\n";
2 fmk 87
    sz = 0;
88
  }
89
  if (arraySz <= 0) {
1276 fmk 90
    opserr << "ID::ID(size, arraySize) - arraySize " << arraySz << " specified < 0\n";
2 fmk 91
    if (sz != 0)
92
      arraySz = sz;
93
    else
94
      arraySz = 1;
95
  }
96
  if (arraySz < sz) {
1276 fmk 97
    opserr << "ID::ID(size, arraySize) - arraySize " << arraySz  << " specified < " << size << endln;
2 fmk 98
    arraySz = sz;
99
  }
100
#endif    
101
 
102
  // create the space
1745 fmk 103
  //  data = (int *)malloc(arraySize*sizeof(int));
104
  data = new int[arraySize];
2 fmk 105
  if (data == 0) {
1271 fmk 106
    opserr << "ID::ID(int, int): ran out of memory with arraySize: " << arraySize << endln;
2 fmk 107
    exit(-1);
108
  }
109
 
110
  // zero the data
111
  for (int i=0; i<arraySize; i++)
112
    data[i] = 0;
113
}
114
 
1745 fmk 115
ID::ID(int *d, int size, bool cleanIt)
947 mhscott 116
  :sz(size), data(d), arraySize(size), fromFree(1)
117
{
1271 fmk 118
  if (d == 0) { // OOPS must have been other constructor we wanted
119
    sz = 0;
120
    data = 0;
121
    arraySize = size;
122
    fromFree = 0;
2 fmk 123
 
1271 fmk 124
    // create the space
125
    if (arraySize != 0) {
126
      data = (int *)malloc(arraySize*sizeof(int));
127
      if (data == 0) {
128
        opserr << "ID::ID(int, int): ran out of memory with arraySize " << arraySize << endln;
129
        exit(-1);
130
      }
131
    }
132
 
133
    // zero the data
134
    for (int i=0; i<arraySize; i++)
135
      data[i] = 0;
136
  }
1745 fmk 137
 
138
  if (cleanIt == true)
139
    fromFree = 0;
947 mhscott 140
}
2 fmk 141
 
142
// ID(const ID&):
143
//      Constructor to init a ID from another.
144
 
145
ID::ID(const ID &other)
947 mhscott 146
  :sz(other.sz), data(0), arraySize(other.arraySize), fromFree(0)
2 fmk 147
{
148
  // create the space
1745 fmk 149
  //  data = (int *)malloc(arraySize*sizeof(int));
150
  data = new int[arraySize];
2 fmk 151
  if (data == 0) {
1271 fmk 152
    opserr << "ID::ID(ID): ran out of memory with arraySize " << arraySize << endln,
2 fmk 153
    exit(-1);
154
  }
155
 
156
  // copy the data 
157
  for (int i=0; i<sz; i++)
158
    data[i] = other.data[i];
159
}      
160
 
161
 
162
 
163
// ~ID():
164
//      destructor, deletes the [] data
165
 
166
ID::~ID()
167
{
947 mhscott 168
  if (data != 0 && fromFree == 0)
1745 fmk 169
    //    free((void *)data);
170
    delete [] data;
2 fmk 171
}
172
 
1137 fmk 173
int
1745 fmk 174
ID::setData(int *newData, int size, bool cleanIt){
2160 fmk 175
 
1137 fmk 176
  if (data != 0 && fromFree == 0)
1745 fmk 177
    //    free((void *)data);
178
    delete [] data;
2 fmk 179
 
1137 fmk 180
  sz = size;
181
  data = newData;
1745 fmk 182
 
183
  if (cleanIt == false)
184
    fromFree = 1;
185
  else
186
    fromFree = 0;
1137 fmk 187
 
188
  if (sz <= 0) {
1271 fmk 189
    opserr << "ID::ID(int *, size) - size " << size << " specified <= 0\n";
1137 fmk 190
    sz = 0;
191
  }
192
 
193
  return 0;
194
}
195
 
196
 
2 fmk 197
void
198
ID::Zero(void)
199
{
200
  for (int i=0; i<sz; i++)
201
    data[i] =0;
202
}
203
 
204
int
205
ID::getLocation(int value) const
206
{
207
  // search through ID for the value
208
  for (int i=0; i<sz; i++)
209
    if (data[i] == value)
210
      return i;
211
 
212
  // if we get here the value is not in the array
213
  return -1;
214
}
215
 
2152 fmk 216
 
2 fmk 217
int
2152 fmk 218
ID::getLocationOrdered(int value) const
219
{
220
  int middle = 0;
221
  int left = 0;
222
  int right = sz-1;
223
  if (sz != 0) {
224
    while (left <= right) {
225
      middle = (left + right)/2;
226
      double dataMiddle = data[middle];
227
      if (value == dataMiddle)
228
        return middle;   // already there
229
      else if (value > dataMiddle)
230
        left = middle + 1;
231
      else
232
        right = middle-1;
233
    }
234
  }
235
 
236
  // if we get here the value is not in the array
237
  return -1;
238
}
239
 
240
 
241
int
2 fmk 242
ID::removeValue(int value)
243
{
244
  int place = -1;
245
  for (int i=0; i<sz; i++)
246
    if (data[i] == value) {
247
      place = i;
248
      // copy the rest of the components down one in ID
249
      for (int j=i; j<sz-1; j++)
250
        data[j] = data[j+1];           
251
      sz--;
252
    }
253
  return place;
254
}    
255
 
256
 
257
int &
258
ID::operator[](int x)
259
{
260
#ifdef _G3DEBUG
261
  // check if it is inside range [0,sz-1]
262
  if (x < 0) {
1276 fmk 263
    opserr << "ID::[] - location " << x << " < 0\n";
2 fmk 264
    return ID_NOT_VALID_ENTRY;
265
  }
266
#endif
267
 
268
  // see if quick return
269
  if (x < sz)
270
    return data[x];
1271 fmk 271
 
2 fmk 272
  /*
273
   * otherwise we have to enlarge the order of the ID
274
   */
275
 
276
  // see if we can just enlarge the array
277
  // without having to go get more space
278
 
279
  if (x < arraySize) {
280
    for (int i=sz; i<x; i++)
281
      data[i] = 0;
282
    sz = x+1;
283
    return data[x];
284
  }
285
 
286
  // otherwise we go get more space
287
  if (x >= arraySize) {
288
    int newArraySize = arraySize * 2;
289
    if (newArraySize < x)
290
      newArraySize = x;
1745 fmk 291
    //    int *newData = (int *)malloc(newArraySize*sizeof(int));    
292
    int *newData = new int[newArraySize];
2 fmk 293
    if (newData != 0) {
294
      // copy the old
295
      for (int i=0; i<sz; i++)
296
        newData[i] = data[i];
297
      // zero the new
298
      for (int j=sz; j<arraySize; j++)
299
        newData[j] = 0;
300
 
301
      sz = x+1;
302
      // release the memory held by the old
1745 fmk 303
      //      free((void *)data);           
2152 fmk 304
      if (fromFree == 0)
305
        delete [] data;
2 fmk 306
      data = newData;
307
      arraySize = newArraySize;
308
 
309
      return newData[x];
310
    }
311
    else {
312
      // we could not allocate more mem .. leave the current size
1271 fmk 313
      opserr << "ID::[]): ran out of memory with arraySize " << arraySize << endln;
2 fmk 314
      return ID_NOT_VALID_ENTRY;
315
    }
316
  }
317
 
318
  // we should never get here, but some compilers need this line
319
  return ID_NOT_VALID_ENTRY;   
320
}
321
 
322
 
2175 fmk 323
int
324
ID::resize(int newSize){
2 fmk 325
 
2175 fmk 326
  // first check that newSize is valid
327
  if (newSize <= 0) {
328
    opserr << "ID::resize() - size specified " << newSize << " <= 0\n";
329
    return -1;
330
  }
331
 
332
 
333
  if (sz > newSize) {
334
 
335
    // is size smaller than current, simply reset sz
336
    sz = newSize;
337
 
338
  } else if (newSize < arraySize) {
339
 
340
    // see if we can just enlarge the array
341
    // without having to go get more space
342
 
343
    for (int i=sz; i<newSize; i++)
344
      data[i] = 0;
345
    sz = newSize;
346
 
347
  } else if (newSize > arraySize) {
348
 
349
    // otherwise we go get more space
350
 
351
    int *newData = new int[newSize];
352
    if (newData != 0) {
353
      // copy the old
354
      for (int i=0; i<sz; i++)
355
        newData[i] = data[i];
356
      // zero the new
357
      for (int j=sz; j<newSize; j++)
358
        newData[j] = 0;
359
 
360
      sz = newSize;
361
      // release the memory held by the old
362
      //      free((void *)data);           
363
      delete [] data;
364
      data = newData;
365
      arraySize = newSize;
366
 
367
    } else {
368
      opserr << "ID::resize() - out of memory creating ID of size " << newSize << "\n";
369
      return -1;      
370
    }
371
  }
372
 
373
  return 0;
374
}
375
 
376
 
377
 
2 fmk 378
// ID &operator=(const ID  &V):
379
//      the assignment operator, This is assigned to be a copy of V. if sizes
380
//      are not compatable this.data [] is deleted. The data pointers will not
381
//      point to the same area in mem after the assignment.
382
//
383
 
384
ID &
385
ID::operator=(const ID &V)
386
{
387
    // first check we are not trying v = v
388
    if (this != &V) {
389
 
390
        // check size compatability, if different delete
391
        // old and make room for new.
392
        if (sz != V.sz) {
393
            if (arraySize < V.sz) {
394
                arraySize = V.sz;
395
                if (data != 0)
1745 fmk 396
                  //free((void *)data);
397
                  delete [] data;
398
                //              data = (int *)malloc(arraySize*sizeof(int));            
399
                data = new int[arraySize];
2 fmk 400
                // check we got the memory requested
401
                if (data == 0) {
1271 fmk 402
                    opserr << "WARNING ID::=(ID) - ran out of memory ";
403
                    opserr << "for new array of size" << arraySize << endln;
2 fmk 404
                    sz = 0;
405
                    arraySize = 0;
406
                }
407
            }
968 fmk 408
            sz = V.sz;
2 fmk 409
        }
410
 
411
        // copy the data
412
        for (int i=0; i<sz; i++)
413
            data[i] = V(i);
414
    }
415
 
416
    return *this;
417
}
418
 
419
 
420
 
421
 
422
 
1271 fmk 423
// friend OPS_Stream &operator<<(OPS_Stream &s, const ID &V)
424
//      A function is defined to allow user to print the IDs using OPS_Streams.
2 fmk 425
 
1271 fmk 426
OPS_Stream &operator<<(OPS_Stream &s, const ID &V)
2 fmk 427
{
428
    for (int i=0; i<V.Size(); i++)
429
    {
430
        s << V(i) << " ";
431
    }
1271 fmk 432
    return s << endln;
2 fmk 433
}
434
 
435
// friend istream &operator>>(istream &s, ID &V)
436
//      A function is defined to allow user to input the data into a ID which has already
437
//      been constructed with data, i.e. ID(int) or ID(const ID &) constructors.
438
 
1271 fmk 439
/*
2 fmk 440
istream &operator>>(istream &s, ID &V)
441
{
442
    for (int i=0; i<V.Size(); i++)
443
        s >> V(i);
444
 
445
    return s;
446
}
1271 fmk 447
*/
2 fmk 448
 
449
 
450
 
2152 fmk 451
int
452
ID::insert(int x)
453
{
454
  int middle = 0;
455
  int left = 0;
456
  int right = sz-1;
457
  if (sz != 0) {
458
    while (left <= right) {
459
      middle = (left + right)/2;
460
      double dataMiddle = data[middle];
461
      if (x == dataMiddle)
2160 fmk 462
        return 1;   // already there
2152 fmk 463
      else if (x > dataMiddle)
464
        left = middle + 1;
465
      else
466
        right = middle-1;
467
    }
468
  }
2 fmk 469
 
2152 fmk 470
  // we need to enlarge the array .. see if we can do it
471
  // without having to go get more space
472
 
473
  middle = left;
2418 fmk 474
 
2160 fmk 475
  /*
476
  for (int i=middle; i<sz; i++)
2418 fmk 477
  (*this)[i+1] = (*this)[i];
2160 fmk 478
  (*this)[i]=middle;
479
  return middle;
2418 fmk 480
  */
2160 fmk 481
 
2152 fmk 482
  if (sz < arraySize) {
483
 
484
    int i = sz;
485
    while (i > middle) {
486
      data[i] = data[i-1];
487
      i--;
488
    }
2418 fmk 489
    sz++;
2152 fmk 490
    data[i] = x;
2160 fmk 491
    return 0;
2152 fmk 492
  } else {
2418 fmk 493
    int newArraySize = (sz+1) * 2;
494
    int *newData = new int[newArraySize];
495
    if (newData != 0) {
496
 
2152 fmk 497
      // copy the old
2160 fmk 498
      for (int ii=0; ii<middle; ii++)
2418 fmk 499
        newData[ii] = data[ii];
500
      newData[middle] = x;
501
 
502
      for (int jj=middle; jj<sz; jj++)
503
        newData[jj+1] = data[jj];
504
 
2152 fmk 505
      sz++;
2418 fmk 506
 
507
      if (data != 0 && fromFree == 0)
508
        delete [] data;
2152 fmk 509
      data = newData;
510
      arraySize = newArraySize;
511
 
2160 fmk 512
      return 0;
2418 fmk 513
 
514
    } else
515
      return -1;
2152 fmk 516
  }
2418 fmk 517
  return -1; // should never get here
2152 fmk 518
}
519