Changeset 24313 for issm/trunk/src/c/classes/Inputs/TransientInput.cpp
- Timestamp:
- 11/01/19 12:01:57 (5 years ago)
- Location:
- issm/trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk
-
issm/trunk/src
- Property svn:mergeinfo changed
-
issm/trunk/src/c
- Property svn:ignore
-
issm/trunk/src/c/classes/Inputs/TransientInput.cpp
r22758 r24313 60 60 } 61 61 /*}}}*/ 62 void TransientInput::AddTimeInput(Input* input,IssmDouble time){/*{{{*/ 63 64 /*insert values at time step: */ 65 if (this->numtimesteps>0 && time<=this->timesteps[this->numtimesteps-1]) _error_("timestep values must increase sequentially"); 66 67 //copy timesteps, add the new time, delete previous timesteps, and add the new input: inputs->AddObject(input); 68 IssmDouble* old_timesteps=NULL; 69 70 if (this->numtimesteps > 0){ 71 old_timesteps=xNew<IssmDouble>(this->numtimesteps); 72 xMemCpy(old_timesteps,this->timesteps,this->numtimesteps); 73 xDelete(this->timesteps); 74 } 75 76 this->numtimesteps=this->numtimesteps+1; 77 this->timesteps=xNew<IssmDouble>(this->numtimesteps); 78 79 if (this->numtimesteps > 1){ 80 xMemCpy(this->timesteps,old_timesteps,this->numtimesteps-1); 81 xDelete(old_timesteps); 82 } 83 84 /*go ahead and plug: */ 85 this->timesteps[this->numtimesteps-1]=time; 86 inputs->AddObject(input); 87 88 } 89 /*}}}*/ 90 void TransientInput::AddTimeInput(Input* input){/*{{{*/ 91 92 _assert_(this->inputs->Size()<this->numtimesteps); 93 inputs->AddObject(input); 94 95 } 96 /*}}}*/ 62 97 63 98 /*Object virtual functions definitions:*/ … … 87 122 _printf_(" enum: " << this->enum_type << " (" << EnumToStringx(this->enum_type) << ")\n"); 88 123 _printf_(" numtimesteps: " << this->numtimesteps << "\n"); 89 _printf_("---inputs: \n"); 124 _printf_("---inputs: \n"); 90 125 for(i=0;i<this->numtimesteps;i++){ 91 126 _printf_(" time: " << this->timesteps[i]<<" "); … … 120 155 121 156 /*TransientInput management*/ 157 void TransientInput::Configure(Parameters* parameters){/*{{{*/ 158 this->parameters=parameters; 159 } 160 /*}}}*/ 161 int TransientInput::GetResultArraySize(void){/*{{{*/ 162 163 return 1; 164 } 165 /*}}}*/ 166 int TransientInput::GetResultInterpolation(void){/*{{{*/ 167 168 IssmDouble time; 169 int output; 170 171 parameters->FindParam(&time,TimeEnum); 172 Input* input=GetTimeInput(time); 173 output = input->GetResultInterpolation(); 174 175 /*Clean up and return*/ 176 delete input; 177 return output; 178 179 } 180 /*}}}*/ 181 int TransientInput::GetResultNumberOfNodes(void){/*{{{*/ 182 183 IssmDouble time; 184 int output; 185 186 parameters->FindParam(&time,TimeEnum); 187 Input* input=GetTimeInput(time); 188 output = input->GetResultNumberOfNodes(); 189 190 /*Clean up and return*/ 191 delete input; 192 return output; 193 194 } 195 /*}}}*/ 122 196 int TransientInput::InstanceEnum(void){/*{{{*/ 123 197 … … 174 248 } 175 249 /*}}}*/ 176 void TransientInput::GetInputAllTimeAverages(IssmDouble** pvalues,IssmDouble** ptimes, int* pnumtimes){/*{{{*/ 250 void TransientInput::GetInputAverage(IssmDouble* pvalue){/*{{{*/ 251 252 IssmDouble time; 253 254 /*First, recover current time from parameters: */ 255 parameters->FindParam(&time,TimeEnum); 256 257 /*Retrieve interpolated values for this time step: */ 258 Input* input=GetTimeInput(time); 259 260 /*Call input function*/ 261 input->GetInputAverage(pvalue); 262 263 delete input; 264 265 } 266 /*}}}*/ 267 void TransientInput::GetInputAverageOverTimeSlice(IssmDouble* pvalue, Gauss* gauss, IssmDouble start_time,IssmDouble end_time){/*{{{*/ 268 269 int averaging = 0; 270 271 Input* input=GetInputAverageOverTime(start_time,end_time,averaging); 272 273 /*Call input function*/ 274 input->GetInputValue(pvalue, gauss); 275 276 //*pvalues=values; 277 delete input; 278 } 279 /*}}}*/ 280 Input* TransientInput::GetInputAverageOverTime(IssmDouble start_time,IssmDouble end_time,int averaging){/*{{{*/ 281 282 int found; 283 int offset,start_offset,end_offset; 284 IssmDouble subdt; 285 IssmDouble slice_duration; 286 287 this->parameters->FindParam(&subdt,TimesteppingTimeStepEnum); //duration of each substeps 288 289 Input *averageinput = NULL; 290 291 292 slice_duration=end_time-start_time; 293 start_time+=subdt; //because time is actually considered at the end of the timestep 294 295 /*go through the timesteps, and grab offset for the start of the slice*/ 296 found=binary_search(&offset,start_time,this->timesteps,this->numtimesteps); 297 if(!found) _error_("Input not found (is TransientInput sorted ?)"); 298 /*go through the timesteps, and grab offset for the end of the slice*/ 299 found=binary_search(&end_offset,end_time,this->timesteps,this->numtimesteps); 300 if(!found) _error_("Input not found (is TransientInput sorted ?)"); 301 302 start_offset = offset; 303 //stack the input for each timestep in the slice 304 while(offset <= end_offset ){ 305 Input *currentinput = NULL; 306 307 if (offset==-1){ 308 /*get values for the first time: */ 309 _assert_(start_time<this->timesteps[0]); 310 currentinput=(Input*)((Input*)this->inputs->GetObjectByOffset(0))->copy(); 311 } 312 else if(offset==(this->numtimesteps-1)){ 313 /*get values for the last time: */ 314 _assert_(end_time>=this->timesteps[offset]); 315 currentinput=(Input*)((Input*)this->inputs->GetObjectByOffset(offset))->copy(); 316 } 317 else{ 318 currentinput=(Input*)((Input*)this->inputs->GetObjectByOffset(offset))->copy(); 319 } 320 switch(averaging){ 321 case 0: //Arithmetic mean 322 if (offset==start_offset){ 323 averageinput=(Input*)currentinput->copy(); 324 averageinput->Scale(subdt); 325 } 326 else{ 327 averageinput->AXPY(currentinput,subdt); 328 } 329 break; 330 case 1: //Geometric mean 331 if (offset==start_offset){ 332 averageinput=(Input*)currentinput->copy(); 333 averageinput->Scale(subdt); 334 } 335 else{ 336 currentinput->Scale(subdt); 337 averageinput->PointwiseMult(currentinput); 338 } 339 break; 340 case 2: //Harmonic mean 341 if (offset==start_offset){ 342 averageinput=(Input*)currentinput->copy(); 343 averageinput->Pow(-1); 344 averageinput->Scale(subdt); 345 } 346 else{ 347 currentinput->Pow(-1); 348 averageinput->AXPY(currentinput,subdt); 349 } 350 break; 351 default: 352 _error_("averaging method is not recognised"); 353 } 354 delete currentinput; 355 offset+=1; 356 } 357 358 //summation is done, now we normalise 359 switch(averaging){ 360 case 0: //Arithmetic mean 361 averageinput->Scale(1.0/slice_duration); 362 break; 363 case 1: //Geometric mean 364 averageinput->Pow(1.0/slice_duration); 365 break; 366 case 2: //Harmonic mean 367 averageinput->Scale(1.0/slice_duration); 368 averageinput->Pow(-1.0); 369 break; 370 default: 371 _error_("averaging method is not recognised"); 372 } 373 return averageinput; 374 } 375 /*}}}*/ 376 void TransientInput::GetInputAveragesOnAllTime(IssmDouble** pvalues,IssmDouble** ptimes, int* pnumtimes){/*{{{*/ 177 377 178 378 int i; … … 195 395 } 196 396 /*}}}*/ 197 void TransientInput::GetInputAverage(IssmDouble* pvalue){/*{{{*/ 198 199 IssmDouble time; 200 201 /*First, recover current time from parameters: */ 202 parameters->FindParam(&time,TimeEnum); 203 204 /*Retrieve interpolated values for this time step: */ 205 Input* input=GetTimeInput(time); 206 207 /*Call input function*/ 208 input->GetInputAverage(pvalue); 209 210 delete input; 211 212 } 213 /*}}}*/ 214 void TransientInput::GetInputDerivativeValue(IssmDouble* p, IssmDouble* xyz_list, Gauss* gauss){/*{{{*/ 215 216 IssmDouble time; 217 218 /*First, recover current time from parameters: */ 219 parameters->FindParam(&time,TimeEnum); 220 221 /*Retrieve interpolated values for this time step: */ 222 Input* input=GetTimeInput(time); 223 224 /*Call input function*/ 225 input->GetInputDerivativeValue(p,xyz_list,gauss); 226 227 delete input; 228 } 229 /*}}}*/ 230 void TransientInput::GetInputValue(IssmDouble* pvalue,Gauss* gauss){/*{{{*/ 231 IssmDouble time; 232 233 /*First, recover current time from parameters: */ 234 parameters->FindParam(&time,TimeEnum); 235 236 /*Retrieve interpolated values for this time step: */ 237 Input* input=GetTimeInput(time); 238 239 /*Call input function*/ 240 input->GetInputValue(pvalue,gauss); 241 242 delete input; 243 } 244 /*}}}*/ 245 void TransientInput::GetInputValue(IssmDouble* pvalue,Gauss* gauss,IssmDouble time){/*{{{*/ 246 247 /*Retrieve interpolated values for this time step: */ 248 Input* input=GetTimeInput(time); 249 250 /*Call input function*/ 251 input->GetInputValue(pvalue,gauss); 252 253 delete input; 254 } 255 /*}}}*/ 256 int TransientInput::GetTimeInputOffset(IssmDouble time){/*{{{*/ 257 258 int found; 259 int offset; 260 261 /*go through the timesteps, and figure out which interval we 262 * *fall within. Then interpolate the values on this interval: */ 263 found=binary_search(&offset,time,this->timesteps,this->numtimesteps); 264 if(!found) _error_("Input not found (is TransientInput sorted ?)"); 265 266 return offset; 267 } 268 /*}}}*/ 269 IssmDouble TransientInput::GetTimeByOffset(int offset){/*{{{*/ 270 if (offset < 0) offset=0; 271 _assert_(offset<(this->numtimesteps)); 272 return this->timesteps[offset]; 273 } 274 /*}}}*/ 275 void TransientInput::GetInputUpToCurrentTimeAverages(IssmDouble** pvalues, IssmDouble** ptimes, int* pnumtimes, IssmDouble currenttime){/*{{{*/ 397 void TransientInput::GetInputAveragesUpToCurrentTime(IssmDouble** pvalues, IssmDouble** ptimes, int* pnumtimes, IssmDouble currenttime){/*{{{*/ 276 398 277 399 int i; … … 313 435 } 314 436 /*}}}*/ 315 void TransientInput::GetInputAverageOnTimes(IssmDouble** pvalues, IssmDouble init_time){/*{{{*/ 316 317 int numnodes; 318 IssmDouble subtimestep; 319 IssmDouble* values= NULL; 320 Input* input=NULL; 321 322 /*Initialize numnode from transientinput out of time loop*/ 323 for(int i=0;i<this->numtimesteps;i++){ 324 /*First compute the lengt of the sub-timestep*/ 325 if(i==0){ 326 subtimestep = this->timesteps[i]-init_time; 327 } 328 else{ 329 subtimestep = this->timesteps[i]-this->timesteps[i-1]; 330 } 331 /*Figure out type of input and get it*/ 332 input = xDynamicCast<Input*>(this->inputs->GetObjectByOffset(i)); _assert_(input); 333 switch(input->ObjectEnum()){ 334 case TriaInputEnum:{ 335 TriaInput* triainput = (TriaInput*)this->inputs->GetObjectByOffset(i); _assert_(triainput); 336 if(i==0){ 337 numnodes= triainput->NumberofNodes(triainput->interpolation_type); 338 values=xNewZeroInit<IssmDouble>(numnodes); 339 } 340 /*Sum the values weighted by their respective sub-timestep*/ 341 for(int j=0;j<numnodes;j++){ 342 values[j]+=(triainput->values[j]*subtimestep); 343 } 344 break; 345 } 346 case PentaInputEnum:{ 347 PentaInput* pentainput = (PentaInput*)this->inputs->GetObjectByOffset(i); _assert_(pentainput); 348 if(i==0){ 349 numnodes= pentainput->NumberofNodes(pentainput->interpolation_type); 350 values=xNewZeroInit<IssmDouble>(numnodes); 351 } 352 /*Sum the values weighted by their respective sub-timestep*/ 353 for(int j=0;j<numnodes;j++){ 354 values[j]+=(pentainput->values[j]*subtimestep); 355 } 356 break; 357 } 358 case TetraInputEnum:{ 359 TetraInput* tetrainput = (TetraInput*)this->inputs->GetObjectByOffset(i); _assert_(tetrainput); 360 if(i==0){ 361 numnodes= tetrainput->NumberofNodes(tetrainput->interpolation_type); 362 values=xNewZeroInit<IssmDouble>(numnodes); 363 } 364 /*Sum the values weighted by their respective sub-timestep*/ 365 for(int j=0;j<numnodes;j++){ 366 values[j]+=(tetrainput->values[j]*subtimestep); 367 } 368 break; 369 } 370 default: _error_("not implemented yet"); 371 } 372 } 373 /*Compute the average based on the length of the full timestep*/ 374 for(int j=0;j<numnodes;j++){ 375 values[j]=values[j]/(this->timesteps[this->numtimesteps-1]-init_time); 376 } 377 *pvalues=values; 378 } 379 /*}}}*/ 380 437 void TransientInput::GetInputDerivativeValue(IssmDouble* p, IssmDouble* xyz_list, Gauss* gauss){/*{{{*/ 438 439 IssmDouble time; 440 441 /*First, recover current time from parameters: */ 442 parameters->FindParam(&time,TimeEnum); 443 444 /*Retrieve interpolated values for this time step: */ 445 Input* input=GetTimeInput(time); 446 447 /*Call input function*/ 448 input->GetInputDerivativeValue(p,xyz_list,gauss); 449 450 delete input; 451 } 452 /*}}}*/ 453 void TransientInput::GetInputValue(IssmDouble* pvalue,Gauss* gauss){/*{{{*/ 454 IssmDouble time; 455 456 /*First, recover current time from parameters: */ 457 parameters->FindParam(&time,TimeEnum); 458 459 /*Retrieve interpolated values for this time step: */ 460 Input* input=GetTimeInput(time); 461 462 /*Call input function*/ 463 input->GetInputValue(pvalue,gauss); 464 465 delete input; 466 } 467 /*}}}*/ 468 void TransientInput::GetInputValue(IssmDouble* pvalue,Gauss* gauss,IssmDouble time){/*{{{*/ 469 470 /*Retrieve interpolated values for this time step: */ 471 Input* input=GetTimeInput(time); 472 473 /*Call input function*/ 474 input->GetInputValue(pvalue,gauss); 475 476 delete input; 477 } 478 /*}}}*/ 479 IssmDouble TransientInput::GetTimeByOffset(int offset){/*{{{*/ 480 if (offset < 0) offset=0; 481 _assert_(offset<(this->numtimesteps)); 482 return this->timesteps[offset]; 483 } 484 /*}}}*/ 485 int TransientInput::GetTimeInputOffset(IssmDouble time){/*{{{*/ 486 487 int offset; 488 489 /*go through the timesteps, and figure out which interval we 490 * *fall within. Then interpolate the values on this interval: */ 491 int found=binary_search(&offset,time,this->timesteps,this->numtimesteps); 492 if(!found) _error_("Input not found (is TransientInput sorted ?)"); 493 494 return offset; 495 } 496 /*}}}*/ 381 497 /*Intermediary*/ 382 void TransientInput::AddTimeInput(Input* input,IssmDouble time){/*{{{*/383 384 /*insert values at time step: */385 if (this->numtimesteps>0 && time<=this->timesteps[this->numtimesteps-1]) _error_("timestep values must increase sequentially");386 387 //copy timesteps, add the new time, delete previous timesteps, and add the new input: inputs->AddObject(input);388 IssmDouble* old_timesteps=NULL;389 390 if (this->numtimesteps > 0){391 old_timesteps=xNew<IssmDouble>(this->numtimesteps);392 xMemCpy(old_timesteps,this->timesteps,this->numtimesteps);393 xDelete(this->timesteps);394 }395 396 this->numtimesteps=this->numtimesteps+1;397 this->timesteps=xNew<IssmDouble>(this->numtimesteps);398 399 if (this->numtimesteps > 1){400 xMemCpy(this->timesteps,old_timesteps,this->numtimesteps-1);401 xDelete(old_timesteps);402 }403 404 /*go ahead and plug: */405 this->timesteps[this->numtimesteps-1]=time;406 inputs->AddObject(input);407 408 }409 /*}}}*/410 void TransientInput::AddTimeInput(Input* input){/*{{{*/411 412 _assert_(this->inputs->Size()<this->numtimesteps);413 inputs->AddObject(input);414 415 }416 /*}}}*/417 void TransientInput::Configure(Parameters* parameters){/*{{{*/418 this->parameters=parameters;419 }420 /*}}}*/421 498 void TransientInput::Extrude(int start){/*{{{*/ 422 499 … … 424 501 ((Input*)this->inputs->GetObjectByOffset(i))->Extrude(start); 425 502 } 426 }427 /*}}}*/428 int TransientInput::GetResultArraySize(void){/*{{{*/429 430 return 1;431 }432 /*}}}*/433 int TransientInput::GetResultInterpolation(void){/*{{{*/434 435 IssmDouble time;436 int output;437 438 parameters->FindParam(&time,TimeEnum);439 Input* input=GetTimeInput(time);440 output = input->GetResultInterpolation();441 442 /*Clean up and return*/443 delete input;444 return output;445 446 }447 /*}}}*/448 int TransientInput::GetResultNumberOfNodes(void){/*{{{*/449 450 IssmDouble time;451 int output;452 453 parameters->FindParam(&time,TimeEnum);454 Input* input=GetTimeInput(time);455 output = input->GetResultNumberOfNodes();456 457 /*Clean up and return*/458 delete input;459 return output;460 461 503 } 462 504 /*}}}*/ … … 476 518 Input *input2 = NULL; 477 519 478 /*go through the timesteps, and figure out which interval we 520 /*go through the timesteps, and figure out which interval we 479 521 *fall within. Then interpolate the values on this interval: */ 480 522 found=binary_search(&offset,intime,this->timesteps,this->numtimesteps); … … 498 540 alpha1=(1.0-alpha2); 499 541 500 input1=(Input*)this->inputs->GetObjectByOffset(offset); 542 input1=(Input*)this->inputs->GetObjectByOffset(offset); 501 543 input2=(Input*)this->inputs->GetObjectByOffset(offset+1); 502 544
Note:
See TracChangeset
for help on using the changeset viewer.