source: issm/trunk-jpl/src/c/objects/Inputs/TransientInput.cpp@ 12744

Last change on this file since 12744 was 12744, checked in by Mathieu Morlighem, 13 years ago

Added TransientParam

File size: 12.2 KB
RevLine 
[8757]1/*!\file TransientInput.c
2 * \brief: implementation of the TransientInput object
3 */
[12326]4/*Headers{{{*/
[8757]5#ifdef HAVE_CONFIG_H
[9320]6 #include <config.h>
[8757]7#else
8#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
9#endif
10
[9320]11#include <stdio.h>
[8757]12#include <string.h>
13#include "../objects.h"
14#include "../../EnumDefinitions/EnumDefinitions.h"
15#include "../../shared/shared.h"
16#include "../../Container/Container.h"
17#include "../../include/include.h"
18/*}}}*/
19
20/*TransientInput constructors and destructor*/
[12326]21/*FUNCTION TransientInput::TransientInput(){{{*/
[8757]22TransientInput::TransientInput(){
[8791]23
[8967]24 enum_type=UNDEF;
[8757]25 inputs=NULL;
[8791]26 this->numtimesteps=0;
27 this->parameters=NULL;
28 this->timesteps=NULL;
29
[8757]30}
31/*}}}*/
[12326]32/*FUNCTION TransientInput::TransientInput(int in_enum_type){{{*/
[8757]33TransientInput::TransientInput(int in_enum_type)
34{
35 /*Set Enum*/
36 enum_type=in_enum_type;
37
38 /*Allocate values and timesteps, and copy: */
39 this->numtimesteps=0;
40 this->timesteps=NULL;
41 inputs = new Inputs();
42 this->parameters=NULL;
43
44}
45/*}}}*/
[12326]46/*FUNCTION TransientInput::~TransientInput{{{*/
[8757]47TransientInput::~TransientInput(){
[12530]48 xDelete<IssmDouble>(this->timesteps);
[8791]49 this->timesteps=NULL;
[8757]50 this->numtimesteps=0;
51 parameters=NULL;
52 delete this->inputs;
53 return;
54}
55/*}}}*/
56
57/*Object virtual functions definitions:*/
[12326]58/*FUNCTION TransientInput::Echo {{{*/
[8757]59void TransientInput::Echo(void){
60 this->DeepEcho();
61}
62/*}}}*/
[12326]63/*FUNCTION TransientInput::DeepEcho{{{*/
[8757]64void TransientInput::DeepEcho(void){
65
66 int i;
67
[12511]68 _printLine_("TransientInput:");
69 _printLine_(" enum: " << this->enum_type << " (" << EnumToStringx(this->enum_type) << ")");
70 _printLine_(" numtimesteps: " << this->numtimesteps);
71 _printLine_("---inputs: ");
[8757]72 for(i=0;i<this->numtimesteps;i++){
[12511]73 _printLine_(" time: " << this->timesteps[i] << " ");
[8757]74 ((Input*)this->inputs->GetObjectByOffset(i))->Echo();
75 }
76}
77/*}}}*/
[12326]78/*FUNCTION TransientInput::Id{{{*/
[8757]79int TransientInput::Id(void){ return -1; }
80/*}}}*/
[12326]81/*FUNCTION TransientInput::MyRank{{{*/
[8757]82int TransientInput::MyRank(void){
83 extern int my_rank;
84 return my_rank;
85}
86/*}}}*/
[12326]87/*FUNCTION TransientInput::ObjectEnum{{{*/
[9883]88int TransientInput::ObjectEnum(void){
[8757]89
90 return TransientInputEnum;
91
92}
93/*}}}*/
[12326]94/*FUNCTION TransientInput::copy{{{*/
[8757]95Object* TransientInput::copy() {
96
97 TransientInput* output=NULL;
98
99 output = new TransientInput();
100 output->enum_type=this->enum_type;
101 output->numtimesteps=this->numtimesteps;
[12530]102 output->timesteps=xNew<IssmDouble>(this->numtimesteps);
103 memcpy(output->timesteps,this->timesteps,this->numtimesteps*sizeof(IssmDouble));
[8757]104 output->inputs=(Inputs*)this->inputs->Copy();
105 output->parameters=this->parameters;
106
107 return output;
108
109}
110/*}}}*/
111
112/*TransientInput management*/
[12326]113/*FUNCTION TransientInput::InstanceEnum{{{*/
[9883]114int TransientInput::InstanceEnum(void){
[8757]115
116 return this->enum_type;
117
118}
119/*}}}*/
[12326]120/*FUNCTION TransientInput::SpawnTriaInput{{{*/
[8757]121Input* TransientInput::SpawnTriaInput(int* indices){
122
123 /*output*/
124 TransientInput* outinput=NULL;
125
126 /*Create new Transientinput (copy of current input)*/
127 outinput=new TransientInput();
128 outinput->enum_type=this->enum_type;
[8791]129 outinput->numtimesteps=this->numtimesteps;
[12530]130 outinput->timesteps=xNew<IssmDouble>(this->numtimesteps);
131 memcpy(outinput->timesteps,this->timesteps,this->numtimesteps*sizeof(IssmDouble));
[8757]132 outinput->inputs=(Inputs*)this->inputs->SpawnTriaInputs(indices);
[8791]133 outinput->parameters=this->parameters;
[8757]134
135 /*Assign output*/
136 return outinput;
137
138}
139/*}}}*/
[12326]140/*FUNCTION TransientInput::SpawnResult{{{*/
[12530]141ElementResult* TransientInput::SpawnResult(int step, IssmDouble time){
[8757]142
143 ElementResult* elementresult=NULL;
144
145 /*Ok, we want to spawn an ElementResult. We have the time, just get
146 *the correct values: */
147 Input* input=GetTimeInput(time);
148
149 elementresult=input->SpawnResult(step,time);
150
[8791]151 delete input;
[8757]152
153 return elementresult;
154}
155/*}}}*/
156
157/*Object functions*/
[12530]158/*FUNCTION TransientInput::GetInputValue(IssmDouble* pvalue,GaussTria* gauss){{{*/
159void TransientInput::GetInputValue(IssmDouble* pvalue,GaussTria* gauss){
160 IssmDouble time;
[8757]161
162 /*First, recover current time from parameters: */
[8791]163 this->parameters->FindParam(&time,TimeEnum);
[8757]164
165 /*Retrieve interpolated values for this time step: */
166 Input* input=GetTimeInput(time);
167
168 /*Call input function*/
[10135]169 input->GetInputValue(pvalue,gauss);
[8757]170
[8791]171 delete input;
[12326]172}
173/*}}}*/
[12704]174/*FUNCTION TransientInput::GetInputValue(IssmDouble* pvalue,GaussPenta* gauss){{{*/
175void TransientInput::GetInputValue(IssmDouble* pvalue,GaussPenta* gauss){
176 IssmDouble time;
177
178 /*First, recover current time from parameters: */
179 this->parameters->FindParam(&time,TimeEnum);
180
181 /*Retrieve interpolated values for this time step: */
182 Input* input=GetTimeInput(time);
183
184 /*Call input function*/
185 input->GetInputValue(pvalue,gauss);
186
187 delete input;
188}
189/*}}}*/
[12530]190/*FUNCTION TransientInput::GetInputValue(IssmDouble* pvalue,GaussTria* gauss,IssmDouble time){{{*/
191void TransientInput::GetInputValue(IssmDouble* pvalue,GaussTria* gauss,IssmDouble time){
[8757]192
[12326]193 /*Retrieve interpolated values for this time step: */
194 Input* input=GetTimeInput(time);
195
196 /*Call input function*/
197 input->GetInputValue(pvalue,gauss);
198
199 delete input;
[8757]200}
201/*}}}*/
[12704]202/*FUNCTION TransientInput::GetInputValue(IssmDouble* pvalue,GaussPenta* gauss,IssmDouble time){{{*/
203void TransientInput::GetInputValue(IssmDouble* pvalue,GaussPenta* gauss,IssmDouble time){
204
205 /*Retrieve interpolated values for this time step: */
206 Input* input=GetTimeInput(time);
207
208 /*Call input function*/
209 input->GetInputValue(pvalue,gauss);
210
211 delete input;
212}
213/*}}}*/
[12550]214/*FUNCTION TransientInput::GetInputDerivativeValue(IssmDouble* p, IssmDouble* xyz_list, GaussTria* gauss){{{*/
215void TransientInput::GetInputDerivativeValue(IssmDouble* p, IssmDouble* xyz_list, GaussTria* gauss){
[8757]216
[12530]217 IssmDouble time;
[8757]218
219 /*First, recover current time from parameters: */
220 parameters->FindParam(&time,TimeEnum);
221
222 /*Retrieve interpolated values for this time step: */
223 Input* input=GetTimeInput(time);
224
225 /*Call input function*/
[10135]226 input->GetInputDerivativeValue(p,xyz_list,gauss);
[8757]227
[8791]228 delete input;
229
[8757]230}
231/*}}}*/
[12326]232/*FUNCTION TransientInput::ChangeEnum{{{*/
[8757]233void TransientInput::ChangeEnum(int newenumtype){
234 this->enum_type=newenumtype;
235}
236/*}}}*/
[12326]237/*FUNCTION TransientInput::GetInputAverage{{{*/
[12530]238void TransientInput::GetInputAverage(IssmDouble* pvalue){
[8757]239
[12530]240 IssmDouble time;
[8757]241
242 /*First, recover current time from parameters: */
243 parameters->FindParam(&time,TimeEnum);
244
245 /*Retrieve interpolated values for this time step: */
246 Input* input=GetTimeInput(time);
247
248 /*Call input function*/
[10135]249 input->GetInputAverage(pvalue);
[8757]250
[8791]251 delete input;
[8757]252
253}
254/*}}}*/
255
256/*Intermediary*/
[12326]257/*FUNCTION TransientInput::AddTimeInput{{{*/
[12530]258void TransientInput::AddTimeInput(Input* input,IssmDouble time){
[12326]259
260 /*insert values at time step: */
261 if (this->numtimesteps>0 && time<=this->timesteps[this->numtimesteps-1]) _assert_("timestep values must increase sequentially");
262
263 //copy timesteps, add the new time, delete previous timesteps, and add the new input: inputs->AddObject(input);
[12530]264 IssmDouble* old_timesteps=NULL;
[12326]265
266 if (this->numtimesteps > 0){
[12530]267 old_timesteps=xNew<IssmDouble>(this->numtimesteps);
268 memcpy(old_timesteps,this->timesteps,this->numtimesteps*sizeof(IssmDouble));
269 xDelete<IssmDouble>(this->timesteps);
[12326]270 }
271
272 this->numtimesteps=this->numtimesteps+1;
[12530]273 this->timesteps=xNew<IssmDouble>(this->numtimesteps);
[12326]274
275 if (this->numtimesteps > 1){
[12530]276 memcpy(this->timesteps,old_timesteps,(this->numtimesteps-1)*sizeof(IssmDouble));
277 xDelete<IssmDouble>(old_timesteps);
[12326]278 }
279
280 /*go ahead and plug: */
281 this->timesteps[this->numtimesteps-1]=time;
282 inputs->AddObject(input);
283
284}
285/*}}}*/
286/*FUNCTION TransientInput::SquareMin{{{*/
[12530]287void TransientInput::SquareMin(IssmDouble* psquaremin, bool process_units,Parameters* parameters){
[8757]288
[12530]289 IssmDouble time;
[8757]290
291 /*First, recover current time from parameters: */
292 parameters->FindParam(&time,TimeEnum);
293
294 /*Retrieve interpolated values for this time step: */
295 Input* input=GetTimeInput(time);
296
297 /*Call input function*/
298 input->SquareMin(psquaremin,process_units,parameters);
299
[8791]300 delete input;
[8757]301
302}
303/*}}}*/
[12326]304/*FUNCTION TransientInput::InfinityNorm{{{*/
[12530]305IssmDouble TransientInput::InfinityNorm(void){
[8757]306
[12530]307 IssmDouble time;
308 IssmDouble infnorm;
[8757]309
310 /*First, recover current time from parameters: */
311 parameters->FindParam(&time,TimeEnum);
312
313 /*Retrieve interpolated values for this time step: */
314 Input* input=GetTimeInput(time);
315
316 /*Call input function*/
317 infnorm=input->InfinityNorm();
318
[11197]319 /*Clean-up and return*/
[8791]320 delete input;
[11197]321 return infnorm;
[8757]322}
323/*}}}*/
[12326]324/*FUNCTION TransientInput::Max{{{*/
[12530]325IssmDouble TransientInput::Max(void){
[8757]326
[12530]327 IssmDouble time;
328 IssmDouble max;
[8757]329
330 /*First, recover current time from parameters: */
331 parameters->FindParam(&time,TimeEnum);
332
333 /*Retrieve interpolated values for this time step: */
334 Input* input=GetTimeInput(time);
335
336 /*Call input function*/
337 max=input->Max();
338
[8791]339 delete input;
[8757]340
341 return max;
342}
343/*}}}*/
[12326]344/*FUNCTION TransientInput::MaxAbs{{{*/
[12530]345IssmDouble TransientInput::MaxAbs(void){
[8757]346
[12530]347 IssmDouble time;
348 IssmDouble maxabs;
[8757]349
350 /*First, recover current time from parameters: */
351 parameters->FindParam(&time,TimeEnum);
352
353 /*Retrieve interpolated values for this time step: */
354 Input* input=GetTimeInput(time);
355
356 /*Call input function*/
357 maxabs=input->MaxAbs();
358
[11197]359 /*Clean-up and return*/
[8791]360 delete input;
[8757]361 return maxabs;
[8791]362
[8757]363}
364/*}}}*/
[12326]365/*FUNCTION TransientInput::Min{{{*/
[12530]366IssmDouble TransientInput::Min(void){
[8757]367
[12530]368 IssmDouble time;
369 IssmDouble min;
[8757]370
371 /*First, recover current time from parameters: */
372 parameters->FindParam(&time,TimeEnum);
373
374 /*Retrieve interpolated values for this time step: */
375 Input* input=GetTimeInput(time);
376
377 /*Call input function*/
378 min=input->Min();
379
[11197]380 /*Clean-up and return*/
[8791]381 delete input;
[8757]382 return min;
[8791]383
[8757]384}
385/*}}}*/
[12326]386/*FUNCTION TransientInput::MinAbs{{{*/
[12530]387IssmDouble TransientInput::MinAbs(void){
[8757]388
[12530]389 IssmDouble time;
390 IssmDouble minabs;
[8757]391
392 /*First, recover current time from parameters: */
393 parameters->FindParam(&time,TimeEnum);
394
395 /*Retrieve interpolated values for this time step: */
396 Input* input=GetTimeInput(time);
397
398 /*Call input function*/
399 minabs=input->MinAbs();
400
[11197]401 /*Clean-up and return*/
[8791]402 delete input;
[8757]403 return minabs;
404}
405/*}}}*/
[12326]406/*FUNCTION TransientInput::GetVectorFromInputs{{{*/
[11695]407void TransientInput::GetVectorFromInputs(Vector* vector,int* doflist){
[8757]408
[12530]409 IssmDouble time;
[8757]410
411 /*First, recover current time from parameters: */
412 parameters->FindParam(&time,TimeEnum);
413
414 /*Retrieve interpolated values for this time step: */
415 Input* input=GetTimeInput(time);
416
417 /*Call input function*/
418 input->GetVectorFromInputs(vector,doflist);
419
[8791]420 delete input;
[8757]421
422} /*}}}*/
[12326]423/*FUNCTION TransientInput::GetTimeInput{{{*/
[12530]424Input* TransientInput::GetTimeInput(IssmDouble intime){
[8757]425
426 int i,j;
[12530]427 IssmDouble deltat;
428 IssmDouble alpha1,alpha2;
[8757]429 bool found=false;
430 Input* input=NULL;
431 Input* input1=NULL;
432 Input* input2=NULL;
433
434 /*Ok, we have the time, go through the timesteps, and figure out which interval we
435 *fall within. Then interpolate the values on this interval: */
436 if(intime<this->timesteps[0]){
437 /*get values for the first time: */
438 input=(Input*)((Input*)this->inputs->GetObjectByOffset(0))->copy();
439 found=true;
440 }
441 else if(intime>this->timesteps[this->numtimesteps-1]){
442 /*get values for the last time: */
443 input=(Input*)((Input*)this->inputs->GetObjectByOffset(numtimesteps-1))->copy();
444 found=true;
445 }
446 else{
447 /*Find which interval we fall within: */
448 for(i=0;i<this->numtimesteps;i++){
449 if(intime==this->timesteps[i]){
450 /*We are right on one step time: */
451 input=(Input*)((Input*)this->inputs->GetObjectByOffset(i))->copy();
452 found=true;
453 break; //we are done with the time interpolation.
454 }
455 else{
456 if(this->timesteps[i]<intime && intime<this->timesteps[i+1]){
457 /*ok, we have the interval ]i:i+1[. Interpolate linearly for now: */
458 deltat=this->timesteps[i+1]-this->timesteps[i];
459 alpha2=(intime-this->timesteps[i])/deltat;
[12744]460 alpha1=(1.0-alpha2);
[8757]461
462 input1=(Input*)this->inputs->GetObjectByOffset(i);
463 input2=(Input*)this->inputs->GetObjectByOffset(i+1);
464
465 input=(Input*)input1->copy();
466 input->Scale(alpha1);
467 input->AXPY(input2,alpha2);
468
469 found=true;
470 break;
471 }
472 else continue; //keep looking on the next interval
473 }
474 }
475 }
[12493]476 if(!found)_error2_("did not find time interval on which to interpolate forcing values!");
[8757]477
478 /*Assign output pointer*/
479 return input;
480}
481/*}}}*/
[12326]482/*FUNCTION TransientInput::Configure{{{*/
[8757]483void TransientInput::Configure(Parameters* parameters){
484 this->parameters=parameters;
485}
486/*}}}*/
Note: See TracBrowser for help on using the repository browser.