Subversion Repositories OpenSees

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
275 fmk 1
/* ****************************************************************** **
2
**    OpenSees - Open System for Earthquake Engineering Simulation    **
3
**          Pacific Earthquake Engineering Research Center            **
4
**                                                                    **
5
**                                                                    **
6
** (C) Copyright 2001, 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
** Reliability module developed by:                                   **
20
**   Terje Haukaas (haukaas@ce.berkeley.edu)                          **
21
**   Armen Der Kiureghian (adk@ce.berkeley.edu)                       **
22
**                                                                    **
23
** ****************************************************************** */
24
 
25
// $Revision: 1.1 $
26
// $Date: 2001-06-13 05:06:18 $
27
// $Source: /usr/local/cvs/OpenSees/SRC/reliability/analysis/sensitivity/OpenSeesSensitivityEvaluator.cpp,v $
28
 
29
 
30
//
31
// Written by Terje Haukaas (haukaas@ce.berkeley.edu) during Spring 2000
32
// Revised: haukaas 06/00 (core code)
33
//                      haukaas 06/01 (made part of official OpenSees)
34
//
35
 
36
#include <OpenSeesSensitivityEvaluator.h>
37
#include <Vector.h>
38
#include <Matrix.h>
39
#include <SensitivityEvaluator.h>
40
#include <ReliabilityDomain.h>
41
#include <LimitStateFunction.h>
42
#include <GFunEvaluator.h>
43
#include <RandomVariable.h>
44
 
45
#include <fstream.h>
46
#include <tcl.h>
47
#include <string.h>
48
 
49
 
50
OpenSeesSensitivityEvaluator::OpenSeesSensitivityEvaluator(
51
                                        Tcl_Interp *passedTclInterp,
52
                                        ReliabilityDomain *passedReliabilityDomain)
53
:SensitivityEvaluator()
54
{
55
        theTclInterp = passedTclInterp;
56
        theReliabilityDomain = passedReliabilityDomain;
57
 
58
        int nrv = theReliabilityDomain->getNumberOfRandomVariables();
59
        grad_g = new Vector(nrv);
60
}
61
 
62
OpenSeesSensitivityEvaluator::~OpenSeesSensitivityEvaluator()
63
{
64
        delete grad_g;
65
}
66
 
67
 
68
 
69
 
70
Vector
71
OpenSeesSensitivityEvaluator::get_grad_g()
72
{
73
        return (*grad_g);
74
}
75
 
76
 
77
int
78
OpenSeesSensitivityEvaluator::evaluate_grad_g(double gFunValue, Vector passed_x)
79
{
80
        ////////////////////////////////////
81
        // Notation:
82
        // g: the limit-state function
83
        // The gradient of the limit-state function:
84
        //   dgdx(m,1) = [ dgdu(1,n) * dudx(n,m) ]^T   +  dgdxufixed(m,1)
85
        // m: number of random variables x(i)
86
        // n: number of response quantities u(i)
87
        ////////////////////////////////////
88
 
89
        // Some initial declaractions
90
        char tclAssignment[500];
91
        double g;
92
        double onedgdxufixed;
93
        double onedgdu;
94
        double onedudx;
95
 
96
        // "Download" limit-state function from reliability domain
97
        int lsf = theReliabilityDomain->getTagOfActiveLimitStateFunction();
98
        LimitStateFunction *theLimitStateFunction =
99
                theReliabilityDomain->getLimitStateFunctionPtr(lsf);
100
        char *theExpression = theLimitStateFunction->getExpression();
101
 
102
        // Declare some much used tokens
103
        char *dollarSign = "$";
104
        char *underscore = "_";
105
 
106
        // Declare strings for the strings to be evaluated by Tcl
107
        char lsf_expression[500] = "";
108
        char grad_lsf_expression[500] = "";
109
 
110
        // Create copies of the limit-state function to be tokenized
111
        char *lsf_copy1 = new char[500];
112
        char *lsf_copy2 = new char[500];
113
        strcpy(lsf_copy1,theExpression);
114
        strcpy(lsf_copy2,theExpression);
115
 
116
        // Have a counter to see how many response quantities are in the lsf
117
        int count_u = 0;
118
 
119
        // Tokenize the limit-state function and assign values to the found quantities. 
120
        char *tokenPtr1 = strtok( lsf_copy1, " _"); // read first token
121
        while ( tokenPtr1 != NULL ) {
122
 
123
                // If a basic random variable is detected
124
                if ( strcmp(tokenPtr1, "x") == 0) {
125
                        strcat(lsf_expression, dollarSign);
126
                        strcat(lsf_expression, tokenPtr1);
127
                        strcat(lsf_expression, underscore);
128
                        tokenPtr1 = strtok( NULL, " _");         // read a token
129
                        strcat(lsf_expression, tokenPtr1);
130
                        int basicRandomVariableNumber = atoi( tokenPtr1 );
131
                        sprintf(tclAssignment , "set x_%d  %15.5f", basicRandomVariableNumber, passed_x(basicRandomVariableNumber-1) );
132
                        Tcl_Eval( theTclInterp, tclAssignment);
133
                }
134
 
135
                // If a nodal displacement is detected
136
                else if ( strcmp(tokenPtr1, "nd") == 0) {
137
                        count_u++;
138
                        strcat(lsf_expression, dollarSign);
139
                        strcat(lsf_expression, tokenPtr1);
140
                        strcat(lsf_expression, underscore);
141
                        tokenPtr1 = strtok( NULL, " _");  // read a token
142
                        strcat(lsf_expression, tokenPtr1);
143
                        strcat(lsf_expression, underscore);
144
                        int nodeNumber = atoi( tokenPtr1 );
145
                        tokenPtr1 = strtok( NULL, " _");  // read a token
146
                        strcat(lsf_expression, tokenPtr1);
147
                        int direction = atoi( tokenPtr1 );
148
                        sprintf(tclAssignment,"set nd_%d_%d [nodeDisp %d %d ]",nodeNumber,direction,nodeNumber,direction);
149
                        Tcl_Eval( theTclInterp, tclAssignment);
150
                }
151
                else {
152
                        strcat(lsf_expression, tokenPtr1);
153
                }
154
 
155
                tokenPtr1 = strtok( NULL, " _");  // read a token
156
        }
157
 
158
        // Assign value of of limit-state function to 'lsfvalue' in Tcl 
159
        Tcl_ExprDouble( theTclInterp, lsf_expression, &g );
160
        sprintf(tclAssignment,"set lsfvalue %35.20f", g);
161
        Tcl_Eval( theTclInterp, tclAssignment);
162
 
163
        // Declaration of quantities used in the gradient computations
164
        int nrv = theReliabilityDomain->getNumberOfRandomVariables();
165
        Vector dgdx(nrv);
166
        Vector dgdu(count_u);
167
        Matrix dudx(count_u, nrv);
168
        Vector dgdxufixed(nrv);  // this must be initialized to zero: is it???
169
        RandomVariable *theRandomVariable;
170
 
171
        // Tokenize the limit-state function and COMPUTE GRADIENTS
172
        count_u = 0;
173
        char *tokenPtr2 = strtok( lsf_copy2, " _"); // read first token
174
        while ( tokenPtr2 != NULL ) {
175
 
176
                // If a basic random variable is detected
177
                if ( strcmp(tokenPtr2, "x") == 0) {
178
                        tokenPtr2 = strtok( NULL, " _");         // read a token
179
                        int basicRandomVariableNumber = atoi( tokenPtr2 );
180
                        // Get the standard deviation of the random variable
181
                        theRandomVariable = theReliabilityDomain->getRandomVariablePtr(basicRandomVariableNumber);
182
                        double stdv = theRandomVariable->getStdv();
183
                        // Assign a perturbed value
184
                        sprintf(tclAssignment , "set x_%d  %35.20f", basicRandomVariableNumber,
185
                                (passed_x(basicRandomVariableNumber-1)+0.005*stdv) );
186
                        Tcl_Eval( theTclInterp, tclAssignment);
187
                        // Evaluate limit-state function again
188
                        Tcl_ExprDouble( theTclInterp, lsf_expression, &g );
189
                        sprintf(tclAssignment,"set lsfperturbed %35.20f", g);
190
                        Tcl_Eval( theTclInterp, tclAssignment);
191
                        // Compute the gradient 'dgdxufixed' by finite difference
192
                        sprintf(tclAssignment , "($lsfperturbed-$lsfvalu)/%35.20f", (0.005*stdv) );
193
                        Tcl_ExprDouble( theTclInterp, tclAssignment, &onedgdxufixed );
194
                        dgdxufixed(basicRandomVariableNumber-1)=onedgdxufixed;
195
                        // Make assignment back to its original value
196
                        sprintf(tclAssignment , "set x_%d  %35.20f", basicRandomVariableNumber, passed_x(basicRandomVariableNumber-1) );
197
                        Tcl_Eval( theTclInterp, tclAssignment);
198
                }
199
 
200
                // If a nodal displacement is detected
201
                else if ( strcmp(tokenPtr2, "nd") == 0) {
202
                        count_u++;
203
                        tokenPtr2 = strtok( NULL, " _");  // read a token
204
                        int nodeNumber = atoi( tokenPtr2 );
205
                        tokenPtr2 = strtok( NULL, " _");  // read a token
206
                        int direction = atoi( tokenPtr2 );
207
                        // Assign a perturbed value
208
                        sprintf(tclAssignment,"set nd_%d_%d [ expr [nodeDisp %d %d ]*1.001 ]",nodeNumber,direction,nodeNumber,direction);
209
                        Tcl_Eval( theTclInterp, tclAssignment);
210
                        // Evaluate the limit-state function again
211
                        Tcl_ExprDouble( theTclInterp, lsf_expression, &g );
212
                        sprintf(tclAssignment,"set lsfperturbed %35.20f", g);
213
                        Tcl_Eval( theTclInterp, tclAssignment);
214
                        // Compute the gradient 'dgdu' by finite difference
215
                        sprintf(tclAssignment , "($lsfperturbed-$lsfvalue)/([nodeDisp %d %d ]*0.001)",nodeNumber,direction);
216
                        Tcl_ExprDouble( theTclInterp, tclAssignment, &onedgdu );
217
                        dgdu(count_u-1)=onedgdu;
218
                        // Make assignment back to its original value
219
                        sprintf(tclAssignment,"set nd_%d_%d [nodeDisp %d %d ]",nodeNumber,direction,nodeNumber,direction);
220
                        Tcl_Eval( theTclInterp, tclAssignment);
221
                        // Assign one row in the 'dudx' matrix
222
                        for (int i=1; i<=nrv; i++) {
223
                                sprintf(tclAssignment , "set sens [sensNodeDisp %d %d %d ]",nodeNumber,direction,i);
224
                                Tcl_Eval( theTclInterp, tclAssignment);
225
                                sprintf(tclAssignment , "$sens ");
226
                                Tcl_ExprDouble( theTclInterp, tclAssignment, &onedudx );
227
                                dudx( (count_u-1), (i-1) ) = onedudx;
228
                        }
229
 
230
                }
231
 
232
                tokenPtr2 = strtok( NULL, " _");  // read next token and go up and check the while condition again
233
 
234
        }
235
 
236
        // Evaluate the product that yields 'dgdx'
237
        Vector temp;
238
        temp = dudx ^ dgdu;
239
        dgdx = temp + dgdxufixed;
240
 
241
        delete lsf_copy1;
242
        delete lsf_copy2;
243
 
244
        (*grad_g) = dgdx;
245
 
246
        return 0;
247
 
248
}