Ignore:
Timestamp:
12/08/20 08:45:53 (4 years ago)
Author:
Mathieu Morlighem
Message:

merged trunk-jpl and trunk for revision 25834

Location:
issm/trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk

  • issm/trunk/src

  • issm/trunk/src/c

    • Property svn:ignore
      •  

        old new  
        2323issm_ocean
        2424issm_dakota
         25issm_post
  • issm/trunk/src/c/modules/InputUpdateFromDakotax/InputUpdateFromDakotax.cpp

    r24313 r25836  
    66#include "../../shared/shared.h"
    77#include "../../toolkits/toolkits.h"
     8#include "../../classes/Inputs/TransientInput.h"
     9#include "../../classes/Inputs/DatasetInput.h"
     10#include "../../classes/Inputs/TriaInput.h"
    811#include "../InputUpdateFromMatrixDakotax/InputUpdateFromMatrixDakotax.h"
    912#include "../InputUpdateFromConstantx/InputUpdateFromConstantx.h"
    1013#include "../InputUpdateFromVectorDakotax/InputUpdateFromVectorDakotax.h"
    1114
    12 void InputUpdateFromDakotax(FemModel* femmodel,double* variables,char* *variables_descriptors,int numvariables){
     15void  InputUpdateFromDakotax(FemModel* femmodel,double* variables,char* *variables_descriptors,int numdakotavariables){ /*{{{*/
    1316
    1417        int     i,j,k,l;
    15         int     dummy;
    16 
    17         int     numberofvertices;
    18         int     numberofelements;
    19         int     nrows;
    20         int     ncols;
    21         int     npart;
    22         double *qmu_vpart  = NULL;
    23         double *qmu_epart  = NULL;
     18
     19        IssmDouble **variable_partitions         = NULL;
     20        IssmDouble * variable_partition         = NULL;
     21        int * variable_partitions_npart         = NULL;
     22        int * variable_partitions_nt         = NULL;
     23        int          variable_partitions_num;
     24        int          npart;
     25        int          nt;
     26        int variablecount=0;
    2427
    2528        double *distributed_values = NULL;
     
    2831        char    root[50]; //root name of variable, ex: DragCoefficent, RhoIce, etc ...
    2932
     33        if (VerboseQmu())_printf0_("dakota variables updates\n");
     34
    3035        /*retrieve parameters: */
    31         femmodel->parameters->FindParam(&npart,QmuNumberofpartitionsEnum);
    32         femmodel->parameters->FindParam(&qmu_vpart,NULL,QmuVpartitionEnum);
    33         femmodel->parameters->FindParam(&qmu_epart,NULL,QmuEpartitionEnum);
    34         numberofvertices=femmodel->vertices->NumberOfVertices();
    35         numberofelements=femmodel->elements->NumberOfElements();
    36 
    37         /*Go through all dakota descriptors, ex: "rho_ice","thermal_conductivity","thickness1","thickness2", etc ..., and
    38          * for each descriptor, take the variable value and plug it into the inputs: */
    39 
    40         for(i=0;i<numvariables;i++){
     36        femmodel->parameters->FindParam(&variable_partitions,&variable_partitions_num,NULL,NULL,QmuVariablePartitionsEnum);
     37        femmodel->parameters->FindParam(&variable_partitions_npart,NULL,NULL,QmuVariablePartitionsNpartEnum);
     38        femmodel->parameters->FindParam(&variable_partitions_nt,NULL,NULL,QmuVariablePartitionsNtEnum);
     39
     40
     41        /*Go through all dakota descriptors, ex: "rho_ice","thermal_conductivity","thickness1","thickness2", etc ..., and
     42         * for each descriptor, take the variable value and plug it into the inputs (more or less :)):
     43         * We also start with distributed and standard values , as they tend to be used to pluck data from a multi-modle ensemble (mme)
     44         * which can then be scaled. Doing the scaling first would be impractical, as the entire mme would have to be scaled,
     45         * which is a waste of time:*/
     46
     47        variablecount=0;
     48        for(i=0;i<numdakotavariables;i++){ //these are the dakota variables, for all partitions.
    4149
    4250                descriptor=variables_descriptors[i];
    4351
    44                 /*From descriptor, figure out if the variable is scaled, indexed, nodal, or just a simple variable: */
     52
     53                /*From descriptor, figure out if the variable is scaled, indexed, distributed or just a simple variable: */
    4554                if (strncmp(descriptor,"scaled_",7)==0){
    46 
    47                         /*Variable is scaled. Determine root name of variable (ex: scaled_DragCoefficient_1 -> DragCoefficient). Allocate distributed_values and fill the
    48                          * distributed_values with the next npart variables: */
    49 
    50                         //strcpy(root,strstr(descriptor,"_")+1); *strstr(root,"_")='\0';
     55                        /*we are skipping these for now.*/
     56                        npart=variable_partitions_npart[variablecount];
     57                        nt=variable_partitions_nt[variablecount];
     58
     59                        /*increment i to skip the distributed values just collected: */
     60                        i+=npart*nt-1; //careful, the for loop will add 1.
     61                }
     62                else if (strncmp(descriptor,"indexed_",8)==0){
     63                        /*we are skipping these for now.*/
     64                }
     65                else if (strncmp(descriptor,"nodal_",8)==0){
     66                        /*we are skipping these for now.*/
     67                }
     68
     69                else if (strncmp(descriptor,"distributed_",12)==0){
     70                        if (VerboseQmu())_printf0_("   updating variable " << descriptor << "\n");
     71
     72                        /*recover partition vector: */
     73                        variable_partition=variable_partitions[variablecount];
     74                        npart=variable_partitions_npart[variablecount];
     75
     76                        /*Variable is distributed. Determine root name of variable (ex: distributed_DragCoefficient_1 -> DragCoefficient).
     77                         * Allocate distributed_values and fill the distributed_values with the next npart variables: */
     78
    5179                        memcpy(root,strstr(descriptor,"_")+1,(strlen(strstr(descriptor,"_")+1)+1)*sizeof(char));
    5280                        *strstr(root,"_")='\0';
     
    5785                        }
    5886
    59                         /*Now, pick up the parameter corresponding to root: */
    60                         femmodel->parameters->FindParamInDataset(&parameter,&nrows,&ncols,QmuVariableDescriptorsEnum,StringToEnumx(root));
    61 
    62 
    63                         /*We've got the parameter, we need to update it using qmu_vpart or qmu_epart (depending on whether
    64                          * it is element or vertex distributed), and the distributed_values.
    65                          In addition, the parameter can be either a static or transient (nrows+1) vector. */
    66                        
    67                         //_printf_("nrows: " << nrows << " numberofvertices: " << numberofvertices << " numberofelements: " << numberofelements << "\n");
    68 
    69                         if (nrows==numberofvertices || nrows==(numberofvertices+1)){
    70                                 for(k=0;k<numberofvertices;k++){
    71                                         for(l=0;l<ncols;l++){
    72                                                 *(parameter+ncols*k+l)=*(parameter+ncols*k+l)*distributed_values[(int)qmu_vpart[k]];
    73                                         }
    74                                 }
    75                         }
    76                         else if (nrows==numberofelements || nrows==(numberofelements+1)){
    77                                 for(k=0;k<numberofelements;k++){
    78                                         for(l=0;l<ncols;l++){
    79                                                 *(parameter+ncols*k+l)=*(parameter+ncols*k+l)*distributed_values[(int)qmu_epart[k]];
    80                                         }
    81                                 }
    82 
    83                         }
    84                         else _error_("partitioning vector should be either elements or vertex sized!");
    85 
    86                         #ifdef _DEBUG_
    87                                 PetscSynchronizedPrintf(IssmComm::GetComm(),"Parameter matrix:");
    88                                 PetscSynchronizedFlush(IssmComm::GetComm());
    89                                 for(l=0;l<ncols;l++){
    90                                         PetscSynchronizedPrintf(IssmComm::GetComm()," time %i\n",l);
    91                                         PetscSynchronizedFlush(IssmComm::GetComm());
    92 
    93                                         for(k=0;k<numberofvertices;k++){
    94                                                 PetscSynchronizedPrintf(IssmComm::GetComm()," node %i value %g\n",k+1,*(parameter+k*ncols+l));
    95                                                 PetscSynchronizedFlush(IssmComm::GetComm());
    96                                         }
    97                                 }
    98                                 PetscSynchronizedPrintf(IssmComm::GetComm()," descriptor: %s root %s enum: %i\n",descriptor,root,StringToEnumx(root));
    99                                 PetscSynchronizedFlush(IssmComm::GetComm());
    100                         #endif
    101 
    102                         /*Update inputs using the parameter matrix: */
    103                         if(nrows==numberofvertices || (nrows==numberofvertices+1))
    104                                 InputUpdateFromMatrixDakotax(femmodel, parameter, nrows,ncols,StringToEnumx(root), VertexEnum);
    105                         else
    106                                 InputUpdateFromMatrixDakotax(femmodel, parameter, nrows,ncols,StringToEnumx(root), ElementEnum);
     87                        //for (int j=0;j<npart;j++)_printf_(j << ":" << distributed_values[j] << "\n");
     88
     89                        //Call specialty code:
     90                        InputUpdateSpecialtyCode(femmodel,distributed_values,variable_partition,npart,root);
    10791
    10892                        /*increment i to skip the distributed values just collected: */
     
    11397                        xDelete<double>(distributed_values);
    11498                }
    115                 else if (strncmp(descriptor,"indexed_",8)==0){
    116                         _error_("indexed variables not supported yet!");
    117                 }
    118                 else if (strncmp(descriptor,"nodal_",8)==0){
    119                         _error_("nodal variables not supported yet!");
    120                 }
    12199                else{
    122100                        /*Ok, standard variable, just update inputs using the variable: */
     101                        if (VerboseQmu())_printf0_("   updating variable " << descriptor << "\n");
    123102                        InputUpdateFromConstantx(femmodel,variables[i],StringToEnumx(descriptor));
    124103                }
    125         }
     104                variablecount++;
     105        }
     106
     107        variablecount=0;
     108        /*now deal with scaled variabes:*/
     109        for(i=0;i<numdakotavariables;i++){ //these are the dakota variables, for all partitions.
     110
     111                descriptor=variables_descriptors[i];
     112
     113                /*From descriptor, figure out if the variable is scaled, indexed, distributed or just a simple variable: */
     114                if (strncmp(descriptor,"scaled_",7)==0){
     115
     116                        if (VerboseQmu())_printf0_("   updating variable " << descriptor << "\n");
     117
     118                        /*recover partition vector: */
     119                        variable_partition=variable_partitions[variablecount];
     120                        npart=variable_partitions_npart[variablecount];
     121                        nt=variable_partitions_nt[variablecount];
     122
     123                        /* Variable is scaled, determine its root name (ex: scaled_DragCoefficient_1 -> DragCoefficient). Allocate distributed_values and fill the
     124                         * distributed_values with the next npart variables coming from Dakota: */
     125                        memcpy(root,strstr(descriptor,"_")+1,(strlen(strstr(descriptor,"_")+1)+1)*sizeof(char));
     126                        *strstr(root,"_")='\0';
     127
     128                        distributed_values=xNew<double>(npart*nt);
     129                        for(j=0;j<npart*nt;j++){
     130                                distributed_values[j]=variables[i+j];
     131                        }
     132
     133                        /*Scale variable inside the inputs:*/
     134                        InputScaleFromDakotax(femmodel, distributed_values, variable_partition,npart, nt, StringToEnumx(root));
     135
     136                        /*increment i to skip the distributed values just collected: */
     137                        i+=npart*nt-1; //careful, the for loop will add 1.
     138
     139                        /*Free allocations: */
     140                        xDelete<double>(parameter);
     141                        xDelete<double>(distributed_values);
     142                }
     143                variablecount++;
     144        }
     145
     146        /*Save results:*/
     147        femmodel->results->AddResult(new GenericExternalResult<IssmPDouble*>(femmodel->results->Size()+1,"uq_variables",variables,numdakotavariables,1,1,0));
    126148
    127149        /*Free ressources:*/
    128         xDelete<double>(qmu_vpart);
    129         xDelete<double>(qmu_epart);
    130 }
     150        for(i=0;i<variable_partitions_num;i++){
     151                IssmDouble* matrix=variable_partitions[i];
     152                xDelete<IssmDouble>(matrix);
     153        }
     154        xDelete<IssmDouble*>(variable_partitions);
     155        xDelete<int>(variable_partitions_npart);
     156        xDelete<int>(variable_partitions_nt);
     157
     158} /*}}}*/
     159void  InputUpdateSpecialtyCode(FemModel* femmodel,IssmDouble* distributed_values,IssmDouble* variable_partition,int npart,char* root){ //{{{
     160
     161        /*Here, we put all the code that cannot be handled any other place: */
     162        if (strncmp(root,"SurfaceloadModelid",18)==0){
     163
     164                if(VerboseQmu()){
     165                        _printf0_("      SurfaceloadModelid MME, with ids: ");
     166                        for (int i=0;i<npart;i++)_printf0_((int)distributed_values[i] << " ");
     167                        _printf0_("\n");
     168                }
     169
     170
     171                if (femmodel->inputs->GetInputObjectEnum(SurfaceloadIceThicknessChangeEnum)==DatasetInputEnum)
     172                        MmeToInput(femmodel,distributed_values,variable_partition,npart,SurfaceloadIceThicknessChangeEnum, P0Enum);
     173
     174                if (femmodel->inputs->GetInputObjectEnum(MaskIceLevelsetEnum)==DatasetInputEnum)
     175                        MmeToInput(femmodel,distributed_values,variable_partition,npart,MaskIceLevelsetEnum, P1Enum);
     176
     177                if (femmodel->inputs->GetInputObjectEnum(MaskOceanLevelsetEnum)==DatasetInputEnum)
     178                        MmeToInput(femmodel,distributed_values,variable_partition,npart,MaskOceanLevelsetEnum, P1Enum);
     179
     180        }
     181        else _error_("InputUpdateSpecialtyCode error message: " << root << " not supported yet!");
     182
     183}       //}}}
     184void  MmeToInput(FemModel* femmodel,IssmDouble* distributed_values,IssmDouble* variable_partition,int npart,int rootenum, int interpolationenum){ /*{{{*/
     185
     186        TransientInput* transientinput  = NULL;
     187        TransientInput* transientinput2 = NULL;
     188        Tria* element                    = NULL;
     189        IssmDouble value;
     190        IssmDouble* values               = NULL;
     191        IssmDouble* times                = NULL;
     192        int N;
     193        int id;
     194
     195        /*find thickness dataset: */
     196        DatasetInput* datasetinput = femmodel->inputs->GetDatasetInput(rootenum);
     197
     198        /*Initialize new transient input: */
     199        transientinput = datasetinput->GetTransientInputByOffset(0); _assert_(transientinput);
     200        transientinput->GetAllTimes(&times,&N);
     201        femmodel->inputs->SetTransientInput(DummyEnum,times,N);
     202        transientinput2 = femmodel->inputs->GetTransientInput(DummyEnum);
     203
     204        for(Object* & object : femmodel->elements->objects){
     205                Tria*   element=xDynamicCast<Tria*>(object);
     206
     207                if((int)variable_partition[element->Sid()]==-1)id=0; //grab background field
     208                else id=distributed_values[(int)variable_partition[element->Sid()]]-1; //grab partition field
     209
     210                /*recover the right field from the mme: */
     211                transientinput = datasetinput->GetTransientInputByOffset(id); _assert_(transientinput);
     212
     213                /*copy values from the transientinput to the final transientinput2: */
     214                for (int j=0;j<N;j++){
     215                        TriaInput* tria_input=transientinput->GetTriaInput(j);
     216                        element->InputServe(tria_input);
     217                        if(interpolationenum==P0Enum){
     218                                value=tria_input->element_values[0];
     219                                transientinput2->AddTriaTimeInput( j,1,&(element->lid),&value,P0Enum);
     220                        }
     221                        else if(interpolationenum==P1Enum){
     222
     223                                /*Get values and lid list*/
     224                                const int   numvertices     = element->GetNumberOfVertices();
     225                                int        *vertexlids      = xNew<int>(numvertices);
     226                                int        *vertexsids      = xNew<int>(numvertices);
     227
     228                                /*Recover vertices ids needed to initialize inputs*/
     229                                element->GetVerticesLidList(&vertexlids[0]);
     230                                element->GetVerticesSidList(&vertexsids[0]);
     231                                values=tria_input->element_values;
     232                                transientinput2->AddTriaTimeInput( j,numvertices,vertexlids,values,P1Enum);
     233                        }
     234                }
     235        }
     236
     237        /*wipe out existing SurfaceloadIceThicknessChangeEnum dataset:*/
     238        femmodel->inputs->ChangeEnum(DummyEnum,rootenum);
     239
     240        //reconfigure:
     241        transientinput2->Configure(femmodel->parameters);
     242}       //}}}
     243void  InputScaleFromDakotax(FemModel* femmodel,IssmDouble* distributed_values,IssmDouble* partition, int npart, int nt, int name){ /*{{{*/
     244
     245        /*Copy input:*/
     246        femmodel->inputs->DuplicateInput(name,DummyEnum);
     247
     248        /*Go through elements, copy input name to dummy, and scale it using the distributed_values and the partition vector:*/
     249        for(Object* & object : femmodel->elements->objects){
     250                Element* element=xDynamicCast<Element*>(object);
     251                element->InputScaleFromDakota(distributed_values,partition,npart,nt,name);
     252        }
     253
     254        /*We created a dummy input, which was a scaled copy of the name input. Now wipe
     255         * out the name input with the new input:*/
     256        femmodel->inputs->ChangeEnum(DummyEnum,name);
     257
     258        /*Some specialty code:*/
     259        switch(name){
     260                case MaterialsRheologyBEnum:
     261                        femmodel->inputs->DuplicateInput(name,MaterialsRheologyBbarEnum);
     262                        break;
     263        }
     264
     265
     266} /*}}}*/
Note: See TracChangeset for help on using the changeset viewer.