- Timestamp:
- 12/08/20 08:45:53 (4 years ago)
- Location:
- issm/trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk
- Property svn:mergeinfo changed
-
issm/trunk/src
- Property svn:mergeinfo changed
-
issm/trunk/src/c
- Property svn:ignore
-
old new 23 23 issm_ocean 24 24 issm_dakota 25 issm_post
-
- Property svn:ignore
-
issm/trunk/src/c/modules/InputUpdateFromDakotax/InputUpdateFromDakotax.cpp
r24313 r25836 6 6 #include "../../shared/shared.h" 7 7 #include "../../toolkits/toolkits.h" 8 #include "../../classes/Inputs/TransientInput.h" 9 #include "../../classes/Inputs/DatasetInput.h" 10 #include "../../classes/Inputs/TriaInput.h" 8 11 #include "../InputUpdateFromMatrixDakotax/InputUpdateFromMatrixDakotax.h" 9 12 #include "../InputUpdateFromConstantx/InputUpdateFromConstantx.h" 10 13 #include "../InputUpdateFromVectorDakotax/InputUpdateFromVectorDakotax.h" 11 14 12 void InputUpdateFromDakotax(FemModel* femmodel,double* variables,char* *variables_descriptors,int numvariables){15 void InputUpdateFromDakotax(FemModel* femmodel,double* variables,char* *variables_descriptors,int numdakotavariables){ /*{{{*/ 13 16 14 17 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; 24 27 25 28 double *distributed_values = NULL; … … 28 31 char root[50]; //root name of variable, ex: DragCoefficent, RhoIce, etc ... 29 32 33 if (VerboseQmu())_printf0_("dakota variables updates\n"); 34 30 35 /*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. 41 49 42 50 descriptor=variables_descriptors[i]; 43 51 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: */ 45 54 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 51 79 memcpy(root,strstr(descriptor,"_")+1,(strlen(strstr(descriptor,"_")+1)+1)*sizeof(char)); 52 80 *strstr(root,"_")='\0'; … … 57 85 } 58 86 59 /*Now, pick up the parameter corresponding to root: */ 60 femmodel->parameters->FindParamInDataset(¶meter,&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); 107 91 108 92 /*increment i to skip the distributed values just collected: */ … … 113 97 xDelete<double>(distributed_values); 114 98 } 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 }121 99 else{ 122 100 /*Ok, standard variable, just update inputs using the variable: */ 101 if (VerboseQmu())_printf0_(" updating variable " << descriptor << "\n"); 123 102 InputUpdateFromConstantx(femmodel,variables[i],StringToEnumx(descriptor)); 124 103 } 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)); 126 148 127 149 /*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 } /*}}}*/ 159 void 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 } //}}} 184 void 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(×,&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 } //}}} 243 void 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.