OOFEM 3.0
Loading...
Searching...
No Matches
interpolatingfunction.C
Go to the documentation of this file.
1/*
2 *
3 * ##### ##### ###### ###### ### ###
4 * ## ## ## ## ## ## ## ### ##
5 * ## ## ## ## #### #### ## # ##
6 * ## ## ## ## ## ## ## ##
7 * ## ## ## ## ## ## ## ##
8 * ##### ##### ## ###### ## ##
9 *
10 *
11 * OOFEM : Object Oriented Finite Element Code
12 *
13 * Copyright (C) 1993 - 2025 Borek Patzak
14 *
15 *
16 *
17 * Czech Technical University, Faculty of Civil Engineering,
18 * Department of Structural Mechanics, 166 29 Prague, Czech Republic
19 *
20 * This library is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU Lesser General Public
22 * License as published by the Free Software Foundation; either
23 * version 2.1 of the License, or (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 * Lesser General Public License for more details.
29 *
30 * You should have received a copy of the GNU Lesser General Public
31 * License along with this library; if not, write to the Free Software
32 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33 */
34
36#include "floatarray.h"
37#include "classfactory.h"
38#include "error.h"
39
40#include <iostream>
41#include <fstream>
42
43namespace oofem {
45
46InterpolatingFuction :: InterpolatingFuction(int num, Domain *d) : Function(num, d)
47{ }
48
49InterpolatingFuction :: ~InterpolatingFuction()
50{ }
51
52
53void
54InterpolatingFuction :: evaluate(FloatArray &answer, const std :: map< std :: string, FunctionArgument > &valDict, GaussPoint *gp, double param)
55{
56 double randomVariable = 0.;
57
58 auto it = valDict.find("x");
59 if ( it == valDict.end() ) {
60 OOFEM_ERROR("Coordinate needed for evaluating function");
61 }
62 const FloatArray &globalCoordinates = it->second.val1;
63
64 if(this->dimension == 2){//2D Case
65 // Map the corresponding random value from the field
66 int countXDown = 0, countXUp = 0, countYDown = 0, countYUp = 0;
67 //Determine x count
68 double helpX = 0., helpY = 0.;
69 int i = 0, exitFlag = 0;
70
71 //Check if gp lies in random field
72 double randomXStart = field(0);
73 double randomXEnd = field( 3 * ( numberReal(0) - 1 ) * numberReal(1) );
74 double randomYStart = field(1);
75 double randomYEnd = field(3 * ( numberReal(0) - 1 ) + 1);
76
77 if ( !( globalCoordinates.at(1) > randomXStart && globalCoordinates.at(1) < randomXEnd &&
78 globalCoordinates.at(2) > randomYStart && globalCoordinates.at(2) < randomYEnd ) ) {
79 randomVariable = 1;
80 } else {
81 //Determine the corner points of the square over which we are going to interpolate
82 while ( exitFlag == 0 ) {
83 if ( field( 3 * i * numberReal(1) ) > globalCoordinates.at(1) ) {
84 if ( i == 0 ) { //Check soundness
85 OOFEM_ERROR("i is zero");
86 } else if ( i == numberReal(0) ) {
87 OOFEM_ERROR("i is equal to realNumber");
88 }
89
90 exitFlag = 1;
91 countXDown = i - 1;
92 countXUp = i;
93 helpX = ( globalCoordinates.at(1) - field( 3 * countXDown * numberReal(1) ) )
94 / ( field( 3 * countXUp * numberReal(1) ) - field( 3 * countXDown * numberReal(1) ) );
95 }
96
97 i++;
98 }
99
100 //Determine y count
101 i = 0, exitFlag = 0;
102 while ( exitFlag == 0 ) {
103 if ( field(3 * i + 1) > globalCoordinates.at(2) ) {
104 if ( i == 0 ) {
105 OOFEM_ERROR("i is zero");
106 } else if ( i == numberReal(0) ) {
107 OOFEM_ERROR("i is equal to realNumber");
108 }
109
110 exitFlag = 1;
111 countYDown = i - 1;
112 countYUp = i;
113 helpY = ( globalCoordinates.at(2) - field(3 * countYDown + 1) )
114 / ( field(3 * countYUp + 1) - field(3 * countYDown + 1) );
115 }
116
117 i++;
118 }
119
120 //Do the interpolation
121 if ( randomVariable == 0. ) {
122 randomVariable =
123 ( 1. - helpX ) * ( 1. - helpY ) * field(3 * ( countXDown * numberReal(1) + countYDown ) + 2) +
124 helpX * ( 1. - helpY ) * field(3 * ( countXUp * numberReal(1) + countYDown ) + 2) +
125 helpX *helpY *field(3 * ( countXUp *numberReal ( 1 ) + countYUp ) + 2) +
126 ( 1. - helpX ) * helpY * field(3 * ( countXDown * numberReal(1) + countYUp ) + 2);
127 }
128 }
129 }
130 else if(this->dimension == 3){//3D case
131 // Map the corresponding random value from the field
132 int countXDown = 0, countXUp = 0, countYDown = 0, countYUp = 0, countZDown = 0, countZUp = 0;
133 //Determine x count
134 double helpX = 0., helpY = 0., helpZ = 0.;
135 int i = 0, exitFlag = 0;
136
137 //Check if gp lies in random field
138 double randomXStart = field.at(1);
139 double randomXEnd = field(4 * ( numberReal.at(1)*numberReal.at(2)*numberReal.at(3) - 1 ));
140 double randomYStart = field.at(2);
141 double randomYEnd = field(4 * ( numberReal.at(1)*numberReal.at(2)*numberReal.at(3) - 1 ) + 1);
142 double randomZStart = field.at(3);
143 double randomZEnd = field(4 * ( numberReal.at(1)*numberReal.at(2)*numberReal.at(3) - 1 ) + 2);
144
145 double fieldX0Y0Z0, fieldX1Y0Z0, fieldX0Y1Z0, fieldX0Y0Z1, fieldX1Y1Z0, fieldX1Y1Z1, fieldX0Y1Z1, fieldX1Y0Z1;
146 double field00, field01, field10, field11;
147 double field0,field1;
148
149 if ( !( globalCoordinates.at(1) >= randomXStart && globalCoordinates.at(1) <= randomXEnd &&
150 globalCoordinates.at(2) >= randomYStart && globalCoordinates.at(2) <= randomYEnd &&
151 globalCoordinates.at(3) >= randomZStart && globalCoordinates.at(3) <= randomZEnd ) ) {
152 randomVariable = 1;
153 printf("Warning: External field too small\n");
154 } else {
155 //Determine the corner points of the square over which we are going to interpolate
156 //Determine xCount
157 while ( exitFlag == 0 ) {
158 if ( field.at( 4 * i * numberReal.at(2)*numberReal.at(3) +1) > globalCoordinates.at(1) ) {
159 if ( i == 0 ) { //Check soundness
160 OOFEM_ERROR("error in externalfieldgenerator.C: i is zero");
161 } else if ( i > numberReal.at(1) ) {
162 OOFEM_ERROR("error in externalfieldgenerator.C: i is greater than realNumber1");
163 }
164
165 exitFlag = 1;
166 countXDown = i - 1;
167 countXUp = i;
168 helpX = ( globalCoordinates.at(1) - field.at( 4 * countXDown * numberReal.at(2) * numberReal.at(3)+1 ) )
169 / ( field.at( 4 * countXUp * numberReal.at(2) * numberReal.at(3)+1 ) - field.at( 4 * countXDown * numberReal.at(2) * numberReal.at(3) +1) );
170 }
171
172 i++;
173 }
174
175 //Determine y count
176 i = 0, exitFlag = 0;
177 while ( exitFlag == 0 ) {
178 if ( field.at(4 *i*numberReal.at(3) + 2) > globalCoordinates.at(2) ) {
179 if ( i == 0 ) {
180 OOFEM_ERROR("error in externalfieldgenerator.C: i is zero");
181 } else if ( i > numberReal.at(2) ) {//Not sure that this is a problem
182 OOFEM_ERROR("error in externalfieldgenerator.C: i is greater than realNumber2");
183 }
184
185 exitFlag = 1;
186 countYDown = i - 1;
187 countYUp = i;
188 helpY = ( globalCoordinates.at(2) - field.at(4 * countYDown*numberReal.at(3) + 2) )
189 / ( field.at(4 * countYUp*numberReal.at(3) + 2) - field.at(4 * countYDown*numberReal.at(3) + 2) );
190 }
191
192 i++;
193 }
194
195
196 //Determine z count
197 i = 0, exitFlag = 0;
198 while ( exitFlag == 0 ) {
199 if ( field.at(4 * i + 3) > globalCoordinates.at(3) ) {
200 if ( i == 0 ) {
201 OOFEM_ERROR("error in externalfieldgenerator.C: i is zero");
202 } else if ( i > numberReal.at(3) ) {
203 OOFEM_ERROR("error in externalfieldgenerator.C: i is equal to realNumber");
204 }
205
206 exitFlag = 1;
207 countZDown = i - 1;
208 countZUp = i;
209 helpZ = ( globalCoordinates.at(3) - field.at(4 * countZDown + 3) )
210 / ( field.at(4 * countZUp + 3) - field.at(4 * countZDown + 3) );
211 }
212
213 i++;
214 }
215
216
217 //Do the interpolation in 3D.
218 if ( randomVariable == 0. ) {
219
220 fieldX0Y0Z0 = field.at(4 * ( countXDown * numberReal.at(2)*numberReal.at(3) + countYDown*numberReal.at(3) + countZDown ) + 4);
221 fieldX1Y0Z0 = field.at(4 * ( countXUp * numberReal.at(2)*numberReal.at(3) + countYDown*numberReal.at(3) + countZDown ) + 4);
222 fieldX0Y1Z0 = field.at(4 * ( countXDown * numberReal.at(2)*numberReal.at(3) + countYUp*numberReal.at(3) + countZDown ) + 4);
223 fieldX0Y0Z1 = field.at(4 * ( countXDown * numberReal.at(2)*numberReal.at(3) + countYDown*numberReal.at(3) + countZUp ) + 4);
224 fieldX1Y1Z0 = field.at(4 * ( countXUp * numberReal.at(2)*numberReal.at(3) + countYUp*numberReal.at(3) + countZDown ) + 4);
225 fieldX1Y1Z1 = field.at(4 * ( countXUp * numberReal.at(2)*numberReal.at(3) + countYUp*numberReal.at(3) + countZUp ) + 4);
226 fieldX0Y1Z1 = field.at(4 * ( countXDown * numberReal.at(2)*numberReal.at(3) + countYUp*numberReal.at(3) + countZUp ) + 4);
227 fieldX1Y0Z1 = field.at(4 * ( countXUp * numberReal.at(2)*numberReal.at(3) + countYDown*numberReal.at(3) + countZUp ) + 4);
228
229 field00 = fieldX0Y0Z0 * (1. - helpX) + fieldX1Y0Z0 * helpX;
230 field10 = fieldX0Y1Z0 * (1. - helpX) + fieldX1Y1Z0 * helpX;
231 field01 = fieldX0Y0Z1 * (1. - helpX) + fieldX1Y0Z1 * helpX;
232 field11 = fieldX0Y1Z1 * (1. - helpX) + fieldX1Y1Z1 * helpX;
233
234 field0 = field00 * (1.-helpY) + field10*helpY;
235 field1 = field01 * (1.-helpY) + field11*helpY;
236
237 randomVariable = field0*(1. - helpZ) + field1*helpZ;
238 }
239 }
240 }
241 else{
242 OOFEM_ERROR("Unknown dimension. Must be 2 or 3.");
243 }
244
245 answer = Vec1(randomVariable);
246}
247
248double
249InterpolatingFuction :: evaluateAtTime(double t)
250{
251 OOFEM_ERROR("InterpolatingFunction needs coordinates to evaluate.");
252}
253
254
255
256void
257InterpolatingFuction :: initializeFrom(InputRecord &ir)
258{
259 std :: string name;
260
261 this->dimension = 2;
263
265
266 std :: ifstream inputField( name.c_str() );
267
268 if ( !inputField.is_open() ) {
269 throw ValueInputException(ir, _IFT_InterpolatingFuction_filename, "Unable to open file: " + name);
270 }
271
272 if(this->dimension == 2){//2D field
273 double deltaX, deltaY;
274 numberReal.resize(2);
275 numberReal.zero();
276 inputField >> numberReal(0) >> numberReal(1) >> deltaX >> deltaY;
277 field.resize( 3 * numberReal(0) * numberReal(1) );
278 field.zero();
279
280 //Read in coordinates and field values
281 for ( int i = 0; i < numberReal(0) * numberReal(1); i++ ) {
282 inputField >> field(3 * i) >> field(3 * i + 1) >> field(3 * i + 2);
283 }
284 }
285 else{//3D field
286 double deltaX, deltaY, deltaZ;
287 numberReal.resize(3);
288 numberReal.zero();
289 inputField >> numberReal(0) >> numberReal(1) >> numberReal(2) >> deltaX >> deltaY >> deltaZ;
290 field.resize( 4 * numberReal.at(1) * numberReal.at(2) * numberReal.at(3) );
291 field.zero();
292
293 //Read in coordinates and field values
294 for ( int i = 0; i < numberReal.at(1) * numberReal.at(2) * numberReal.at(3) ; i++ ) {
295 inputField >> field.at(4 * i+1) >> field.at(4 * i + 2) >> field.at(4 * i + 3) >> field.at(4 * i + 4);
296 }
297 }
298}
299} // end namespace oofem
#define REGISTER_Function(class)
double & at(Index i)
Definition floatarray.h:202
Function(int n, Domain *d)
Definition function.C:44
#define OOFEM_ERROR(...)
Definition error.h:79
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Definition inputrecord.h:75
#define IR_GIVE_FIELD(__ir, __value, __id)
Definition inputrecord.h:67
#define _IFT_InterpolatingFuction_filename
#define _IFT_InterpolatingFuction_dim
static FloatArray Vec1(const double &a)
Definition floatarray.h:605

This page is part of the OOFEM-3.0 documentation. Copyright Copyright (C) 1994-2025 Borek Patzak Bořek Patzák
Project e-mail: oofem@fsv.cvut.cz
Generated at for OOFEM by doxygen 1.15.0 written by Dimitri van Heesch, © 1997-2011