Ignore:
Timestamp:
11/01/19 12:01:57 (5 years ago)
Author:
Mathieu Morlighem
Message:

merged trunk-jpl and trunk for revision 24310

Location:
issm/trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk

  • issm/trunk/src

  • issm/trunk/src/c

    • Property svn:ignore
      •  

        old new  
        55*.obj
        66*.exe
         7*.mod
        78appscan.*
        89ouncemake*
         
        1415probe.results
        1516stXXXX*
        16 *.deps
        17 *.dirstamp
         17.deps
         18.dirstamp
        1819.libs
        1920issm
         
        2122issm_slr
        2223issm_ocean
        23 lnb_param.mod
        24 lovenb_sub.mod
        25 model.mod
        26 util.mod
         24issm_dakota
  • issm/trunk/src/c/classes/Inputs/TransientInput.cpp

    r22758 r24313  
    6060}
    6161/*}}}*/
     62void 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/*}}}*/
     90void TransientInput::AddTimeInput(Input* input){/*{{{*/
     91
     92        _assert_(this->inputs->Size()<this->numtimesteps);
     93        inputs->AddObject(input);
     94
     95}
     96/*}}}*/
    6297
    6398/*Object virtual functions definitions:*/
     
    87122        _printf_("   enum: " << this->enum_type << " (" << EnumToStringx(this->enum_type) << ")\n");
    88123        _printf_("   numtimesteps: " << this->numtimesteps << "\n");
    89         _printf_("---inputs: \n"); 
     124        _printf_("---inputs: \n");
    90125        for(i=0;i<this->numtimesteps;i++){
    91126                _printf_("   time: " << this->timesteps[i]<<"  ");
     
    120155
    121156/*TransientInput management*/
     157void TransientInput::Configure(Parameters* parameters){/*{{{*/
     158        this->parameters=parameters;
     159}
     160/*}}}*/
     161int  TransientInput::GetResultArraySize(void){/*{{{*/
     162
     163        return 1;
     164}
     165/*}}}*/
     166int  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/*}}}*/
     181int  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/*}}}*/
    122196int TransientInput::InstanceEnum(void){/*{{{*/
    123197
     
    174248}
    175249/*}}}*/
    176 void TransientInput::GetInputAllTimeAverages(IssmDouble** pvalues,IssmDouble** ptimes, int* pnumtimes){/*{{{*/
     250void 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/*}}}*/
     267void 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/*}}}*/
     280Input* 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/*}}}*/
     376void TransientInput::GetInputAveragesOnAllTime(IssmDouble** pvalues,IssmDouble** ptimes, int* pnumtimes){/*{{{*/
    177377
    178378        int i;
     
    195395}
    196396/*}}}*/
    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){/*{{{*/
     397void TransientInput::GetInputAveragesUpToCurrentTime(IssmDouble** pvalues, IssmDouble** ptimes, int* pnumtimes, IssmDouble currenttime){/*{{{*/
    276398
    277399        int         i;
     
    313435}
    314436/*}}}*/
    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 
     437void 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/*}}}*/
     453void 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/*}}}*/
     468void 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/*}}}*/
     479IssmDouble  TransientInput::GetTimeByOffset(int offset){/*{{{*/
     480        if (offset < 0) offset=0;
     481        _assert_(offset<(this->numtimesteps));
     482        return this->timesteps[offset];
     483}
     484/*}}}*/
     485int  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/*}}}*/
    381497/*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 /*}}}*/
    421498void TransientInput::Extrude(int start){/*{{{*/
    422499
     
    424501                ((Input*)this->inputs->GetObjectByOffset(i))->Extrude(start);
    425502        }
    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 
    461503}
    462504/*}}}*/
     
    476518        Input *input2 = NULL;
    477519
    478         /*go through the timesteps, and figure out which interval we 
     520        /*go through the timesteps, and figure out which interval we
    479521         *fall within. Then interpolate the values on this interval: */
    480522        found=binary_search(&offset,intime,this->timesteps,this->numtimesteps);
     
    498540                alpha1=(1.0-alpha2);
    499541
    500                 input1=(Input*)this->inputs->GetObjectByOffset(offset); 
     542                input1=(Input*)this->inputs->GetObjectByOffset(offset);
    501543                input2=(Input*)this->inputs->GetObjectByOffset(offset+1);
    502544
Note: See TracChangeset for help on using the changeset viewer.