Ice Sheet System Model  4.18
Code documentation
FemModel.cpp
Go to the documentation of this file.
1 
5 #ifdef HAVE_CONFIG_H
6  #include <config.h>
7 #else
8 #error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
9 #endif
10 
11 #include <stdio.h>
12 #include <math.h>
13 #include "../cores/cores.h"
14 #include "../shared/io/io.h"
15 #include "./classes.h"
16 #include "./modules/modules.h"
17 #include "../shared/Enum/Enum.h"
18 #include "../analyses/analyses.h"
22 
23 #if _HAVE_CODIPACK_
24 #include <sstream> // for output of the CoDiPack tape
25 extern CoDi_global codi_global;
26 #endif
27 
28 #if defined(_HAVE_NEOPZ_) && !defined(_HAVE_AD_)
29 #include <TPZRefPatternDataBase.h>
30 #endif
31 
32 /*module includes: {{{*/
33 #include "../modules/ModelProcessorx/ModelProcessorx.h"
34 #include "../modules/SpcNodesx/SpcNodesx.h"
35 #include "../modules/ConfigureObjectsx/ConfigureObjectsx.h"
36 #include "../modules/ParseToolkitsOptionsx/ParseToolkitsOptionsx.h"
37 #include "../modules/GetVectorFromInputsx/GetVectorFromInputsx.h"
38 #include "../modules/InputUpdateFromVectorx/InputUpdateFromVectorx.h"
39 #include "../modules/NodesDofx/NodesDofx.h"
40 #include "../modules/SurfaceAbsVelMisfitx/SurfaceAbsVelMisfitx.h"
41 #include "../modules/SurfaceRelVelMisfitx/SurfaceRelVelMisfitx.h"
42 #include "../modules/SurfaceLogVelMisfitx/SurfaceLogVelMisfitx.h"
43 #include "../modules/SurfaceLogVxVyMisfitx/SurfaceLogVxVyMisfitx.h"
44 #include "../modules/SurfaceAverageVelMisfitx/SurfaceAverageVelMisfitx.h"
45 #include "../modules/ThicknessAbsMisfitx/ThicknessAbsMisfitx.h"
46 #include "../modules/ThicknessAlongGradientx/ThicknessAlongGradientx.h"
47 #include "../modules/ThicknessAcrossGradientx/ThicknessAcrossGradientx.h"
48 #include "../modules/RheologyBbarAbsGradientx/RheologyBbarAbsGradientx.h"
49 #include "../modules/DragCoefficientAbsGradientx/DragCoefficientAbsGradientx.h"
50 #include "../modules/NodalValuex/NodalValuex.h"
51 #include "../modules/GetVectorFromInputsx/GetVectorFromInputsx.h"
52 #include "../modules/AverageOntoPartitionx/AverageOntoPartitionx.h"
53 /*}}}*/
54 
55 /*Object constructors and destructor*/
56 FemModel::FemModel(int argc,char** argv,ISSM_MPI_Comm incomm,bool trace){/*{{{*/
57 
58  /*configuration: */
59  int solution_type,amrtype,amr_frequency;
60  int ierr;
61 
62  /*File names*/
63  char *lockfilename = NULL;
64  char *binfilename = NULL;
65  char *outbinfilename = NULL;
66  char *petscfilename = NULL;
67  char *restartfilename = NULL;
68  char *rootpath = NULL;
69 
70  /*First things first, store the communicator, and set it as a global variable: */
71  IssmComm::SetComm(incomm);
72 
73  /*Now, initialize PETSC: */
74  #ifdef _HAVE_PETSC_
75  PETSC_COMM_WORLD=incomm;
76  ierr=PetscInitialize(&argc,&argv,(char*)0,""); if(ierr) _error_("Could not initialize Petsc");
77  #endif
78 
79  /*Start profiler: */
80  this->profiler=new Profiler();
82 
83  /*From command line arguments, retrieve different filenames needed to create the FemModel: */
84  ProcessArguments(&solution_type,&binfilename,&outbinfilename,&petscfilename,&lockfilename,&restartfilename,&rootpath,argc,argv);
85 
86  /*Create femmodel from input files: */
88  this->InitFromFiles(rootpath,binfilename,outbinfilename,petscfilename,lockfilename,restartfilename, solution_type,trace,NULL);
90 
91  /*Save communicator in the parameters dataset: */
93 
94  /*AMR stuff*/
95  this->parameters->FindParam(&amr_frequency,TransientAmrFrequencyEnum);
96  this->parameters->FindParam(&amr_frequency,TransientAmrFrequencyEnum);
97  #if defined(_HAVE_NEOPZ_) && !defined(_HAVE_AD_)
98  this->amr = NULL;
99  #endif
100  #if defined(_HAVE_BAMG_) && !defined(_HAVE_AD_)
101  this->amrbamg = NULL;
102  #endif
103  #if !defined(_HAVE_AD_)
104  if(amr_frequency && solution_type==TransientSolutionEnum){
105  /*Verifications. AMR supports SSA, P1 and horizontal 2D domain*/
106  bool isSSA;
107  int domaintype,element_type;
108  this->analysis_counter=-1;
110  this->parameters->FindParam(&domaintype,DomainTypeEnum);
111  for(int i=0;i<this->nummodels;i++) if(this->analysis_type_list[i]==StressbalanceAnalysisEnum){analysis_counter=i;break;}
112  if(analysis_counter==-1) _error_("Could not find alias for analysis_type StressbalanceAnalysisEnum in list of FemModel analyses\n");
113  for(int i=0;i<this->elements->Size();i++){
114  Element* element = xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
115  element_type = element->element_type_list[analysis_counter];
116  if(element_type!=P1Enum) _error_("Element type "<<EnumToStringx(element_type)<<" not supported with AMR yet!\n");
117  }
118  if(!isSSA) _error_("Flow equation not supported with AMR yet!\n ");
119  if(domaintype!=Domain2DhorizontalEnum) _error_("Domain "<<EnumToStringx(domaintype)<<" not supported with AMR yet!\n");
120 
121  this->parameters->FindParam(&amrtype,AmrTypeEnum);
122  switch(amrtype){
123 
124  #if defined(_HAVE_NEOPZ_)
125  case AmrNeopzEnum: this->InitializeAdaptiveRefinementNeopz(); break;
126  #endif
127 
128  #if defined(_HAVE_BAMG_)
129  case AmrBamgEnum: this->InitializeAdaptiveRefinementBamg(); break;
130  #endif
131 
132  default: _error_("not implemented yet");
133  }
134  }
135  #endif
136 
137  /*Free resources */
138  xDelete<char>(lockfilename);
139  xDelete<char>(binfilename);
140  xDelete<char>(outbinfilename);
141  xDelete<char>(petscfilename);
142  xDelete<char>(restartfilename);
143  xDelete<char>(rootpath);
144 
145 }
146 /*}}}*/
147 FemModel::FemModel(char* rootpath, char* inputfilename, char* outputfilename, char* toolkitsfilename, char* lockfilename, char* restartfilename, ISSM_MPI_Comm incomm, int solution_type,IssmPDouble* X){ /*{{{*/
148 
149  bool traceon=true;
150  this->profiler=NULL; /*avoid leak, as we are not using the profiler ever in ad control run. */
151 
152  /*Store the communicator, but do not set it as a global variable, as this has already
153  * been done by the FemModel that called this copy constructor: */
154  IssmComm::SetComm(incomm);
155 
156  /*Create femmodel from input files, with trace activated: */
158  this->InitFromFiles(rootpath,inputfilename,outputfilename,toolkitsfilename,lockfilename,restartfilename, solution_type,traceon,X);
160 
161  #if defined(_HAVE_NEOPZ_) && !defined(_HAVE_AD_)
162  this->amr = NULL;
163  #endif
164  #if defined(_HAVE_BAMG_) && !defined(_HAVE_AD_)
165  this->amrbamg = NULL;
166  #endif
167 
168  /*Save communicator in the parameters dataset: */
170 }
171 /*}}}*/
173 
174  /*Intermediary*/
175  FILE *output_fid;
176  char *outbinfilename = NULL;
177  char *lockfilename = NULL;
178 
179  #ifndef _HAVE_JAVASCRIPT_
180  if(this->parameters->Exist(OutputFileNameEnum)) this->parameters->FindParam(&outbinfilename,OutputFileNameEnum);
181  if(this->parameters->Exist(LockFileNameEnum)) this->parameters->FindParam(&lockfilename,LockFileNameEnum);
182  #endif
183 
184  /*Delete all the datasets: */
185  if(analysis_type_list)xDelete<int>(analysis_type_list);
186  if(outbinfilename)xDelete<char>(outbinfilename);
187  if(lockfilename)xDelete<char>(lockfilename);
188  if(elements)delete elements;
189  if(vertices)delete vertices;
190  if(this->constraints_list && this->nummodels){
191  for(int i=0;i<this->nummodels;i++) delete this->constraints_list[i];
192  xDelete<Constraints*>(constraints_list);
193  }
194  if(this->loads_list && this->nummodels){
195  for(int i=0;i<this->nummodels;i++) delete this->loads_list[i];
196  xDelete<Loads*>(loads_list);
197  }
198  if(this->nodes_list && this->nummodels){
199  for(int i=0;i<this->nummodels;i++) delete this->nodes_list[i];
200  xDelete<Nodes*>(nodes_list);
201  }
202  if(materials)delete materials;
203  if(parameters)delete parameters;
204  if(inputs2)delete inputs2;
205  if(results)delete results;
206 
207  #if defined(_HAVE_NEOPZ_) && !defined(_HAVE_AD_)
208  if(amr)delete amr;
209  #endif
210 
211  #if defined(_HAVE_BAMG_) && !defined(_HAVE_AD_)
212  if(amrbamg)delete amrbamg;
213  #endif
214 
215  /*Now delete: */
216  if(profiler)delete profiler;
217 }/*}}}*/
218 
219 /*Object management*/
220 int FemModel::AnalysisIndex(int analysis_enum){/*{{{*/
221 
222  /*Checks in debugging mode*/
224 
225  /*Find analysis in list*/
226  for(int i=0;i<this->nummodels;i++){
227  if(this->analysis_type_list[i]==analysis_enum){
228  return i;
229  break;
230  }
231  }
232 
233  /*If you reach this point, analysis has not been found*/
234  _error_("Could not find index of analysis " << EnumToStringx(analysis_enum) << " in list of FemModel analyses");
235 
236 
237 }/*}}}*/
238 void FemModel::CheckPoint(void){/*{{{*/
239 
240  FILE* restartfid=NULL;
241  char* restartfilename = NULL;
242  int femmodel_size;
243  char* femmodel_buffer=NULL;
244  char* femmodel_buffer_ini=NULL;
245 
246  /*First, recover the name of the restart file: */
247  parameters->FindParam(&restartfilename,RestartFileNameEnum);
248 
249  /*Open file for writing: */
250  restartfid=pfopen(restartfilename,"wb");
251 
252  /*Initialize: */
253  femmodel_size=0;
254 
255  /*Create buffer to hold marshalled femmodel: */
256  this->Marshall(NULL,&femmodel_size,MARSHALLING_SIZE);
257  femmodel_buffer=xNew<char>(femmodel_size);
258  /*Keep track of initial position of femmodel_buffer: */
259  femmodel_buffer_ini=femmodel_buffer;
260 
261  /*Marshall:*/
262  this->Marshall(&femmodel_buffer,NULL,MARSHALLING_FORWARD);
263 
264  /*Reset position of buffer: */
265  femmodel_buffer=femmodel_buffer_ini;
266 
267  /*write buffer: */
268  fwrite(femmodel_buffer,femmodel_size,sizeof(char),restartfid);
269 
270  /*Done, close file :*/
271  pfclose(restartfid,restartfilename);
272 
273  /*Free ressources: */
274  xDelete<char>(femmodel_buffer);
275  xDelete<char>(restartfilename);
276 
277 }
278 /*}}}*/
279 void FemModel::CleanUp(void){/*{{{*/
280 
281  /*Intermediary*/
282  char *lockfilename = NULL;
283  bool waitonlock = false;
284 
285  /*Write lock file if requested: */
286  this->parameters->FindParam(&waitonlock,SettingsWaitonlockEnum);
287  this->parameters->FindParam(&lockfilename,LockFileNameEnum);
288  if(waitonlock){
289  _printf0_("write lock file:\n");
290  WriteLockFile(lockfilename);
291  }
292 
293  /*Before we delete the profiler, report statistics for this run: */
294  profiler->Stop(TOTAL); //final tagging
295 
296  _printf0_("\n");
297  _printf0_(" "<<setw(40)<<left<<"FemModel initialization elapsed time:"<<setw(7)<<profiler->TotalTime(MPROCESSOR) << "\n");
298  /*Total times*/
299  _printf0_(" "<<setw(40)<<left<<"Total Core solution elapsed time:"<<setw(7)<<profiler->TotalTime(CORE) << "\n");
300 
301  /*Linear solver only*/
302  _printf0_(" "<<setw(40)<<left<<"Linear solver elapsed time:"<<setw(7)<<profiler->TotalTime(SOLVER) << " ("<<setprecision(2)<<profiler->TotalTime(SOLVER)/profiler->TotalTime(CORE)*100.<<"%)\n");
303  _printf0_("\n");
304  _printf0_(" Total elapsed time: "
305  <<profiler->TotalTimeModHour(TOTAL)<<" hrs "
306  <<profiler->TotalTimeModMin(TOTAL)<<" min "
307  <<profiler->TotalTimeModSec(TOTAL)<<" sec"
308  );
309  _printf0_("\n");
310 
311  /*Finalize PETSC for this model: */
312  #ifdef _HAVE_PETSC_
313  //_printf0_("closing PETSc\n");
314  PetscFinalize();
315  #endif
316 
317  /*Clean up*/
318  xDelete<char>(lockfilename);
319 } /*}}}*/
320 FemModel* FemModel::copy(void){/*{{{*/
321 
322  FemModel* output=NULL;
323  int i;
324  int analysis_type;
325 
326  output=new FemModel(*this); //Use default copy constructor.
327 
328  output->nummodels = this->nummodels;
329  output->solution_type = this->solution_type;
330  output->analysis_counter = this->analysis_counter;
331 
332  /*Now, deep copy arrays: */
333  output->analysis_type_list=xNew<int>(nummodels);
334  xMemCpy<int>(output->analysis_type_list,this->analysis_type_list,this->nummodels);
335 
336  /*Analysis dependent arrays*/
337  output->constraints_list=xNew<Constraints*>(this->nummodels);
338  output->loads_list=xNew<Loads*>(this->nummodels);
339  output->nodes_list=xNew<Nodes*>(this->nummodels);
340 
341  output->profiler=static_cast<Profiler*>(this->profiler->copy());
342 
343  output->materials=static_cast<Materials*>(this->materials->Copy());
344  output->parameters=static_cast<Parameters*>(this->parameters->Copy());
345  output->inputs2=static_cast<Inputs2*>(this->inputs2->Copy());
346  output->results=static_cast<Results*>(this->results->Copy());
347  output->vertices=static_cast<Vertices*>(this->vertices->Copy());
348  output->elements=static_cast<Elements*>(this->elements->Copy());
349 
350  /*reset hooks for elements, loads and nodes: */
351  output->elements->ResetHooks();
352  output->loads->ResetHooks();
353  output->materials->ResetHooks();
354 
355  /*do the post-processing of the datasets to get an FemModel that can actually run analyses: */
356  for(i=0;i<nummodels;i++){
357  output->constraints_list[i] = static_cast<Constraints*>(this->constraints_list[i]->Copy());
358  output->loads_list[i] = static_cast<Loads*>(this->loads_list[i]->Copy());
359  output->nodes_list[i] = static_cast<Nodes*>(this->nodes_list[i]->Copy());
360  analysis_type=output->analysis_type_list[i];
361  output->SetCurrentConfiguration(analysis_type);
362  SpcNodesx(output->nodes_list[i],output->constraints_list[i],output->parameters);
363  NodesDofx(output->nodes_list[i],output->parameters);
364  ConfigureObjectsx(output->elements,output->loads_list[i],output->nodes_list[i],output->vertices,output->materials,output->parameters,output->inputs2);
365  }
366 
367  /*AMR, no copy for now*/
368  #if defined(_HAVE_NEOPZ_) && !defined(_HAVE_AD_)
369  this->amr = NULL;
370  #endif
371  #if defined(_HAVE_BAMG_) && !defined(_HAVE_AD_)
372  this->amrbamg = NULL;
373  #endif
374 
375  /*Reset current configuration: */
376  analysis_type=output->analysis_type_list[analysis_counter];
377  output->SetCurrentConfiguration(analysis_type);
378 
379  return output;
380 }
381 /*}}}*/
382 void FemModel::Echo(void){/*{{{*/
383 
384  _printf_("FemModel echo: \n");
385  _printf_(" number of fem models: " << nummodels << "\n");
386  _printf_(" analysis_type_list: \n");
387  for(int i=0;i<nummodels;i++)_printf_(" " << i << ": " << EnumToStringx(analysis_type_list[i]) << "\n");
388  _printf_(" current analysis_type: \n");
390 
391 }
392 /*}}}*/
393 void FemModel::InitFromFiles(char* rootpath, char* inputfilename, char* outputfilename, char* toolkitsfilename, char* lockfilename, char* restartfilename, const int in_solution_type,bool trace,IssmPDouble* X){/*{{{*/
394 
395  /*intermediary*/
396  FILE *IOMODEL = NULL;
397  FILE *toolkitsoptionsfid = NULL;
398 
399  /*recover my_rank:*/
400  int my_rank=IssmComm::GetRank();
401 
402  /*Open input file descriptor on cpu 0: */
403  if(my_rank==0) IOMODEL = pfopen0(inputfilename ,"rb");
404 
405  /*Open toolkits file: */
406  toolkitsoptionsfid=pfopen(toolkitsfilename,"r");
407 
408  /*Now, go create FemModel:*/
409  this->InitFromFids(rootpath,IOMODEL,toolkitsoptionsfid,in_solution_type,trace,X);
410 
411  /*Close input file and toolkits file descriptors: */
412  if(my_rank==0) pfclose(IOMODEL,inputfilename);
413  pfclose(toolkitsoptionsfid,toolkitsfilename);
414 
415  /*Now save all of these file names into parameters, you never know when you might need them: */
416  this->parameters->AddObject(new StringParam(ToolkitsFileNameEnum,toolkitsfilename));
417  this->parameters->AddObject(new StringParam(RootPathEnum,rootpath));
418  this->parameters->AddObject(new StringParam(InputFileNameEnum,inputfilename));
419  this->parameters->AddObject(new StringParam(OutputFileNameEnum,outputfilename));
420  this->parameters->AddObject(new StringParam(LockFileNameEnum,lockfilename));
421  this->parameters->AddObject(new StringParam(RestartFileNameEnum,restartfilename));
422 
423 }/*}}}*/
424 void FemModel::InitFromFids(char* rootpath, FILE* IOMODEL, FILE* toolkitsoptionsfid, int in_solution_type, bool trace, IssmPDouble* X){/*{{{*/
425 
426  /*Initialize internal data: */
427  this->solution_type = in_solution_type;
428  this->analysis_counter = -1;
429  this->results = new Results(); //not initialized by CreateDataSets
430 
431  /*create IoModel */
432  IoModel* iomodel = new IoModel(IOMODEL,in_solution_type,trace,X);
433 
434  /*Figure out what analyses are activated for this solution*/
435  SolutionAnalysesList(&this->analysis_type_list,&this->nummodels,iomodel,this->solution_type);
436 
437  /*create datasets for all analyses*/
438  ModelProcessorx(&this->elements,&this->nodes_list,&this->vertices,&this->materials,&this->constraints_list,&this->loads_list,&this->parameters,&this->inputs2,iomodel,toolkitsoptionsfid,rootpath,this->solution_type,this->nummodels,this->analysis_type_list);
439 
440  /*do the post-processing of the datasets to get an FemModel that can actually run analyses: */
441  for(int i=0;i<nummodels;i++){
442 
443  if(VerboseMProcessor()) _printf0_(" Processing finite element model of analysis " << EnumToStringx(analysis_type_list[i]) << ":\n");
445 
446  if(VerboseMProcessor()) _printf0_(" configuring element and loads\n");
447  ConfigureObjectsx(this->elements,this->loads,this->nodes,this->vertices,this->materials,this->parameters,this->inputs2);
448 
449  if(i==0){
450  if(VerboseMProcessor()) _printf0_(" detecting active vertices\n");
452  }
453 
454  if(VerboseMProcessor()) _printf0_(" resolving node constraints\n");
456 
457  if(VerboseMProcessor()) _printf0_(" creating nodal degrees of freedom\n");
459  }
460 
461  /*Clean up*/
462  delete iomodel;
463 }/*}}}*/
464 void FemModel::Marshall(char** pmarshalled_data, int* pmarshalled_data_size, int marshall_direction){ /*{{{*/
465 
466  int i;
467  int analysis_type;
468 
469  if(marshall_direction==MARSHALLING_BACKWARD){
470  delete this->materials;
471  delete this->parameters;
472  delete this->inputs2;
473  if(this->constraints_list && this->nummodels){
474  for(i=0;i<this->nummodels;i++) delete this->constraints_list[i];
475  xDelete<Constraints*>(constraints_list);
476  }
477  if(this->loads_list && this->nummodels){
478  for(i=0;i<this->nummodels;i++) delete this->loads_list[i];
479  xDelete<Loads*>(loads_list);
480  }
481  if(this->nodes_list && this->nummodels){
482  for(i=0;i<this->nummodels;i++) delete this->nodes_list[i];
483  xDelete<Nodes*>(nodes_list);
484  }
485  delete this->results;
486  delete this->vertices;
487  delete this->elements;
488  xDelete<int>(this->analysis_type_list);
489 
490  this->materials = new Materials();
491  this->parameters = new Parameters();
492  this->inputs2 = new Inputs2();
493  this->results = new Results();
494  this->nodes = new Nodes();
495  this->vertices = new Vertices();
496  this->elements = new Elements();
497  }
498 
500 
505 
506  this->materials->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
507  this->parameters->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
508  this->inputs2->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
509  this->results->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
510  this->vertices->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
511  this->elements->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
512 
513  if(marshall_direction==MARSHALLING_BACKWARD){
514  this->constraints_list = xNew<Constraints*>(this->nummodels);
515  for(i=0;i<nummodels;i++) this->constraints_list[i] = new Constraints();
516  this->loads_list = xNew<Loads*>(this->nummodels);
517  for(i=0;i<nummodels;i++) this->loads_list[i] = new Loads();
518  this->nodes_list = xNew<Nodes*>(this->nummodels);
519  for(i=0;i<nummodels;i++) this->nodes_list[i] = new Nodes();
520  }
521 
522  for(i=0;i<nummodels;i++){
523  this->constraints_list[i]->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
524  this->loads_list[i]->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
525  this->nodes_list[i]->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
526  }
527 
528  if(marshall_direction==MARSHALLING_BACKWARD){
529  /*reset hooks for elements, loads and nodes:*/
530  this->elements->ResetHooks();
531  this->materials->ResetHooks();
532 
533  /*do the post-processing of the datasets to get an FemModel that can actually run analyses:*/
534  for(i=0;i<nummodels;i++){
535  this->loads_list[i]->ResetHooks();
536  analysis_type=this->analysis_type_list[i];
537  SetCurrentConfiguration(analysis_type);
538  SpcNodesx(this->nodes_list[i],this->constraints_list[i],this->parameters);
539  NodesDofx(this->nodes_list[i],this->parameters);
540  ConfigureObjectsx(this->elements,this->loads_list[i],this->nodes_list[i],this->vertices,this->materials,this->parameters,this->inputs2);
541  }
542 
543  //Reset current configuration:
544  analysis_type=this->analysis_type_list[analysis_counter];
545  SetCurrentConfiguration(analysis_type);
546  }
547 }
548 /*}}}*/
549 void FemModel::Restart(){ /*{{{*/
550 
551  FILE* restartfid=NULL;
552  char* restartfilename = NULL;
553  int femmodel_size=0;
554  int fread_return=0;
555  char* femmodel_buffer=NULL;
556  char* femmodel_buffer_ini=NULL;
557 
558  /*First, recover the name of the restart file: */
559  parameters->FindParam(&restartfilename,RestartFileNameEnum);
560 
561  /*Now, figure out whether this file actually exists!: */
562  restartfid=pfopen(restartfilename,"r",false);
563 
564  if(restartfid==NULL){
565  xDelete<char>(restartfilename);
566  return; //could not find the file, so no restart possible.
567  }
568 
569  /*Print banner*/
570  _printf0_(" \n");
571  _printf0_("====================================================================\n");
572  _printf0_(" RESTART DETECTED \n");
573  _printf0_(" \n");
574  _printf0_(" Restart file: "<<restartfilename<<" \n");
575  _printf0_("====================================================================\n");
576  _printf0_(" \n");
577 
578  /*Figure out size of buffer to be read: */
579  fseek(restartfid, 0L, SEEK_END);
580  femmodel_size = ftell(restartfid);
581  fseek(restartfid, 0L, SEEK_SET);
582 
583  /*Allocate buffer: */
584  femmodel_buffer=xNew<char>(femmodel_size);
585 
586  /*Read buffer from file: */
587  fread_return=fread(femmodel_buffer,femmodel_size,sizeof(char),restartfid); if(fread_return!=1)_error_("error reading the buffer from marshalled file!");
588  femmodel_buffer_ini=femmodel_buffer; //keep track of the initial position, so as to free later.
589 
590  /*Create new FemModel by demarshalling the buffer: */
591  this->Marshall(&femmodel_buffer,NULL,MARSHALLING_BACKWARD);
592 
593  /*Reset position of buffer: */
594  femmodel_buffer=femmodel_buffer_ini;
595 
596  /*Done, close file :*/
597  pfclose(restartfid,restartfilename);
598 
599  /*Free ressources: */
600  xDelete<char>(restartfilename);
601  xDelete<char>(femmodel_buffer);
602 }/*}}}*/
603 void FemModel::SetCurrentConfiguration(int configuration_type,int analysis_type){/*{{{*/
604 
605  /*Use configuration_type to setup the analysis counter, the configurations of objects etc ... but use
606  * analysis_type to drive the element numerics. This allows for use of 1 configuration_type for several
607  * analyses. For example: do a SurfaceSlopeX, SurfaceSlopeY, BedSlopeX and BedSlopeY analysis using the
608  * Slope configuration.*/
609  int index = AnalysisIndex(configuration_type);
610 
611  /*If we already have the right analysis, return*/
612  //if(this->analysis_counter==index) return;
613  this->analysis_counter=index;
614 
615  /*Now, plug analysis_counter and analysis_type inside the parameters: */
617  this->parameters->SetParam(analysis_type,AnalysisTypeEnum);
618  this->parameters->SetParam(configuration_type,ConfigurationTypeEnum);
619 
620  /*configure elements, loads and nodes, for this new analysis: */
621  this->loads = this->loads_list[this->analysis_counter];
622  this->constraints = this->constraints_list[this->analysis_counter];
623  this->nodes = this->nodes_list[this->analysis_counter];
626 
627  /*take care of toolkits options, that depend on this analysis type (present only after model processor)*/
629  ToolkitsOptionsFromAnalysis(this->parameters,analysis_type);
630  if(VerboseSolver()) _printf0_(" toolkits Options set for analysis: " << EnumToStringx(analysis_type) << "\n");
631  }
632 
633 }/*}}}*/
634 void FemModel::SetCurrentConfiguration(int configuration_type){/*{{{*/
635  this->SetCurrentConfiguration(configuration_type,configuration_type);
636 }
637 /*}}}*/
638 int FemModel::Size(){ /*{{{*/
639  int femmodel_size;
640 
641  this->Marshall(NULL,&femmodel_size,MARSHALLING_SIZE);
642 
643  return femmodel_size;
644 }
645 /*}}}*/
646 void FemModel::SolutionAnalysesList(int** panalyses,int* pnumanalyses,IoModel* iomodel,int solutiontype){/*{{{*/
647 
648  /*output: */
649  int numanalyses = 0;
650  int *analyses = NULL;
651 
652  /*Intermediaries*/
653  const int MAXANALYSES = 30;
654  int analyses_temp[MAXANALYSES];
655 
656  /*Analyses lists*/
657  switch(solutiontype){
658 
660  bool isSIA,isFS;
661  int fe_FS;
662  iomodel->FindConstant(&fe_FS,"md.flowequation.fe_FS");
663  iomodel->FindConstant(&isSIA,"md.flowequation.isSIA");
664  iomodel->FindConstant(&isFS,"md.flowequation.isFS");
665  analyses_temp[numanalyses++]=StressbalanceAnalysisEnum;
666  analyses_temp[numanalyses++]=StressbalanceVerticalAnalysisEnum;
667  if(isSIA){
668  analyses_temp[numanalyses++]=StressbalanceSIAAnalysisEnum;
669  }
670  analyses_temp[numanalyses++]=L2ProjectionBaseAnalysisEnum;
671  analyses_temp[numanalyses++]=ExtrudeFromBaseAnalysisEnum;
672  analyses_temp[numanalyses++]=DepthAverageAnalysisEnum;
673  if(fe_FS==LATaylorHoodEnum || fe_FS==LACrouzeixRaviartEnum){
674  analyses_temp[numanalyses++]=UzawaPressureAnalysisEnum;
675  }
676  }
677  break;
678 
680  bool isSIA,isenthalpy;
681  iomodel->FindConstant(&isSIA,"md.flowequation.isSIA");
682  iomodel->FindConstant(&isenthalpy,"md.thermal.isenthalpy");
683  analyses_temp[numanalyses++]=StressbalanceAnalysisEnum;
684  analyses_temp[numanalyses++]=StressbalanceVerticalAnalysisEnum;
685  if(isSIA){
686  analyses_temp[numanalyses++]=StressbalanceSIAAnalysisEnum;
687  }
688  if(isenthalpy){
689  analyses_temp[numanalyses++]=EnthalpyAnalysisEnum;
690  }
691  else{
692  analyses_temp[numanalyses++]=ThermalAnalysisEnum;
693  analyses_temp[numanalyses++]=MeltingAnalysisEnum;
694  }
695  analyses_temp[numanalyses++]=L2ProjectionBaseAnalysisEnum;
696  }
697  break;
698 
699  case ThermalSolutionEnum:{
700  bool isenthalpy;
701  iomodel->FindConstant(&isenthalpy,"md.thermal.isenthalpy");
702  if(isenthalpy){
703  analyses_temp[numanalyses++]=EnthalpyAnalysisEnum;
704  }
705  else{
706  analyses_temp[numanalyses++]=ThermalAnalysisEnum;
707  analyses_temp[numanalyses++]=MeltingAnalysisEnum;
708  }
709  }
710  break;
711 
712  case HydrologySolutionEnum:{
713  int hydrology_model;
714  iomodel->FindConstant(&hydrology_model,"md.hydrology.model");
715  if(hydrology_model==HydrologyshreveEnum){
716  analyses_temp[numanalyses++]=HydrologyShreveAnalysisEnum;
717  }
718  else if(hydrology_model==HydrologyGlaDSEnum){
719  analyses_temp[numanalyses++]=HydrologyGlaDSAnalysisEnum;
720  }
721  if(hydrology_model==HydrologyshaktiEnum){
722  analyses_temp[numanalyses++]=HydrologyShaktiAnalysisEnum;
723  }
724  if(hydrology_model==HydrologypismEnum){
725  analyses_temp[numanalyses++]=HydrologyPismAnalysisEnum;
726  }
727  if(hydrology_model==HydrologydcEnum){
728  analyses_temp[numanalyses++]=HydrologyDCInefficientAnalysisEnum;
729  analyses_temp[numanalyses++]=HydrologyDCEfficientAnalysisEnum;
730  analyses_temp[numanalyses++]=L2ProjectionEPLAnalysisEnum;
731  analyses_temp[numanalyses++]=L2ProjectionBaseAnalysisEnum;
732  }
733  }
734  break;
735 
737  analyses_temp[numanalyses++]=DepthAverageAnalysisEnum;
738  analyses_temp[numanalyses++]=SmbAnalysisEnum;
739  analyses_temp[numanalyses++]=MasstransportAnalysisEnum;
740  analyses_temp[numanalyses++]=ExtrudeFromBaseAnalysisEnum;
741 
742  break;
743 
745  analyses_temp[numanalyses++]=BalancethicknessAnalysisEnum;
746  break;
747 
749  analyses_temp[numanalyses++]=L2ProjectionBaseAnalysisEnum;
750  analyses_temp[numanalyses++]=SmoothAnalysisEnum;
751  analyses_temp[numanalyses++]=Balancethickness2AnalysisEnum;
752  break;
753 
755  analyses_temp[numanalyses++]=BalancethicknessAnalysisEnum;
756  break;
757 
759  analyses_temp[numanalyses++]=BalancevelocityAnalysisEnum;
760  analyses_temp[numanalyses++]=SmoothAnalysisEnum;
761  break;
762 
764  analyses_temp[numanalyses++]=L2ProjectionBaseAnalysisEnum;
765  break;
766 
768  analyses_temp[numanalyses++]=L2ProjectionBaseAnalysisEnum;
769  break;
770 
771  case GiaSolutionEnum:
772  analyses_temp[numanalyses++]=GiaAnalysisEnum;
773  break;
774 
775  case LoveSolutionEnum:
776  analyses_temp[numanalyses++]=LoveAnalysisEnum;
777  break;
778 
779  case EsaSolutionEnum:
780  analyses_temp[numanalyses++]=EsaAnalysisEnum;
781  break;
782 
784  analyses_temp[numanalyses++]=SealevelriseAnalysisEnum;
785  analyses_temp[numanalyses++]=GiaAnalysisEnum;
786  break;
787 
788  case SmbSolutionEnum:
789  analyses_temp[numanalyses++]=SmbAnalysisEnum;
790  break;
791 
793  analyses_temp[numanalyses++]=DamageEvolutionAnalysisEnum;
794  break;
795 
796  case TransientSolutionEnum:{
797  /*We have multiple analyses here, process one by one*/
798  bool isSIA,isFS,isthermal,isenthalpy,ismasstransport,isgroundingline,isstressbalance,ismovingfront,ishydrology,isdamage,issmb,isslr,isesa,isgia;
799  iomodel->FindConstant(&isthermal,"md.transient.isthermal");
800  iomodel->FindConstant(&ismovingfront,"md.transient.ismovingfront");
801  iomodel->FindConstant(&ismasstransport,"md.transient.ismasstransport");
802  iomodel->FindConstant(&isstressbalance,"md.transient.isstressbalance");
803  iomodel->FindConstant(&isgroundingline,"md.transient.isgroundingline");
804  iomodel->FindConstant(&isdamage,"md.transient.isdamageevolution");
805  iomodel->FindConstant(&ishydrology,"md.transient.ishydrology");
806  iomodel->FindConstant(&issmb,"md.transient.issmb");
807  iomodel->FindConstant(&isslr,"md.transient.isslr");
808  iomodel->FindConstant(&isesa,"md.transient.isesa");
809  iomodel->FindConstant(&isgia,"md.transient.isgia");
810  int* analyses_iter = NULL;
811  int num_analyses_iter = 0;
812  if(isstressbalance){
813  SolutionAnalysesList(&analyses_iter,&num_analyses_iter,iomodel,StressbalanceSolutionEnum);
814  xMemCpy<int>(&analyses_temp[numanalyses],analyses_iter,num_analyses_iter);
815  numanalyses+=num_analyses_iter; xDelete<int>(analyses_iter);
816  }
817  if(isthermal && iomodel->domaintype==Domain3DEnum){
818  SolutionAnalysesList(&analyses_iter,&num_analyses_iter,iomodel,ThermalSolutionEnum);
819  xMemCpy<int>(&analyses_temp[numanalyses],analyses_iter,num_analyses_iter);
820  numanalyses+=num_analyses_iter; xDelete<int>(analyses_iter);
821  }
822  if(ismasstransport || isgroundingline){
823  analyses_temp[numanalyses++]=MasstransportAnalysisEnum;
824  int basalforcing_model;
825  iomodel->FindConstant(&basalforcing_model,"md.basalforcings.model");
826  if(basalforcing_model==BasalforcingsPicoEnum){
827  bool isplume;
828  iomodel->FindConstant(&isplume,"md.basalforcings.isplume");
829  if(isplume){
830  analyses_temp[numanalyses++]=GLheightadvectionAnalysisEnum;
831  }
832  }
833  }
834  if(issmb) analyses_temp[numanalyses++]=SmbAnalysisEnum;
835  if(ismovingfront){
836  analyses_temp[numanalyses++]=ExtrapolationAnalysisEnum;
837  analyses_temp[numanalyses++]=LevelsetAnalysisEnum;
838  }
839  if(ishydrology){
840  SolutionAnalysesList(&analyses_iter,&num_analyses_iter,iomodel,HydrologySolutionEnum);
841  xMemCpy<int>(&analyses_temp[numanalyses],analyses_iter,num_analyses_iter);
842  numanalyses+=num_analyses_iter; xDelete<int>(analyses_iter);
843  }
844  if(isdamage){
845  analyses_temp[numanalyses++]=DamageEvolutionAnalysisEnum;
846  }
847  if(isslr){
848  analyses_temp[numanalyses++]=GiaAnalysisEnum;
849  analyses_temp[numanalyses++]=SealevelriseAnalysisEnum;
850  }
851  if(isesa){
852  analyses_temp[numanalyses++]=EsaAnalysisEnum;
853  }
854  if(isgia){
855  analyses_temp[numanalyses++]=GiaAnalysisEnum;
856  }
857 
858  if(iomodel->domaintype==Domain2DverticalEnum || iomodel->domaintype==Domain3DEnum){
859  analyses_temp[numanalyses++]=ExtrudeFromBaseAnalysisEnum;
860  analyses_temp[numanalyses++]=ExtrudeFromTopAnalysisEnum;
861  analyses_temp[numanalyses++]=FreeSurfaceBaseAnalysisEnum;
862  analyses_temp[numanalyses++]=FreeSurfaceTopAnalysisEnum;
863  }
864  analyses_temp[numanalyses++]=L2ProjectionBaseAnalysisEnum;
865  }
866  break;
867 
868  default:
869  _error_("solution type: " << EnumToStringx(solutiontype) << " not supported yet!");
870  break;
871  }
872 
873  /*Copy analyses from temp to output*/
874  _assert_(numanalyses<MAXANALYSES);
875  analyses=xNew<int>(numanalyses);
876  for(int i=0;i<numanalyses;i++) analyses[i]=analyses_temp[i];
877 
878  /*Assign output pointers:*/
879  if(pnumanalyses) *pnumanalyses=numanalyses;
880  if(panalyses) *panalyses=analyses;
881  else xDelete<int>(analyses);
882 }/*}}}*/
883 void FemModel::Solve(void){/*{{{*/
884 
885  /*profiling: */
886  bool profiling = false;
887  IssmDouble solution_time;
888  IssmDouble solution_flops;
889  IssmDouble solution_memory;
890 
891  /*solution: */
892  int solution_type;
893  void (*solutioncore)(FemModel*)=NULL; //core solution function pointer
894 
895  _printf0_("call computational core:\n");
896 
897  /*Retrieve solution_type from parameters: */
899 
900  /*Figure out which solution core we are going to run with the current solution type: */
901  WrapperCorePointerFromSolutionEnum(&solutioncore,this->parameters,solution_type);
902 
903  /*run solution core: */
904  profiler->Start(CORE);
905  solutioncore(this);
906  profiler->Stop(CORE);
907 
908  /*run AD core if needed: */
910  ad_core(this);
911  profiler->Stop(ADCORE);
912 
913  /*some profiling results for the core: */
915  if(profiling){
916 
917  solution_time=profiler->TotalTime(CORE);
918  solution_flops=profiler->TotalFlops(CORE);
919  solution_memory=profiler->Memory(CORE);
920 
921  _printf0_("\nCore solution profiling\n");
922  _printf0_(" elapsed time : " << solution_time << " Seconds\n");
923  _printf0_(" number of flops : " << solution_flops << " Flops\n");
924  _printf0_(" memory used : " << solution_memory << " Bytes\n");
925 
926  /*Individual cores*/
927  _printf0_("Individual core profiling\n");
928  if(profiler->Used(THERMALCORE)) _printf0_(" "<<setw(40)<<left<<"Thermal core elapsed time:"<<setw(7)<<setprecision(6)<<profiler->TotalTime(THERMALCORE) << " sec\n");
929  if(profiler->Used(HYDROLOGYCORE)) _printf0_(" "<<setw(40)<<left<<"Hydrology core elapsed time:"<<setw(7)<<setprecision(6)<<profiler->TotalTime(HYDROLOGYCORE) << " sec\n");
930  if(profiler->Used(STRESSBALANCECORE)) _printf0_(" "<<setw(40)<<left<<"Stress balance core elapsed time:"<<setw(7)<<setprecision(6)<<profiler->TotalTime(STRESSBALANCECORE) << " sec\n");
931  if(profiler->Used(DAMAGECORE)) _printf0_(" "<<setw(40)<<left<<"Damage core elapsed time:"<<setw(7)<<setprecision(6)<<profiler->TotalTime(DAMAGECORE) << " sec\n");
932  if(profiler->Used(MOVINGFRONTCORE)) _printf0_(" "<<setw(40)<<left<<"Moving front core elapsed time:"<<setw(7)<<setprecision(6)<<profiler->TotalTime(MOVINGFRONTCORE) << " sec\n");
933  if(profiler->Used(MASSTRANSPORTCORE)) _printf0_(" "<<setw(40)<<left<<"Mass transport core elapsed time:"<<setw(7)<<setprecision(6)<<profiler->TotalTime(MASSTRANSPORTCORE) << " sec\n");
934  if(profiler->Used(SMBCORE)) _printf0_(" "<<setw(40)<<left<<"SMB core elapsed time:"<<setw(7)<<setprecision(6)<<profiler->TotalTime(SMBCORE) << " sec\n");
935  if(profiler->Used(GROUNDINGLINECORE)) _printf0_(" "<<setw(40)<<left<<"Groundingline migration core elapsed time:"<<setw(7)<<setprecision(6)<<profiler->TotalTime(GROUNDINGLINECORE) << " sec\n");
936  if(profiler->Used(GIACORE)) _printf0_(" "<<setw(40)<<left<<"GIA core elapsed time:"<<setw(7)<<setprecision(6)<<profiler->TotalTime(GIACORE) << " sec\n");
937  if(profiler->Used(ESACORE)) _printf0_(" "<<setw(40)<<left<<"ESA core elapsed time:"<<setw(7)<<setprecision(6)<<profiler->TotalTime(ESACORE) << " sec\n");
938  if(profiler->Used(SLRCORE)) _printf0_(" "<<setw(40)<<left<<"SLR core elapsed time:"<<setw(7)<<setprecision(6)<<profiler->TotalTime(SLRCORE) << " sec\n");
939  if(profiler->Used(MPISERIAL)) _printf0_(" "<<setw(40)<<left<<"MPISERIAL elapsed time:"<<setw(7)<<setprecision(6)<<profiler->TotalTime(MPISERIAL) << " sec\n");
940 
941  /*Add to results: */
945 
946  #ifdef _HAVE_AD_
947  solution_time = profiler->TotalTime(ADCORE);
948  solution_flops = profiler->TotalFlops(ADCORE);
949  solution_memory = profiler->Memory(ADCORE);
950 
951  _printf0_("AD profiling\n");
952  _printf0_(" elapsed time : " << solution_time << " Seconds\n");
953  _printf0_(" number of flops : " << solution_flops << " Flops\n");
954  _printf0_(" memory used : " << solution_memory << " Bytes\n");
955  #endif
956  _printf0_("\n");
957  }
958 }
959 /*}}}*/
960 
961 /*Modules:*/
963 
964  /*output: */
965  IssmDouble J=0.;
966  IssmDouble J_sum;
967 
968  IssmDouble weight,vx,vy,H,dvx[2],dvy[2],dH[2];
969  IssmDouble temp,Jdet,dhdt,groundedice_melting,surface_mass_balance;
970  IssmDouble* xyz_list = NULL;
971  IssmDouble dp[3];
972 
973  /*Compute Misfit: */
974  for(int i=0;i<elements->Size();i++){
975  Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
976 
977  /*If on water, return 0: */
978  if(!element->IsIceInElement()) continue;
979 
980  /* Get node coordinates*/
981  element->GetVerticesCoordinates(&xyz_list);
982  DatasetInput2* weights_input = element->GetDatasetInput2(InversionCostFunctionsCoefficientsEnum); _assert_(weights_input);
983  Input2* thickness_input = element->GetInput2(ThicknessEnum); _assert_(thickness_input);
984  Input2* vx_input = element->GetInput2(VxEnum); _assert_(vx_input);
985  Input2* vy_input = element->GetInput2(VyEnum); _assert_(vy_input);
986  Input2* surface_mass_balance_input = element->GetInput2(SmbMassBalanceEnum); _assert_(surface_mass_balance_input);
987  Input2* groundedice_melting_input = element->GetInput2(BasalforcingsGroundediceMeltingRateEnum); _assert_(groundedice_melting_input);
988  Input2* dhdt_input = element->GetInput2(BalancethicknessThickeningRateEnum); _assert_(dhdt_input);
989 
990  /* Start looping on the number of gaussian points: */
991  Gauss* gauss=element->NewGauss(2);
992  for(int ig=gauss->begin();ig<gauss->end();ig++){
993 
994  gauss->GaussPoint(ig);
995 
996  /* Get Jacobian determinant: */
997  element->JacobianDeterminant(&Jdet,xyz_list,gauss);
998 
999  /*Get all parameters at gaussian point*/
1000  weights_input->GetInputValue(&weight,gauss,BalancethicknessMisfitEnum);
1001  thickness_input->GetInputValue(&H, gauss);
1002  thickness_input->GetInputDerivativeValue(&dH[0],xyz_list,gauss);
1003  surface_mass_balance_input->GetInputValue(&surface_mass_balance,gauss);
1004  groundedice_melting_input->GetInputValue(&groundedice_melting,gauss);
1005  dhdt_input->GetInputValue(&dhdt,gauss);
1006  vx_input->GetInputValue(&vx,gauss);
1007  vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);
1008  vy_input->GetInputValue(&vy,gauss);
1009  vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);
1010 
1011  /*Balance thickness soft constraint J = 1/2 (div(Hv)-a)^2*/
1012  temp = vx*dH[0]+vy*dH[1]+H*(dvx[0]+dvy[1]) - (surface_mass_balance-groundedice_melting-dhdt);
1013  J +=weight*1/2*temp*temp*Jdet*gauss->weight;
1014  }
1015 
1016  /*clean up and Return: */
1017  xDelete<IssmDouble>(xyz_list);
1018  delete gauss;
1019  }
1020 
1021  /*Sum all J from all cpus of the cluster:*/
1024  J=J_sum;
1025 
1026  /*Assign output pointers: */
1027  *presponse=J;
1028 
1029 }/*}}}*/
1031 
1032  for(int i=0;i<elements->Size();i++){
1033  Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
1034  element->CalvingRateVonmises();
1035  }
1036 }
1037 /*}}}*/
1039 
1040  for(int i=0;i<elements->Size();i++){
1041  Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
1042  element->CalvingRateLevermann();
1043  }
1044 }
1045 /*}}}*/
1047 
1048  for(int i=0;i<elements->Size();i++){
1049  Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
1050  element->CalvingFluxLevelset();
1051  }
1052 }
1053 /*}}}*/
1055 
1056  for(int i=0;i<elements->Size();i++){
1057  Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
1058  element->CalvingMeltingFluxLevelset();
1059  }
1060 }
1061 /*}}}*/
1062 void FemModel::CostFunctionx(IssmDouble* pJ,IssmDouble** pJlist,int* pn){/*{{{*/
1063 
1064  /*Intermediary*/
1065  int num_responses;
1066  int *responses = NULL;
1067  Results *cost_functions = NULL;
1068 
1069  /*Recover parameters*/
1072 
1073  /*Get the value of all cost functions*/
1074  this->RequestedOutputsx(&cost_functions,responses,num_responses);
1075 
1076  /*Get and add all contributions one by one*/
1077  IssmDouble J=0;
1078  IssmDouble* Jlist = xNew<IssmDouble>(num_responses);
1079  for(int i=0;i<num_responses;i++){
1080  ExternalResult* result=(ExternalResult*)cost_functions->GetObjectByOffset(i);
1081  Jlist[i] = reCast<IssmDouble>(result->GetValue());
1082  J += Jlist[i];
1083  }
1084  _assert_(cost_functions->Size()==num_responses);
1085 
1086  /*Assign output pointers: */
1087  delete cost_functions;
1088  xDelete<int>(responses);
1089  if(pJ) *pJ = J;
1090  if(pJlist) *pJlist = Jlist;
1091  else xDelete<IssmDouble>(Jlist);
1092  if(pn) *pn = num_responses;
1093 }
1094 /*}}}*/
1096 
1097  for(int i=0;i<elements->Size();i++){
1098  Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
1099  element->ComputeDeviatoricStressTensor();
1100  }
1101 }
1102 /*}}}*/
1103 void FemModel::DistanceToFieldValue(int fieldenum,IssmDouble fieldvalue,int distanceenum){/*{{{*/
1104 
1105  /*recover my_rank:*/
1106  int my_rank = IssmComm::GetRank();
1107  int num_procs = IssmComm::GetSize();
1108 
1109  /*Get domain type (2d or 3d)*/
1110  int domaintype;
1111  this->parameters->FindParam(&domaintype,DomainTypeEnum);
1112 
1113  /*1: go throug all elements of this partition and figure out how many
1114  * segments we have (corresopnding to field = value)*/
1115  DataSet* segments=new DataSet();
1116  for(int i=0;i<elements->Size();i++){
1117  Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
1118  if(!element->IsOnBase()) continue;
1119  Element* basalelement = element->SpawnBasalElement();
1120  basalelement->WriteFieldIsovalueSegment(segments,fieldenum,fieldvalue);
1121  if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;};
1122  }
1123 
1124  /*2: now get the segments from all partitions*/
1125  int segcount=segments->Size();
1126  int* allsegcount=xNew<int>(num_procs);
1127  ISSM_MPI_Gather(&segcount,1,ISSM_MPI_INT,allsegcount,1,ISSM_MPI_INT,0,IssmComm::GetComm());
1128  ISSM_MPI_Bcast(allsegcount,num_procs,ISSM_MPI_INT,0,IssmComm::GetComm());
1129 
1130  /* Every cpu should start its own dof count at the end of the dofcount from cpu-1*/
1131  int numseg_offset=0;
1132  int numseg=0;
1133  for(int i=0;i<my_rank; i++) numseg_offset+=allsegcount[i];
1134  for(int i=0;i<num_procs;i++) numseg+=allsegcount[i];
1135  IssmDouble* segmentlist = xNewZeroInit<IssmDouble>(4*numseg);
1136  IssmDouble* allsegmentlist = xNewZeroInit<IssmDouble>(4*numseg);
1137  for(int i=0;i<segments->Size();i++){
1139  _assert_(segment->nods == 2);
1140  segmentlist[(numseg_offset+i)*4 + 0] = segment->x[0];
1141  segmentlist[(numseg_offset+i)*4 + 1] = segment->y[0];
1142  segmentlist[(numseg_offset+i)*4 + 2] = segment->x[1];
1143  segmentlist[(numseg_offset+i)*4 + 3] = segment->y[1];
1144  }
1145 
1146  ISSM_MPI_Allreduce((void*)segmentlist,(void*)allsegmentlist,4*numseg,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,IssmComm::GetComm());
1147  delete segments;
1148  xDelete<IssmDouble>(segmentlist);
1149  xDelete<int>(allsegcount);
1150 
1151  /*3: Add distance input to all elements*/
1152  IssmDouble* distances = xNew<IssmDouble>(vertices->Size());
1153  IssmDouble d,xn,yn,dmin;
1154  int last = -1;
1155  for(int v=0;v<vertices->Size();v++){
1156 
1157  Vertex* vertex=dynamic_cast<Vertex*>(this->vertices->GetObjectByOffset(v));
1158  IssmDouble x = vertex->x;
1159  IssmDouble y = vertex->y;
1160 
1161  /*Most of the time the last checked segment is the closest so start with that one*/
1162  if(last>0){
1163  dmin = pow(allsegmentlist[4*last+0] - x,2) + pow(y-allsegmentlist[4*last+1],2);
1164  }
1165  else{
1166  dmin = 1.e+50;
1167  }
1168 
1169  for(int i=0;i<numseg;i++){
1170 
1171  /*Skip if tip is more than 10xdmin away*/
1172  if(pow(allsegmentlist[4*i+0] - x,2)>10*dmin) continue;
1173  if(pow(allsegmentlist[4*i+1] - y,2)>10*dmin) continue;
1174 
1175  IssmDouble l2 = (allsegmentlist[4*i+2]-allsegmentlist[4*i+0])*(allsegmentlist[4*i+2]-allsegmentlist[4*i+0]) + (allsegmentlist[4*i+3]-allsegmentlist[4*i+1])*(allsegmentlist[4*i+3]-allsegmentlist[4*i+1]);
1176 
1177  /*Segment has a length of 0*/
1178  if(l2==0.){
1179  d = (x-allsegmentlist[4*i+0])*(x-allsegmentlist[4*i+0])+(y-allsegmentlist[4*i+1])*(y-allsegmentlist[4*i+1]);
1180  if(d<dmin){
1181  dmin = d;
1182  last = i;
1183  }
1184  continue;
1185  }
1186 
1187  /*Consider the line extending the segment, parameterized as v + t (w - v).
1188  *We find projection of point p onto the line.
1189  *It falls where t = [(p-v) . (w-v)] / |w-v|^2*/
1190  IssmDouble t = ((x-allsegmentlist[4*i+0])*(allsegmentlist[4*i+2]-allsegmentlist[4*i+0]) + (y-allsegmentlist[4*i+1])*(allsegmentlist[4*i+3]-allsegmentlist[4*i+1]))/l2;
1191  if(t < 0.0){
1192  // Beyond the 'v' end of the segment
1193  d = (x-allsegmentlist[4*i+0])*(x-allsegmentlist[4*i+0])+(y-allsegmentlist[4*i+1])*(y-allsegmentlist[4*i+1]);
1194  }
1195  else if (t > 1.0){
1196  // Beyond the 'w' end of the segment
1197  d = (x-allsegmentlist[4*i+2])*(x-allsegmentlist[4*i+2])+(y-allsegmentlist[4*i+3])*(y-allsegmentlist[4*i+3]);
1198  }
1199  else{
1200  // Projection falls on the segment
1201  xn = allsegmentlist[4*i+0] + t * (allsegmentlist[4*i+2] - allsegmentlist[4*i+0]);
1202  yn = allsegmentlist[4*i+1] + t * (allsegmentlist[4*i+3] - allsegmentlist[4*i+1]);
1203  d = (x-xn)*(x-xn)+(y-yn)*(y-yn);
1204  }
1205 
1206  if(d<dmin){
1207  dmin = d;
1208  last = i;
1209  }
1210  }
1211 
1212  /*Update signed distance*/
1213  _assert_(vertex->lid<vertices->Size());
1214  distances[vertex->lid] = sqrt(dmin);
1215  }
1216 
1217  for(int i=0;i<this->elements->Size();i++){
1218  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
1219  element->CreateDistanceInputFromSegmentlist(distances,distanceenum);
1220  }
1221  //InputUpdateFromVectorx(this,distances,distanceenum,VertexLIdEnum);
1222 
1223  /*Clean up and return*/
1224  xDelete<IssmDouble>(distances);
1225  xDelete<IssmDouble>(allsegmentlist);
1226 }/*}}}*/
1228 
1229  IssmDouble local_divergence=0;
1230  IssmDouble total_divergence;
1231 
1232  for(int i=0;i<this->elements->Size();i++){
1233  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
1234  local_divergence+=element->Divergence();
1235  }
1236  ISSM_MPI_Reduce(&local_divergence,&total_divergence,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
1237  ISSM_MPI_Bcast(&total_divergence,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
1238 
1239  /*Assign output pointers: */
1240  *pdiv=total_divergence;
1241 
1242 }/*}}}*/
1243 void FemModel::ElementOperationx(void (Element::*function)(void)){ /*{{{*/
1244 
1245  for(int i=0;i<elements->Size();i++){
1246  Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
1247  (element->*function)();
1248  }
1249 
1250 }
1251 /*}}}*/
1252 void FemModel::ElementResponsex(IssmDouble* presponse,int response_enum){/*{{{*/
1253 
1254  int found=0;
1255  int sumfound=0;
1256  int cpu_found=-1;
1257  int index;
1258  IssmDouble response;
1259  Element* element=NULL;
1260 
1261  /*retrieve element we are interested in: */
1262  this->parameters->FindParam(&index,IndexEnum);
1263  int my_rank=IssmComm::GetRank();
1264 
1265  /*now, go through our elements, and retrieve the one with this id: index: */
1266  for(int i=0;i<this->elements->Size();i++){
1267  element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
1268  if (element->Id()==index){
1269  found=1;
1270  cpu_found=my_rank;
1271  break;
1272  }
1273  }
1274 
1275  /*Broadcast whether we found the element: */
1277  if(!sumfound)_error_("could not find material with id" << index << " to compute ElementResponse");
1278 
1279  /*Ok, we found the element, compute responseocity: */
1280  if(my_rank==cpu_found){
1281  element->ElementResponse(&response,response_enum);
1282  }
1283 
1284  /*Broadcast and plug into response: */
1285  ISSM_MPI_Allreduce ( &cpu_found,&cpu_found,1,ISSM_MPI_INT,ISSM_MPI_MAX,IssmComm::GetComm());
1286  ISSM_MPI_Bcast(&response,1,ISSM_MPI_DOUBLE,cpu_found,IssmComm::GetComm());
1287 
1288  /*Assign output pointers: */
1289  *presponse=response;
1290 
1291 }/*}}}*/
1292 void FemModel::FloatingAreax(IssmDouble* pV, bool scaled){/*{{{*/
1293 
1294  IssmDouble local_floating_area= 0;
1295  IssmDouble total_floating_area;
1296 
1297  for(int i=0;i<this->elements->Size();i++){
1298  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
1299  local_floating_area+=element->FloatingArea(scaled);
1300  }
1301  ISSM_MPI_Reduce(&local_floating_area,&total_floating_area,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
1302  ISSM_MPI_Bcast(&total_floating_area,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
1303 
1304  /*Assign output pointers: */
1305  *pV=total_floating_area;
1306 
1307 }/*}}}*/
1309 
1310  /*Initialize output vectors*/
1311  int numnodes = this->nodes->NumberOfNodes();
1312  IssmDouble* uLmin_local = xNew<IssmDouble>(numnodes);
1313  IssmDouble* uLmax_local = xNew<IssmDouble>(numnodes);
1314  IssmDouble* uLmin = xNew<IssmDouble>(numnodes);
1315  IssmDouble* uLmax = xNew<IssmDouble>(numnodes);
1316  for(int i=0;i<numnodes;i++){
1317  uLmin_local[i] = +1.e+50;
1318  uLmax_local[i] = -1.e+50;
1319  }
1320 
1321  for(int i=0;i<this->elements->Size();i++){
1322  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
1323  element->GetInputLocalMinMaxOnNodes(uLmin_local,uLmax_local,ug);
1324  }
1325 
1326  /*Synchronize all CPUs*/
1327  ISSM_MPI_Allreduce((void*)uLmin_local,(void*)uLmin,numnodes,ISSM_MPI_DOUBLE,ISSM_MPI_MIN,IssmComm::GetComm());
1328  ISSM_MPI_Allreduce((void*)uLmax_local,(void*)uLmax,numnodes,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,IssmComm::GetComm());
1329  xDelete<IssmDouble>(uLmin_local);
1330  xDelete<IssmDouble>(uLmax_local);
1331 
1332  /*Assign output pointers: */
1333  *pmin=uLmin;
1334  *pmax=uLmax;
1335 
1336 }/*}}}*/
1338 
1339  this->nodes->GetLocalVectorWithClonesGset(plocal_ug,ug);
1340 
1341 }/*}}}*/
1343 
1344  /*retrieve vertex info*/
1345  int localsize = this->vertices->NumberOfVerticesLocalAll();
1346  int localsize_masters = this->vertices->NumberOfVerticesLocal();
1347 
1348  /*Get local vector of vector*/
1349  int *indices_vector_masters = NULL;
1350  IssmDouble *local_vector_masters = NULL;
1351  vector->GetLocalVector(&local_vector_masters,&indices_vector_masters);
1352  _assert_(localsize_masters==indices_vector_masters[localsize_masters-1] - indices_vector_masters[0]+1);
1353  xDelete<int>(indices_vector_masters);
1354 
1355  /*Now, extend vectors to account for clones (make vectors longer, for clones at the end)*/
1356  IssmDouble *local_vector = xNew<IssmDouble>(localsize);
1357  xMemCpy<IssmDouble>(local_vector,local_vector_masters,localsize_masters);
1358  xDelete<IssmDouble>(local_vector_masters);
1359 
1360  /*Now send and receive vector for vertices on partition edge*/
1361  SyncLocalVectorWithClonesVertices(local_vector);
1362 
1363  /*Assign output pointer*/
1364  *plocal_vector = local_vector;
1365 }/*}}}*/
1367 
1368  /*recover my_rank:*/
1369  ISSM_MPI_Status status;
1370  int my_rank = IssmComm::GetRank();
1371  int num_procs = IssmComm::GetSize();
1372 
1373  /*Now send and receive vector for vertices on partition edge*/
1374  #ifdef _HAVE_AD_
1375  IssmDouble* buffer = xNew<IssmDouble>(this->vertices->Size(),"t"); //only one alloc, "t" is required by adolc
1376  #else
1377  IssmDouble* buffer = xNew<IssmDouble>(this->vertices->Size());
1378  #endif
1379  for(int rank=0;rank<num_procs;rank++){
1380  if(this->vertices->common_send[rank]){
1381  int numids = this->vertices->common_send[rank];
1382  for(int i=0;i<numids;i++){
1383  int master_lid = this->vertices->common_send_ids[rank][i];
1384  Vertex* vertex=xDynamicCast<Vertex*>(this->vertices->GetObjectByOffset(master_lid));
1385  _assert_(!vertex->clone);
1386  buffer[i] = local_vector[vertex->lid];
1387  }
1388  ISSM_MPI_Send(buffer,numids,ISSM_MPI_DOUBLE,rank,0,IssmComm::GetComm());
1389  }
1390  }
1391  for(int rank=0;rank<num_procs;rank++){
1392  if(this->vertices->common_recv[rank]){
1393  int numids = this->vertices->common_recv[rank];
1394  ISSM_MPI_Recv(buffer,numids,ISSM_MPI_DOUBLE,rank,0,IssmComm::GetComm(),&status);
1395  for(int i=0;i<numids;i++){
1396  int master_lid = this->vertices->common_recv_ids[rank][i];
1397  Vertex* vertex=xDynamicCast<Vertex*>(this->vertices->GetObjectByOffset(master_lid));
1398  _assert_(vertex->clone);
1399  local_vector[vertex->lid] = buffer[i];
1400  }
1401  }
1402  }
1403  xDelete<IssmDouble>(buffer);
1404 }/*}}}*/
1406 
1407  /*recover my_rank:*/
1408  ISSM_MPI_Status status;
1409  int my_rank = IssmComm::GetRank();
1410  int num_procs = IssmComm::GetSize();
1411 
1412  /*Now send and receive vector for vertices on partition edge*/
1413  #ifdef _HAVE_AD_
1414  IssmDouble* buffer = xNew<IssmDouble>(this->vertices->Size(),"t"); //only one alloc, "t" is required by adolc
1415  #else
1416  IssmDouble* buffer = xNew<IssmDouble>(this->vertices->Size());
1417  #endif
1418 
1419  /*1st: add slaves to master values (reverse of what we usually do)*/
1420  for(int rank=0;rank<num_procs;rank++){
1421  if(this->vertices->common_recv[rank]){
1422  int numids = this->vertices->common_recv[rank];
1423  for(int i=0;i<numids;i++){
1424  int master_lid = this->vertices->common_recv_ids[rank][i];
1425  Vertex* vertex=xDynamicCast<Vertex*>(this->vertices->GetObjectByOffset(master_lid));
1426  _assert_(vertex->clone);
1427  buffer[i] = local_vector[vertex->lid];
1428  }
1429  ISSM_MPI_Send(buffer,numids,ISSM_MPI_DOUBLE,rank,0,IssmComm::GetComm());
1430  }
1431  }
1432  for(int rank=0;rank<num_procs;rank++){
1433  if(this->vertices->common_send[rank]){
1434  int numids = this->vertices->common_send[rank];
1435  ISSM_MPI_Recv(buffer,numids,ISSM_MPI_DOUBLE,rank,0,IssmComm::GetComm(),&status);
1436  for(int i=0;i<numids;i++){
1437  int master_lid = this->vertices->common_send_ids[rank][i];
1438  Vertex* vertex=xDynamicCast<Vertex*>(this->vertices->GetObjectByOffset(master_lid));
1439  _assert_(!vertex->clone);
1440  local_vector[vertex->lid] += buffer[i];
1441  }
1442  }
1443  }
1444 
1445  /*Now sync masters across partitions*/
1446  for(int rank=0;rank<num_procs;rank++){
1447  if(this->vertices->common_send[rank]){
1448  int numids = this->vertices->common_send[rank];
1449  for(int i=0;i<numids;i++){
1450  int master_lid = this->vertices->common_send_ids[rank][i];
1451  Vertex* vertex=xDynamicCast<Vertex*>(this->vertices->GetObjectByOffset(master_lid));
1452  _assert_(!vertex->clone);
1453  buffer[i] = local_vector[vertex->lid];
1454  }
1455  ISSM_MPI_Send(buffer,numids,ISSM_MPI_DOUBLE,rank,0,IssmComm::GetComm());
1456  }
1457  }
1458  for(int rank=0;rank<num_procs;rank++){
1459  if(this->vertices->common_recv[rank]){
1460  int numids = this->vertices->common_recv[rank];
1461  ISSM_MPI_Recv(buffer,numids,ISSM_MPI_DOUBLE,rank,0,IssmComm::GetComm(),&status);
1462  for(int i=0;i<numids;i++){
1463  int master_lid = this->vertices->common_recv_ids[rank][i];
1464  Vertex* vertex=xDynamicCast<Vertex*>(this->vertices->GetObjectByOffset(master_lid));
1465  _assert_(vertex->clone);
1466  local_vector[vertex->lid] = buffer[i];
1467  }
1468  }
1469  }
1470  xDelete<IssmDouble>(buffer);
1471 }/*}}}*/
1473 
1474  /*recover my_rank:*/
1475  ISSM_MPI_Status status;
1476  int my_rank = IssmComm::GetRank();
1477  int num_procs = IssmComm::GetSize();
1478 
1479  /*retrieve vertex info*/
1480  int localsize = this->nodes->NumberOfNodesLocalAll();
1481  int localsize_masters = this->nodes->NumberOfNodesLocal();
1482 
1483  /*Get local vector of vector*/
1484  int *indices_vector_masters = NULL;
1485  IssmDouble *local_vector_masters = NULL;
1486  vector->GetLocalVector(&local_vector_masters,&indices_vector_masters);
1487  _assert_(localsize_masters==indices_vector_masters[localsize_masters-1] - indices_vector_masters[0]+1);
1488  xDelete<int>(indices_vector_masters);
1489 
1490  /*Now, extend vectors to account for clones (make vectors longer, for clones at the end)*/
1491  IssmDouble *local_vector = xNew<IssmDouble>(localsize);
1492  xMemCpy<IssmDouble>(local_vector,local_vector_masters,localsize_masters);
1493  xDelete<IssmDouble>(local_vector_masters);
1494 
1495  /*Now send and receive vector for nodes on partition edge*/
1496  #ifdef _HAVE_AD_
1497  IssmDouble* buffer = xNew<IssmDouble>(this->nodes->Size(),"t"); //only one alloc, "t" is required by adolc
1498  #else
1499  IssmDouble* buffer = xNew<IssmDouble>(this->nodes->Size());
1500  #endif
1501  for(int rank=0;rank<num_procs;rank++){
1502  if(this->nodes->common_send[rank]){
1503  int numids = this->nodes->common_send[rank];
1504  for(int i=0;i<numids;i++){
1505  int master_lid = this->nodes->common_send_ids[rank][i];
1506  Node* vertex=xDynamicCast<Node*>(this->nodes->GetObjectByOffset(master_lid));
1507  _assert_(!vertex->clone);
1508  buffer[i] = local_vector[vertex->lid];
1509  }
1510  ISSM_MPI_Send(buffer,numids,ISSM_MPI_DOUBLE,rank,0,IssmComm::GetComm());
1511  }
1512  }
1513  for(int rank=0;rank<num_procs;rank++){
1514  if(this->nodes->common_recv[rank]){
1515  int numids = this->nodes->common_recv[rank];
1516  ISSM_MPI_Recv(buffer,numids,ISSM_MPI_DOUBLE,rank,0,IssmComm::GetComm(),&status);
1517  for(int i=0;i<numids;i++){
1518  int master_lid = this->nodes->common_recv_ids[rank][i];
1519  Node* vertex=xDynamicCast<Node*>(this->nodes->GetObjectByOffset(master_lid));
1520  _assert_(vertex->clone);
1521  local_vector[vertex->lid] = buffer[i];
1522  }
1523  }
1524  }
1525  xDelete<IssmDouble>(buffer);
1526 
1527  /*Assign output pointer*/
1528  *plocal_vector = local_vector;
1529 }/*}}}*/
1530 void FemModel::GroundedAreax(IssmDouble* pV, bool scaled){/*{{{*/
1531 
1532  IssmDouble local_grounded_area= 0;
1533  IssmDouble total_grounded_area;
1534 
1535  for(int i=0;i<this->elements->Size();i++){
1536  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
1537  local_grounded_area+=element->GroundedArea(scaled);
1538  }
1539  ISSM_MPI_Reduce(&local_grounded_area,&total_grounded_area,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
1540  ISSM_MPI_Bcast(&total_grounded_area,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
1541 
1542  /*Assign output pointers: */
1543  *pV=total_grounded_area;
1544 
1545 }/*}}}*/
1547 
1548  int numvertices = 6;
1549  int numbasins;
1550  IssmDouble* BasinId = xNew<IssmDouble>(numvertices);
1552  IssmDouble* basin_icefront_area = xNewZeroInit<IssmDouble>(numbasins);
1553 
1554  for(int basin=1;basin<numbasins+1;basin++){
1555  IssmDouble local_icefront_area = 0;
1556  IssmDouble total_icefront_area;
1557 
1558  for(int i=0;i<this->elements->Size();i++){
1559  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
1561  for(int j=0;j<numvertices;j++){
1562  if(BasinId[j]==basin){
1563  local_icefront_area+=element->GetIcefrontArea();
1564  break;
1565  }
1566  }
1567  }
1568  ISSM_MPI_Reduce(&local_icefront_area,&total_icefront_area,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm());
1569  ISSM_MPI_Bcast(&total_icefront_area,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
1570 
1571  basin_icefront_area[basin-1]=total_icefront_area;
1572  }
1573 
1574  this->parameters->AddObject(new DoubleVecParam(FrontalForcingsBasinIcefrontAreaEnum,basin_icefront_area,numbasins));
1575 
1576  xDelete<IssmDouble>(basin_icefront_area);
1577  xDelete<IssmDouble>(BasinId);
1578 }/*}}}*/
1579 void FemModel::IcefrontMassFluxx(IssmDouble* pM, bool scaled){/*{{{*/
1580 
1581  IssmDouble local_mass_flux = 0;
1582  IssmDouble total_mass_flux;
1583 
1584  for(int i=0;i<this->elements->Size();i++){
1585  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
1586  local_mass_flux+=element->IcefrontMassFlux(scaled);
1587  }
1588  ISSM_MPI_Reduce(&local_mass_flux,&total_mass_flux,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
1589  ISSM_MPI_Bcast(&total_mass_flux,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
1590 
1591  /*Assign output pointers: */
1592  *pM=total_mass_flux;
1593 
1594 }/*}}}*/
1595 void FemModel::IcefrontMassFluxLevelsetx(IssmDouble* pM, bool scaled){/*{{{*/
1596 
1597  IssmDouble local_mass_flux = 0;
1598  IssmDouble total_mass_flux;
1599 
1600  for(int i=0;i<this->elements->Size();i++){
1601  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
1602  local_mass_flux+=element->IcefrontMassFluxLevelset(scaled);
1603  }
1604  ISSM_MPI_Reduce(&local_mass_flux,&total_mass_flux,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
1605  ISSM_MPI_Bcast(&total_mass_flux,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
1606 
1607  /*Assign output pointers: */
1608  *pM=total_mass_flux;
1609 
1610 }/*}}}*/
1611 void FemModel::InputMakeDiscontinuous(int enum_in){/*{{{*/
1612 
1613  int numvertices = 6;
1614  IssmDouble* P1DGlist = xNew<IssmDouble>(numvertices);
1615 
1616  for(int i=0;i<this->elements->Size();i++){
1617  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
1618  element->GetInputListOnVertices(P1DGlist,enum_in);
1619  element->AddInput2(DummyEnum,P1DGlist,P1DGEnum);
1620  }
1621  xDelete<IssmDouble>(P1DGlist);
1622 
1623  this->inputs2->ChangeEnum(DummyEnum,enum_in);
1624  this->inputs2->DeleteInput(DummyEnum);
1625 
1626 }/*}}}*/
1627 void FemModel::GroundinglineMassFluxx(IssmDouble* pM, bool scaled){/*{{{*/
1628 
1629  /*First we need to depth average the velocities*/
1630  int domaintype;
1631  this->parameters->FindParam(&domaintype,DomainTypeEnum);
1634  depthaverage_core(this);
1635  if(domaintype!=Domain2DverticalEnum){
1638  depthaverage_core(this);
1639  }
1640 
1641  IssmDouble local_mass_flux = 0;
1642  IssmDouble total_mass_flux;
1643 
1644  for(int i=0;i<this->elements->Size();i++){
1645  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
1646  local_mass_flux+=element->GroundinglineMassFlux(scaled);
1647  }
1648  ISSM_MPI_Reduce(&local_mass_flux,&total_mass_flux,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
1649  ISSM_MPI_Bcast(&total_mass_flux,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
1650 
1651  /*Assign output pointers: */
1652  *pM=total_mass_flux;
1653 
1654 }/*}}}*/
1655 void FemModel::IceMassx(IssmDouble* pM, bool scaled){/*{{{*/
1656 
1657  IssmDouble local_ice_mass = 0;
1658  IssmDouble total_ice_mass;
1659 
1660  for(int i=0;i<this->elements->Size();i++){
1661  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
1662  local_ice_mass+=element->IceMass(scaled);
1663  }
1664  ISSM_MPI_Reduce(&local_ice_mass,&total_ice_mass,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
1665  ISSM_MPI_Bcast(&total_ice_mass,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
1666 
1667  /*Assign output pointers: */
1668  *pM=total_ice_mass;
1669 
1670 }/*}}}*/
1671 void FemModel::IceVolumeAboveFloatationx(IssmDouble* pV, bool scaled){/*{{{*/
1672 
1673  IssmDouble local_ice_volume_af = 0;
1674  IssmDouble total_ice_volume_af;
1675 
1676  for(int i=0;i<this->elements->Size();i++){
1677  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
1678  local_ice_volume_af+=element->IceVolumeAboveFloatation(scaled);
1679  }
1680  ISSM_MPI_Reduce(&local_ice_volume_af,&total_ice_volume_af,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
1681  ISSM_MPI_Bcast(&total_ice_volume_af,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
1682 
1683  /*Assign output pointers: */
1684  *pV=total_ice_volume_af;
1685 
1686 }/*}}}*/
1687 void FemModel::IceVolumex(IssmDouble* pV, bool scaled){/*{{{*/
1688 
1689  IssmDouble local_ice_volume = 0;
1690  IssmDouble total_ice_volume;
1691 
1692  for(int i=0;i<this->elements->Size();i++){
1693  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
1694  local_ice_volume+=element->IceVolume(scaled);
1695  }
1696  ISSM_MPI_Reduce(&local_ice_volume,&total_ice_volume,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
1697  ISSM_MPI_Bcast(&total_ice_volume,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
1698 
1699  /*Assign output pointers: */
1700  *pV=total_ice_volume;
1701 
1702 }/*}}}*/
1703 void FemModel::MassFluxx(IssmDouble* pmass_flux){/*{{{*/
1704 
1705  int i,j;
1706  Element *element = NULL;
1707  int element_id;
1708  bool ispresent = false;
1709  IssmDouble mass_flux = 0;
1710  IssmDouble all_mass_flux = 0;
1711  int counter;
1712  IssmDouble **array = NULL;
1713  int M;
1714  int *mdims_array = NULL;
1715  int *ndims_array = NULL;
1716  IssmDouble *segments = NULL;
1717  int num_segments;
1718 
1719  /*First, figure out which segment to compute our mass flux on. Start with retrieving qmu_mass_flux_segments: */
1721  if(!ispresent)_error_("no mass flux segments available!");
1722  this->parameters->FindParam(&array,&M,&mdims_array,&ndims_array,MassFluxSegmentsEnum);
1723 
1724  /*Retrieve index of segments being used for MassFlux computation: */
1725  parameters->FindParam(&counter,IndexEnum);
1726 
1727  /*retrieve segments from array: */
1728  segments = array[counter-1]; //matlab to "C" indexing
1729  num_segments = mdims_array[counter-1];
1730 
1731  /*Go through segments, and then elements, and figure out which elements belong to a segment.
1732  * When we find one, use the element to compute the mass flux on the segment: */
1733  for(i=0;i<num_segments;i++){
1734  element_id=reCast<int,IssmDouble>(*(segments+5*i+4));
1735  for(j=0;j<elements->Size();j++){
1736  element=(Element*)this->elements->GetObjectByOffset(j);
1737  if (element->Id()==element_id){
1738  /*We found the element which owns this segment, use it to compute the mass flux: */
1739  mass_flux+=element->MassFlux(segments+5*i+0);
1740  break;
1741  }
1742  }
1743  }
1744 
1745  ISSM_MPI_Allreduce ( (void*)&mass_flux,(void*)&all_mass_flux,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,IssmComm::GetComm());
1746  mass_flux=all_mass_flux;
1747 
1748  /*Free ressources:*/
1749  for(i=0;i<M;i++){
1750  IssmDouble* matrix=array[i];
1751  xDelete<IssmDouble>(matrix);
1752  }
1753  xDelete<int>(mdims_array);
1754  xDelete<int>(ndims_array);
1755  xDelete<IssmDouble*>(array);
1756 
1757  /*Assign output pointers: */
1758  *pmass_flux=mass_flux;
1759 
1760 }/*}}}*/
1761 void FemModel::MaxAbsVxx(IssmDouble* pmaxabsvx){/*{{{*/
1762 
1763  int i;
1764  IssmDouble maxabsvx;
1765  IssmDouble node_maxabsvx;
1766  IssmDouble element_maxabsvx;
1767 
1768  /*Go through elements, and request velocity: */
1769  maxabsvx=-INFINITY;
1770  for(i=0;i<this->elements->Size();i++){
1771  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
1772  Input2* input = element->GetInput2(VxEnum);
1773  element_maxabsvx=input->GetInputMaxAbs();
1774  if(element_maxabsvx>maxabsvx) maxabsvx=element_maxabsvx;
1775  }
1776 
1777  /*Figure out maximum across the cluster: */
1778  ISSM_MPI_Reduce(&maxabsvx,&node_maxabsvx,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
1779  ISSM_MPI_Bcast(&node_maxabsvx,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
1780  maxabsvx=node_maxabsvx;
1781 
1782  /*Assign output pointers:*/
1783  *pmaxabsvx=maxabsvx;
1784 
1785 }/*}}}*/
1786 void FemModel::MaxAbsVyx(IssmDouble* pmaxabsvy){/*{{{*/
1787 
1788  int i;
1789  IssmDouble maxabsvy;
1790  IssmDouble node_maxabsvy;
1791  IssmDouble element_maxabsvy;
1792 
1793  /*Go through elements, and request velocity: */
1794  maxabsvy=-INFINITY;
1795  for(i=0;i<this->elements->Size();i++){
1796  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
1797  Input2* input = element->GetInput2(VyEnum);
1798  element_maxabsvy=input->GetInputMaxAbs();
1799  if(element_maxabsvy>maxabsvy) maxabsvy=element_maxabsvy;
1800  }
1801 
1802  /*Figure out maximum across the cluster: */
1803  ISSM_MPI_Reduce(&maxabsvy,&node_maxabsvy,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
1804  ISSM_MPI_Bcast(&node_maxabsvy,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
1805  maxabsvy=node_maxabsvy;
1806 
1807  /*Assign output pointers:*/
1808  *pmaxabsvy=maxabsvy;
1809 
1810 }/*}}}*/
1811 void FemModel::MaxAbsVzx(IssmDouble* pmaxabsvz){/*{{{*/
1812 
1813  int i;
1814  IssmDouble maxabsvz;
1815  IssmDouble node_maxabsvz;
1816  IssmDouble element_maxabsvz;
1817 
1818  /*Go through elements, and request velocity: */
1819  maxabsvz=-INFINITY;
1820  for(i=0;i<this->elements->Size();i++){
1821  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
1822  Input2* input = element->GetInput2(VzEnum);
1823  element_maxabsvz=input->GetInputMaxAbs();
1824  if(element_maxabsvz>maxabsvz) maxabsvz=element_maxabsvz;
1825  }
1826 
1827  /*Figure out maximum across the cluster: */
1828  ISSM_MPI_Reduce(&maxabsvz,&node_maxabsvz,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
1829  ISSM_MPI_Bcast(&node_maxabsvz,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
1830  maxabsvz=node_maxabsvz;
1831 
1832  /*Assign output pointers:*/
1833  *pmaxabsvz=maxabsvz;
1834 
1835 }/*}}}*/
1837 
1838  IssmDouble local_divergence;
1839  IssmDouble node_max_divergence;
1840  IssmDouble max_divergence = -INFINITY;
1841 
1842  for(int i=0;i<this->elements->Size();i++){
1843  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
1844  local_divergence=element->Divergence();
1845  if(fabs(local_divergence)>max_divergence) max_divergence=fabs(local_divergence);
1846  }
1847  ISSM_MPI_Reduce(&max_divergence,&node_max_divergence,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
1848  ISSM_MPI_Bcast(&node_max_divergence,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
1849  max_divergence=node_max_divergence;
1850 
1851  /*Assign output pointers: */
1852  *pdiv=max_divergence;
1853 
1854 }/*}}}*/
1855 void FemModel::MaxVelx(IssmDouble* pmaxvel){/*{{{*/
1856 
1857  int i;
1858  IssmDouble maxvel;
1859  IssmDouble node_maxvel;
1860  IssmDouble element_maxvel;
1861 
1862  /*Go through elements, and request velocity: */
1863  maxvel=-INFINITY;
1864  for(i=0;i<this->elements->Size();i++){
1865  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
1866  Input2* vel_input = element->GetInput2(VelEnum); _assert_(vel_input);
1867  element_maxvel = vel_input->GetInputMax();
1868  if(element_maxvel>maxvel) maxvel=element_maxvel;
1869  }
1870 
1871  /*Figure out maximum across the cluster: */
1872  ISSM_MPI_Reduce(&maxvel,&node_maxvel,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
1873  ISSM_MPI_Bcast(&node_maxvel,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
1874  maxvel=node_maxvel;
1875 
1876  /*Assign output pointers:*/
1877  *pmaxvel=maxvel;
1878 
1879 }/*}}}*/
1880 void FemModel::MaxVxx(IssmDouble* pmaxvx){/*{{{*/
1881 
1882  int i;
1883  IssmDouble maxvx;
1884  IssmDouble node_maxvx;
1885  IssmDouble element_maxvx;
1886 
1887  /*Go through elements, and request velocity: */
1888  maxvx=-INFINITY;
1889  for(i=0;i<this->elements->Size();i++){
1890  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
1891  Input2* vx_input = element->GetInput2(VxEnum); _assert_(vx_input);
1892  element_maxvx = vx_input->GetInputMax();
1893  if(element_maxvx>maxvx) maxvx=element_maxvx;
1894  }
1895 
1896  /*Figure out maximum across the cluster: */
1899  maxvx=node_maxvx;
1900 
1901  /*Assign output pointers:*/
1902  *pmaxvx=maxvx;
1903 
1904 }/*}}}*/
1905 void FemModel::MaxVyx(IssmDouble* pmaxvy){/*{{{*/
1906 
1907  int i;
1908  IssmDouble maxvy;
1909  IssmDouble node_maxvy;
1910  IssmDouble element_maxvy;
1911 
1912  /*Go through elements, and request velocity: */
1913  maxvy=-INFINITY;
1914  for(i=0;i<this->elements->Size();i++){
1915  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
1916  Input2* vy_input = element->GetInput2(VyEnum); _assert_(vy_input);
1917  element_maxvy = vy_input->GetInputMax();
1918  if(element_maxvy>maxvy) maxvy=element_maxvy;
1919  }
1920 
1921  /*Figure out maximum across the cluster: */
1924  maxvy=node_maxvy;
1925 
1926  /*Assign output pointers:*/
1927  *pmaxvy=maxvy;
1928 
1929 }/*}}}*/
1930 void FemModel::MaxVzx(IssmDouble* pmaxvz){/*{{{*/
1931 
1932  int i;
1933  IssmDouble maxvz;
1934  IssmDouble node_maxvz;
1935  IssmDouble element_maxvz;
1936 
1937  /*Go through elements, and request velocity: */
1938  maxvz=-INFINITY;
1939  for(i=0;i<this->elements->Size();i++){
1940  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
1941  Input2* vz_input = element->GetInput2(VzEnum); _assert_(vz_input);
1942  element_maxvz = vz_input->GetInputMax();
1943  if(element_maxvz>maxvz) maxvz=element_maxvz;
1944  }
1945 
1946  /*Figure out maximum across the cluster: */
1949  maxvz=node_maxvz;
1950 
1951  /*Assign output pointers:*/
1952  *pmaxvz=maxvz;
1953 
1954 }/*}}}*/
1955 void FemModel::MinVelx(IssmDouble* pminvel){/*{{{*/
1956 
1957  int i;
1958  IssmDouble minvel;
1959  IssmDouble node_minvel;
1960  IssmDouble element_minvel;
1961 
1962  /*Go through elements, and request velocity: */
1963  minvel=INFINITY;
1964  for(i=0;i<this->elements->Size();i++){
1965  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
1966  Input2* input = element->GetInput2(VelEnum);
1967  element_minvel =input->GetInputMin();
1968  if(element_minvel<minvel) minvel=element_minvel;
1969  }
1970 
1971  /*Figure out minimum across the cluster: */
1972  ISSM_MPI_Reduce(&minvel,&node_minvel,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() );
1973  ISSM_MPI_Bcast(&node_minvel,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
1974  minvel=node_minvel;
1975 
1976  /*Assign output pointers:*/
1977  *pminvel=minvel;
1978 
1979 }/*}}}*/
1980 void FemModel::MinVxx(IssmDouble* pminvx){/*{{{*/
1981 
1982  int i;
1983  IssmDouble minvx;
1984  IssmDouble node_minvx;
1985  IssmDouble element_minvx;
1986 
1987  /*Go through elements, and request velocity: */
1988  minvx=INFINITY;
1989  for(i=0;i<this->elements->Size();i++){
1990  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
1991  Input2* input = element->GetInput2(VxEnum);
1992  element_minvx =input->GetInputMin();
1993  if(element_minvx<minvx) minvx=element_minvx;
1994  }
1995 
1996  /*Figure out minimum across the cluster: */
1999  minvx=node_minvx;
2000 
2001  /*Assign output pointers:*/
2002  *pminvx=minvx;
2003 
2004 }/*}}}*/
2005 void FemModel::MinVyx(IssmDouble* pminvy){/*{{{*/
2006 
2007  int i;
2008  IssmDouble minvy;
2009  IssmDouble node_minvy;
2010  IssmDouble element_minvy;
2011 
2012  /*Go through elements, and request velocity: */
2013  minvy=INFINITY;
2014  for(i=0;i<this->elements->Size();i++){
2015  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
2016  Input2* input = element->GetInput2(VyEnum);
2017  element_minvy =input->GetInputMin();
2018  if(element_minvy<minvy) minvy=element_minvy;
2019  }
2020 
2021  /*Figure out minimum across the cluster: */
2024  minvy=node_minvy;
2025 
2026  /*Assign output pointers:*/
2027  *pminvy=minvy;
2028 
2029 }/*}}}*/
2030 void FemModel::MinVzx(IssmDouble* pminvz){/*{{{*/
2031 
2032  int i;
2033  IssmDouble minvz;
2034  IssmDouble node_minvz;
2035  IssmDouble element_minvz;
2036 
2037  /*Go through elements, and request velocity: */
2038  minvz=INFINITY;
2039  for(i=0;i<this->elements->Size();i++){
2040  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
2041  Input2* input = element->GetInput2(VzEnum);
2042  element_minvz =input->GetInputMin();
2043  if(element_minvz<minvz) minvz=element_minvz;
2044  }
2045 
2046  /*Figure out minimum across the cluster: */
2049  minvz=node_minvz;
2050 
2051  /*Assign output pointers:*/
2052  *pminvz=minvz;
2053 
2054 }/*}}}*/
2056 
2057  /*output: */
2058  IssmDouble J=0.;
2059  IssmDouble J_sum;
2060 
2061  IssmDouble omega,weight;
2062  IssmDouble Jdet;
2063  IssmDouble* xyz_list = NULL;
2064  IssmDouble dp[3];
2065 
2066  /*Compute Misfit: */
2067  for(int i=0;i<elements->Size();i++){
2068  Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
2069 
2070  /*If on water, return 0: */
2071  if(!element->IsIceInElement()) continue;
2072 
2073  /* Get node coordinates*/
2074  element->GetVerticesCoordinates(&xyz_list);
2075 
2076  /*Retrieve all inputs we will be needing: */
2077  DatasetInput2* weights_input = element->GetDatasetInput2(InversionCostFunctionsCoefficientsEnum); _assert_(weights_input);
2078  Input2* omega_input = element->GetInput2(BalancethicknessOmegaEnum); _assert_(omega_input);
2079 
2080  /* Start looping on the number of gaussian points: */
2081  Gauss* gauss=element->NewGauss(2);
2082  for(int ig=gauss->begin();ig<gauss->end();ig++){
2083 
2084  gauss->GaussPoint(ig);
2085 
2086  /* Get Jacobian determinant: */
2087  element->JacobianDeterminant(&Jdet,xyz_list,gauss);
2088 
2089  /*Get all parameters at gaussian point*/
2090  weights_input->GetInputValue(&weight,gauss,OmegaAbsGradientEnum);
2091  omega_input->GetInputDerivativeValue(&dp[0],xyz_list,gauss);
2092 
2093  /*Tikhonov regularization: J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */
2094  //J+=weight*1/2*(dp[0]*dp[0]+dp[1]*dp[1])*Jdet*gauss->weight;
2095  J+=weight*1/2*pow(dp[0]*dp[0]+dp[1]*dp[1],2)*Jdet*gauss->weight;
2096  }
2097 
2098  /*clean up and Return: */
2099  xDelete<IssmDouble>(xyz_list);
2100  delete gauss;
2101  }
2102 
2103  /*Sum all J from all cpus of the cluster:*/
2106  J=J_sum;
2107 
2108  /*Assign output pointers: */
2109  *pJ=J;
2110 }
2111 /*}}}*/
2112 void FemModel::EtaDiffx( IssmDouble* pJ){/*{{{*/
2113 
2114  /*output: */
2115  IssmDouble J=0.;
2116  IssmDouble J_sum;
2117 
2118  IssmDouble omega,weight;
2119  IssmDouble Jdet;
2120  IssmDouble* xyz_list = NULL;
2121  IssmDouble p,p0;
2122 
2123  /*Compute Misfit: */
2124  for(int i=0;i<elements->Size();i++){
2125  Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
2126 
2127  /*If on water, return 0: */
2128  if(!element->IsIceInElement()) continue;
2129 
2130  /* Get node coordinates*/
2131  element->GetVerticesCoordinates(&xyz_list);
2132 
2133  /*Retrieve all inputs we will be needing: */
2134  DatasetInput2* weights_input =element->GetDatasetInput2(InversionCostFunctionsCoefficientsEnum); _assert_(weights_input);
2135  Input2* omega_input =element->GetInput2(BalancethicknessOmegaEnum); _assert_(omega_input);
2136  Input2* omega0_input =element->GetInput2(BalancethicknessOmega0Enum); _assert_(omega0_input);
2137 
2138  /* Start looping on the number of gaussian points: */
2139  Gauss* gauss=element->NewGauss(2);
2140  for(int ig=gauss->begin();ig<gauss->end();ig++){
2141 
2142  gauss->GaussPoint(ig);
2143 
2144  /* Get Jacobian determinant: */
2145  element->JacobianDeterminant(&Jdet,xyz_list,gauss);
2146 
2147  /*Get all parameters at gaussian point*/
2148  weights_input->GetInputValue(&weight,gauss,EtaDiffEnum);
2149  omega_input->GetInputValue(&p,gauss);
2150  omega0_input->GetInputValue(&p0,gauss);
2151 
2152  /*Tikhonov regularization: J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */
2153  //J+=weight*1/2*(dp[0]*dp[0]+dp[1]*dp[1])*Jdet*gauss->weight;
2154  J+=weight*1/2*pow(p - p0,2)*Jdet*gauss->weight;
2155  }
2156 
2157  /*clean up and Return: */
2158  xDelete<IssmDouble>(xyz_list);
2159  delete gauss;
2160  }
2161 
2162  /*Sum all J from all cpus of the cluster:*/
2165  J=J_sum;
2166 
2167  /*Assign output pointers: */
2168  *pJ=J;
2169 }
2170 /*}}}*/
2171 void FemModel::OutputControlsx(Results **presults){/*{{{*/
2172 
2173  /*parameters: */
2174  int num_controls,step;
2175  IssmDouble time;
2176  int *control_type = NULL;
2177 
2178  /*recover results*/
2179  Results* results = *presults;
2180  if(!results) results = new Results();
2181 
2182  /*Get list of Controls*/
2184  this->parameters->FindParam(&control_type,NULL,InversionControlParametersEnum);
2185  this->parameters->FindParam(&step,StepEnum);
2186  this->parameters->FindParam(&time,TimeEnum);
2187 
2188  for(int i=0;i<num_controls;i++){
2189 
2190  int control_enum = control_type[i];
2191  int gradient_enum;
2192 
2193  switch(i){
2194  case 0: gradient_enum = Gradient1Enum; break;
2195  case 1: gradient_enum = Gradient2Enum; break;
2196  case 2: gradient_enum = Gradient3Enum; break;
2197  default: _error_("more than 3 controls not implemented yet");
2198  }
2199 
2200  /*Allocate vector*/
2201  Vector<IssmPDouble> *vector_control = new Vector<IssmPDouble>(this->vertices->NumberOfVertices());
2202  Vector<IssmPDouble> *vector_gradient = new Vector<IssmPDouble>(this->vertices->NumberOfVertices());
2203 
2204  /*Fill in vector*/
2205  for(int j=0;j<elements->Size();j++){
2206  Element* element=(Element*)elements->GetObjectByOffset(j);
2207  element->ControlToVectors(vector_control,vector_gradient,control_enum);
2208  }
2209  vector_control->Assemble();
2210  vector_gradient->Assemble();
2211 
2212  results->AddResult(new GenericExternalResult<Vector<IssmPDouble>*>(results->Size()+1,control_enum,vector_control ,step,time));
2213  results->AddResult(new GenericExternalResult<Vector<IssmPDouble>*>(results->Size()+1,gradient_enum,vector_gradient,step,time));
2214  }
2215 
2216  /*Clean up and return*/
2217  xDelete<int>(control_type);
2218 }
2219 /*}}}*/
2221 
2222  bool isautodiff = false;
2223  IssmDouble output_value;
2224 
2225  int num_dependents;
2226  IssmPDouble *dependents;
2227  DataSet* dependent_objects=NULL;
2228  int my_rank=IssmComm::GetRank();
2229 
2230  /*AD mode on?: */
2232 
2233  if(isautodiff){
2234  #ifdef _HAVE_AD_
2236  parameters->FindParam(&dependent_objects,AutodiffDependentObjectsEnum);
2237  if(num_dependents){
2238  dependents=xNew<IssmPDouble>(num_dependents);
2239 
2240  #if defined(_HAVE_CODIPACK_)
2241  auto& tape_codi = IssmDouble::getGlobalTape();
2242  #endif
2243 
2244  /*Go through our dependent variables, and compute the response:*/
2245  for(int i=0;i<dependent_objects->Size();i++){
2246  DependentObject* dep=(DependentObject*)dependent_objects->GetObjectByOffset(i);
2247  dep->Responsex(&output_value,this);
2248  if (my_rank==0) {
2249  #if defined(_HAVE_CODIPACK_)
2250  tape_codi.registerOutput(output_value);
2251  dependents[i] = output_value.getValue();
2252  codi_global.output_indices.push_back(output_value.getGradientData());
2253  #else
2254  output_value>>=dependents[i];
2255  #endif
2256  }
2257  }
2258  }
2259  delete dependent_objects;
2260  if(num_dependents)xDelete<IssmPDouble>(dependents);
2261  #else
2262  _error_("Should not be requesting dependents when an AD library is not available!");
2263  #endif
2264  }
2265 }
2266 /*}}}*/
2267 void FemModel::RequestedOutputsx(Results **presults,char** requested_outputs, int numoutputs, bool save_results){/*{{{*/
2268 
2269  /*Intermediaries*/
2270  bool isvec,results_on_nodes;
2271  int step,output_enum,numonnodes;
2272  IssmDouble time;
2273  IssmDouble double_result;
2274  const char *output_string = NULL;
2275  char** resultsonnodes = NULL;
2276 
2277  /*recover results*/
2278  Results* results = *presults;
2279  if(!results) results = new Results();
2280 
2281  /*Get time and step*/
2282  parameters->FindParam(&step,StepEnum);
2283  parameters->FindParam(&time,TimeEnum);
2285  if(numonnodes) parameters->FindParam(&resultsonnodes,&numonnodes,SettingsResultsOnNodesEnum);
2286 
2287 
2288  /*Go through all requested output*/
2289  for(int i=0;i<numoutputs;i++){
2290  output_string = requested_outputs[i];
2291  output_enum = StringToEnumx(output_string,false);
2292  isvec = false;
2293 
2294 
2295  /*If string is not an enum, it is defined in output definitions*/
2296  if(output_enum<0){
2297  double_result = OutputDefinitionsResponsex(this,output_string);
2298  if(save_results){
2299  results->AddResult(new GenericExternalResult<IssmPDouble>(results->Size()+1,output_string,reCast<IssmPDouble>(double_result),step,time));
2300  continue;
2301  }
2302  }
2303  else{
2304  /*last chance for the output definition, if the enum is one of Outputdefinition[1-10]Enum:*/
2305  if(output_enum>=Outputdefinition1Enum && output_enum <=Outputdefinition100Enum){
2306  double_result = OutputDefinitionsResponsex(this,output_enum);
2307  if(save_results){
2308  results->AddResult(new GenericExternalResult<IssmPDouble>(results->Size()+1,output_string,reCast<IssmPDouble>(double_result),step,time));
2309  continue;
2310  }
2311  }
2312  else{
2313  switch(output_enum){
2314 
2315  /*Scalar output*/
2316  case DivergenceEnum: this->Divergencex(&double_result); break;
2317  case MaxDivergenceEnum: this->MaxDivergencex(&double_result); break;
2318  case IceMassEnum: this->IceMassx(&double_result,false); break;
2319  case IcefrontMassFluxEnum: this->IcefrontMassFluxx(&double_result,false); break;
2320  case IcefrontMassFluxLevelsetEnum: this->IcefrontMassFluxLevelsetx(&double_result,false); break;
2321  case IceMassScaledEnum: this->IceMassx(&double_result,true); break;
2322  case IceVolumeEnum: this->IceVolumex(&double_result,false); break;
2323  case IceVolumeScaledEnum: this->IceVolumex(&double_result,true); break;
2324  case IceVolumeAboveFloatationEnum: this->IceVolumeAboveFloatationx(&double_result,false); break;
2325  case IceVolumeAboveFloatationScaledEnum: this->IceVolumeAboveFloatationx(&double_result,true); break;
2326  case GroundedAreaEnum: this->GroundedAreax(&double_result,false); break;
2327  case GroundedAreaScaledEnum: this->GroundedAreax(&double_result,true); break;
2328  case GroundinglineMassFluxEnum: this->GroundinglineMassFluxx(&double_result,false); break;
2329  case FloatingAreaEnum: this->FloatingAreax(&double_result,false); break;
2330  case FloatingAreaScaledEnum: this->FloatingAreax(&double_result,true); break;
2331  case MinVelEnum: this->MinVelx(&double_result); break;
2332  case MaxVelEnum: this->MaxVelx(&double_result); break;
2333  case MinVxEnum: this->MinVxx(&double_result); break;
2334  case MaxVxEnum: this->MaxVxx(&double_result); break;
2335  case MaxAbsVxEnum: this->MaxAbsVxx(&double_result); break;
2336  case MinVyEnum: this->MinVyx(&double_result); break;
2337  case MaxVyEnum: this->MaxVyx(&double_result); break;
2338  case MaxAbsVyEnum: this->MaxAbsVyx(&double_result); break;
2339  case MinVzEnum: this->MinVzx(&double_result); break;
2340  case MaxVzEnum: this->MaxVzx(&double_result); break;
2341  case MaxAbsVzEnum: this->MaxAbsVzx(&double_result); break;
2342  case MassFluxEnum: this->MassFluxx(&double_result); break;
2343  case TotalCalvingFluxLevelsetEnum: this->TotalCalvingFluxLevelsetx(&double_result,false); break;
2344  case TotalCalvingMeltingFluxLevelsetEnum:this->TotalCalvingMeltingFluxLevelsetx(&double_result,false); break;
2345  case TotalFloatingBmbEnum: this->TotalFloatingBmbx(&double_result,false); break;
2346  case TotalFloatingBmbScaledEnum: this->TotalFloatingBmbx(&double_result,true); break;
2347  case TotalGroundedBmbEnum: this->TotalGroundedBmbx(&double_result,false); break;
2348  case TotalGroundedBmbScaledEnum: this->TotalGroundedBmbx(&double_result,true); break;
2349  case TotalSmbEnum: this->TotalSmbx(&double_result,false); break;
2350  case TotalSmbScaledEnum: this->TotalSmbx(&double_result,true); break;
2351 
2352  /*Scalar control output*/
2357  case SurfaceAverageVelMisfitEnum: SurfaceAverageVelMisfitx(&double_result,this); break;
2359  case ThicknessAbsGradientEnum: this->ThicknessAbsGradientx(&double_result); break;
2362  case ThicknessPositiveEnum: this->ThicknessPositivex(&double_result); break;
2367  case BalancethicknessMisfitEnum: BalancethicknessMisfitx(&double_result); break;
2368  case SurfaceAbsMisfitEnum: SurfaceAbsMisfitx(&double_result); break;
2369  case OmegaAbsGradientEnum: OmegaAbsGradientx(&double_result); break;
2370  case EtaDiffEnum: EtaDiffx(&double_result); break;
2371 
2372  /*Vector special case (maybe should go to specific analysis?)*/
2373  case ChannelAreaEnum:{
2374 
2375  /*Get Number of Channels*/
2376  int numchannels_local=0,numchannels;
2377  for(int j=0;j<this->loads->Size();j++){
2378  if(this->loads->GetEnum(j)==ChannelEnum) numchannels_local++;
2379  }
2380  ISSM_MPI_Reduce(&numchannels_local,&numchannels,1,ISSM_MPI_INT,ISSM_MPI_SUM,0,IssmComm::GetComm() );
2381  ISSM_MPI_Bcast(&numchannels,1,ISSM_MPI_INT,0,IssmComm::GetComm());
2382 
2383  IssmPDouble* values = xNewZeroInit<IssmPDouble>(numchannels);
2384  IssmPDouble* allvalues = xNew<IssmPDouble>(numchannels);
2385 
2386  /*Fill-in vector*/
2387  for(int j=0;j<this->loads->Size();j++){
2388  if(this->loads->GetEnum(j)==ChannelEnum){
2389  Channel* channel=(Channel*)this->loads->GetObjectByOffset(j);
2390  channel->WriteChannelCrossSection(values);
2391  }
2392  }
2393 
2394  /*Gather from all cpus*/
2395  ISSM_MPI_Allreduce((void*)values,(void*)allvalues,numchannels,ISSM_MPI_PDOUBLE,ISSM_MPI_SUM,IssmComm::GetComm());
2396  xDelete<IssmPDouble>(values);
2397 
2398  if(save_results)results->AddResult(new GenericExternalResult<IssmPDouble*>(results->Size()+1,output_enum,allvalues,numchannels,1,step,time));
2399  xDelete<IssmPDouble>(allvalues);
2400 
2401  isvec = true;
2402  }
2403  break;
2404 
2405 
2406  /*Default is always Vector */
2407  default:
2408 
2409  /*Some preliminary calculation may be required (use similar syntax for other inputs)*/
2410  if(output_enum==NewDamageEnum){
2414  }
2415 
2416  /*Vector layout*/
2417  if(!IsInputEnum(output_enum)) _error_("Cannot output \""<<EnumToStringx(output_enum)<<"\" because it is not an input");
2418  int interpolation,nodesperelement,size,nlines,ncols,array_size;
2419  int rank_interpolation=-1,rank_nodesperelement=-1,rank_arraysize=-1,max_rank_arraysize=0;
2420  bool isarray=false;
2421 
2422  /*Get interpolation (and compute input if necessary)*/
2423  for(int j=0;j<elements->Size();j++){
2424  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(j));
2425  element->ResultInterpolation(&rank_interpolation,&rank_nodesperelement,&rank_arraysize,output_enum);
2426  if(rank_arraysize>max_rank_arraysize)max_rank_arraysize=rank_arraysize;
2427  }
2428  rank_arraysize=max_rank_arraysize;
2429 
2430  /*Broadcast for cpus that do not have any elements*/
2431  ISSM_MPI_Reduce(&rank_interpolation,&interpolation,1,ISSM_MPI_INT,ISSM_MPI_MAX,0,IssmComm::GetComm());
2432  ISSM_MPI_Reduce(&rank_nodesperelement,&nodesperelement,1,ISSM_MPI_INT,ISSM_MPI_MAX,0,IssmComm::GetComm());
2433  ISSM_MPI_Reduce(&rank_arraysize,&array_size,1,ISSM_MPI_INT,ISSM_MPI_MAX,0,IssmComm::GetComm());
2434  ISSM_MPI_Bcast(&interpolation,1,ISSM_MPI_INT,0,IssmComm::GetComm());
2435  ISSM_MPI_Bcast(&nodesperelement,1,ISSM_MPI_INT,0,IssmComm::GetComm());
2436  ISSM_MPI_Bcast(&array_size,1,ISSM_MPI_INT,0,IssmComm::GetComm());
2437 
2438  results_on_nodes=false;
2439  /*Loop to see if this output was requested on nodes*/
2440  for(int j=0;j<numonnodes & results_on_nodes==false;j++){
2441  if(strcmp(resultsonnodes[j],output_string) == 0 || strcmp(resultsonnodes[j],"all") == 0) results_on_nodes=true;
2442  }
2443 
2444  if(results_on_nodes){
2445 
2446  /*Allocate matrices*/
2447  int nbe = this->elements->NumberOfElements();
2448  IssmDouble* values = xNewZeroInit<IssmDouble>(nbe*nodesperelement);
2449  IssmDouble* allvalues = xNew<IssmDouble>(nbe*nodesperelement);
2450 
2451  /*Fill-in matrix*/
2452  for(int j=0;j<elements->Size();j++){
2453  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(j));
2454  element->ResultToPatch(values,nodesperelement,output_enum);
2455  }
2456 
2457  /*Gather from all cpus*/
2458  ISSM_MPI_Allreduce((void*)values,(void*)allvalues,nbe*nodesperelement,ISSM_MPI_PDOUBLE,ISSM_MPI_SUM,IssmComm::GetComm());
2459  xDelete<IssmDouble>(values);
2460 
2461  if(save_results)results->AddResult(new GenericExternalResult<IssmDouble*>(results->Size()+1,output_enum,allvalues,nbe,nodesperelement,step,time));
2462  xDelete<IssmDouble>(allvalues);
2463 
2464  }
2465  else{
2466 
2467  /*Allocate vector depending on interpolation*/
2468  switch(interpolation){
2469  case P0Enum: isarray = false; size = this->elements->NumberOfElements(); break;
2470  case P1Enum: isarray = false; size = this->vertices->NumberOfVertices(); break;
2471  case P0ArrayEnum: isarray = true; nlines = this->elements->NumberOfElements(); ncols= array_size; break;
2472  default: _error_("Interpolation "<<EnumToStringx(interpolation)<<" not supported yet");
2473 
2474  }
2475  if(!isarray){
2476  Vector<IssmDouble> *vector_result = new Vector<IssmDouble>(size);
2477 
2478  /*Fill in vector*/
2479  for(int j=0;j<elements->Size();j++){
2480  Element* element=(Element*)elements->GetObjectByOffset(j);
2481  element->ResultToVector(vector_result,output_enum);
2482  }
2483  vector_result->Assemble();
2484 
2485  if(save_results){
2486  results->AddResult(new GenericExternalResult<Vector<IssmDouble>*>(results->Size()+1,output_enum,vector_result,step,time));
2487  /*We do not do a copy for Vectors, so don't delete*/
2488  }
2489  else{
2490  delete vector_result;
2491  }
2492  }
2493  else{
2494  IssmDouble* values = xNewZeroInit<IssmDouble>(nlines*ncols);
2495  IssmDouble* allvalues = xNew<IssmDouble>(nlines*ncols);
2496 
2497  /*Fill-in matrix*/
2498  for(int j=0;j<elements->Size();j++){
2499  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(j));
2500  element->ResultToMatrix(values,ncols,output_enum);
2501  }
2502  /*Gather from all cpus*/
2503  ISSM_MPI_Allreduce((void*)values,(void*)allvalues,ncols*nlines,ISSM_MPI_PDOUBLE,ISSM_MPI_SUM,IssmComm::GetComm());
2504  xDelete<IssmDouble>(values);
2505 
2506  if(save_results)results->AddResult(new GenericExternalResult<IssmDouble*>(results->Size()+1,output_enum,allvalues,nlines,ncols,step,time));
2507  xDelete<IssmDouble>(allvalues);
2508  }
2509  }
2510  isvec = true;
2511  break;
2512  }
2513  }
2514 
2515  }
2516 
2517  /*Add result to Results*/
2518  if(!isvec && save_results){
2519  results->AddResult(new GenericExternalResult<IssmPDouble>(results->Size()+1,output_string,reCast<IssmPDouble>(double_result),step,time));
2520  }
2521  }
2522 
2523  /*Clean up*/
2524  for(int i=0;i<numonnodes;i++) xDelete<char>(resultsonnodes[i]);
2525  xDelete<char*>(resultsonnodes);
2526 
2527  /*Assign pointer and clean up*/
2528  *presults = results;
2529 }
2530 /*}}}*/
2531 void FemModel::RequestedOutputsx(Results **presults,int* requested_outputs, int numoutputs,bool save_results){/*{{{*/
2532 
2533  /*Convert list of enums to list of string*/
2534  char** enumlist = xNew<char*>(numoutputs);
2535  for(int i=0;i<numoutputs;i++) EnumToStringx(&enumlist[i],requested_outputs[i]);
2536 
2537  /*Call main module*/
2538  this->RequestedOutputsx(presults,enumlist,numoutputs,save_results);
2539 
2540  /*clean up and return*/
2541  for(int i=0;i<numoutputs;i++) xDelete<char>(enumlist[i]);
2542  xDelete<char*>(enumlist);
2543 }
2544 /*}}}*/
2545 void FemModel::ResetLevelset(void){/*{{{*/
2546 
2548 
2549 }
2550 /*}}}*/
2551 void FemModel::Responsex(IssmDouble* responses,const char* response_descriptor){/*{{{*/
2552 
2553  int response_descriptor_enum=StringToEnumx(response_descriptor);
2554  this->Responsex(responses, response_descriptor_enum);
2555 
2556 }
2557 /*}}}*/
2558 void FemModel::Responsex(IssmDouble* responses,int response_descriptor_enum){/*{{{*/
2559 
2560  switch (response_descriptor_enum){
2561 
2562  case DivergenceEnum: this->Divergencex(responses); break;
2563  case MaxDivergenceEnum: this->MaxDivergencex(responses); break;
2564  case IceMassEnum: this->IceMassx(responses, false); break;
2565  case IceMassScaledEnum: this->IceMassx(responses, true); break;
2566  case IceVolumeEnum: this->IceVolumex(responses, false); break;
2567  case IceVolumeScaledEnum: this->IceVolumex(responses, true); break;
2568  case IceVolumeAboveFloatationEnum: this->IceVolumeAboveFloatationx(responses, false); break;
2569  case IceVolumeAboveFloatationScaledEnum: this->IceVolumeAboveFloatationx(responses, true); break;
2570  case IcefrontMassFluxEnum: this->IcefrontMassFluxx(responses, false); break;
2571  case IcefrontMassFluxLevelsetEnum: this->IcefrontMassFluxLevelsetx(responses, false); break;
2572  case GroundedAreaEnum: this->GroundedAreax(responses, false); break;
2573  case GroundedAreaScaledEnum: this->GroundedAreax(responses, true); break;
2574  case FloatingAreaEnum: this->FloatingAreax(responses, false); break;
2575  case FloatingAreaScaledEnum: this->FloatingAreax(responses, true); break;
2576  case MinVelEnum: this->MinVelx(responses); break;
2577  case MaxVelEnum: this->MaxVelx(responses); break;
2578  case MinVxEnum: this->MinVxx(responses); break;
2579  case MaxVxEnum: this->MaxVxx(responses); break;
2580  case MaxAbsVxEnum: this->MaxAbsVxx(responses); break;
2581  case MinVyEnum: this->MinVyx(responses); break;
2582  case MaxVyEnum: this->MaxVyx(responses); break;
2583  case MaxAbsVyEnum: this->MaxAbsVyx(responses); break;
2584  case MinVzEnum: this->MinVzx(responses); break;
2585  case MaxVzEnum: this->MaxVzx(responses); break;
2586  case MaxAbsVzEnum: this->MaxAbsVzx(responses); break;
2587  case MassFluxEnum: this->MassFluxx(responses); break;
2592  case SurfaceAverageVelMisfitEnum: SurfaceAverageVelMisfitx(responses,this); break;
2594  case ThicknessAbsGradientEnum: this->ThicknessAbsGradientx(responses); break;
2599  case BalancethicknessMisfitEnum: BalancethicknessMisfitx(responses); break;
2600  case TotalCalvingFluxLevelsetEnum: this->TotalCalvingFluxLevelsetx(responses, false); break;
2601  case TotalCalvingMeltingFluxLevelsetEnum:this->TotalCalvingMeltingFluxLevelsetx(responses, false); break;
2602  case TotalFloatingBmbEnum: this->TotalFloatingBmbx(responses, false); break;
2603  case TotalFloatingBmbScaledEnum: this->TotalFloatingBmbx(responses, true); break;
2604  case TotalGroundedBmbEnum: this->TotalGroundedBmbx(responses, false); break;
2605  case TotalGroundedBmbScaledEnum: this->TotalGroundedBmbx(responses, true); break;
2606  case TotalSmbEnum: this->TotalSmbx(responses, false); break;
2607  case TotalSmbScaledEnum: this->TotalSmbx(responses, true); break;
2609  case VelEnum: this->ElementResponsex(responses,VelEnum); break;
2611  default:
2612  if(response_descriptor_enum>=Outputdefinition1Enum && response_descriptor_enum <=Outputdefinition100Enum){
2613  IssmDouble double_result = OutputDefinitionsResponsex(this,response_descriptor_enum);
2614  *responses=double_result;
2615  }
2616  else _error_("response descriptor \"" << EnumToStringx(response_descriptor_enum) << "\" not supported yet!");
2617  break;
2618  }
2619 
2620 }
2621 /*}}}*/
2623 
2624  for(int i=0;i<elements->Size();i++){
2625  Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
2626  element->RignotMeltParameterization();
2627  }
2628 }
2629 /*}}}*/
2631 
2632  for(int i=0;i<elements->Size();i++){
2633  Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
2634  element->StrainRateparallel();
2635  }
2636 }
2637 /*}}}*/
2639 
2640  for(int i=0;i<elements->Size();i++){
2641  Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
2642  element->StrainRateperpendicular();
2643  }
2644 }
2645 /*}}}*/
2647 
2648  for(int i=0;i<elements->Size();i++){
2649  Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
2650  element->ComputeStrainRate();
2651  }
2652 }
2653 /*}}}*/
2655 
2656  /*Update input for basal element only*/
2657  for(int i=0;i<elements->Size();i++){
2658  Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i));
2659  element->StressIntensityFactor();
2660  }
2661 }
2662  /*}}}*/
2663 void FemModel::SurfaceAbsMisfitx(IssmDouble* presponse){/*{{{*/
2664 
2665  /*output: */
2666  IssmDouble J=0.;
2667  IssmDouble J_sum;
2668 
2669  IssmDouble surface,surfaceobs,weight;
2670  IssmDouble Jdet;
2671  IssmDouble* xyz_list = NULL;
2672 
2673  /*Compute Misfit: */
2674  for(int i=0;i<elements->Size();i++){
2675  Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
2676 
2677  /*If on water, return 0: */
2678  if(!element->IsIceInElement()) continue;
2679 
2680  /* Get node coordinates*/
2681  element->GetVerticesCoordinates(&xyz_list);
2682 
2683  /*Retrieve all inputs we will be needing: */
2684  DatasetInput2* weights_input =element->GetDatasetInput2(InversionCostFunctionsCoefficientsEnum); _assert_(weights_input);
2685  Input2* surface_input =element->GetInput2(SurfaceEnum); _assert_(surface_input);
2686  Input2* surfaceobs_input=element->GetInput2(InversionSurfaceObsEnum); _assert_(surfaceobs_input);
2687 
2688  /* Start looping on the number of gaussian points: */
2689  Gauss* gauss=element->NewGauss(2);
2690  for(int ig=gauss->begin();ig<gauss->end();ig++){
2691 
2692  gauss->GaussPoint(ig);
2693 
2694  /* Get Jacobian determinant: */
2695  element->JacobianDeterminant(&Jdet,xyz_list,gauss);
2696 
2697  /*Get all parameters at gaussian point*/
2698  weights_input->GetInputValue(&weight,gauss,SurfaceAbsMisfitEnum);
2699  surface_input->GetInputValue(&surface,gauss);
2700  surfaceobs_input->GetInputValue(&surfaceobs,gauss);
2701 
2702  /*Compute SurfaceAbsMisfitEnum*/
2703  J+=0.5*(surface-surfaceobs)*(surface-surfaceobs)*weight*Jdet*gauss->weight;
2704  }
2705  delete gauss;
2706  xDelete<IssmDouble>(xyz_list);
2707  }
2708 
2709  /*Sum all J from all cpus of the cluster:*/
2712  J=J_sum;
2713 
2714  /*Assign output pointers: */
2715  *presponse=J;
2716 
2717 }/*}}}*/
2719 
2720  /*output: */
2721  IssmDouble J=0.;
2722  IssmDouble J_sum;
2723 
2724  IssmDouble thickness,weight;
2725  IssmDouble Jdet;
2726  IssmDouble* xyz_list = NULL;
2727  IssmDouble dp[3];
2728 
2729  /*Compute Misfit: */
2730  for(int i=0;i<elements->Size();i++){
2731  Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
2732 
2733  /*If on water, return 0: */
2734  if(!element->IsIceInElement()) continue;
2735 
2736  /* Get node coordinates*/
2737  element->GetVerticesCoordinates(&xyz_list);
2738 
2739  /*Retrieve all inputs we will be needing: */
2740  DatasetInput2* weights_input =element->GetDatasetInput2(InversionCostFunctionsCoefficientsEnum); _assert_(weights_input);
2741  Input2* thickness_input =element->GetInput2(ThicknessEnum); _assert_(thickness_input);
2742 
2743  /* Start looping on the number of gaussian points: */
2744  Gauss* gauss=element->NewGauss(2);
2745  for(int ig=gauss->begin();ig<gauss->end();ig++){
2746 
2747  gauss->GaussPoint(ig);
2748 
2749  /* Get Jacobian determinant: */
2750  element->JacobianDeterminant(&Jdet,xyz_list,gauss);
2751 
2752  /*Get all parameters at gaussian point*/
2753  weights_input->GetInputValue(&weight,gauss,ThicknessAbsGradientEnum);
2754  thickness_input->GetInputDerivativeValue(&dp[0],xyz_list,gauss);
2755 
2756  /*Tikhonov regularization: J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */
2757  J+=weight*1/2*(dp[0]*dp[0]+dp[1]*dp[1])*Jdet*gauss->weight;
2758  }
2759 
2760  /*clean up and Return: */
2761  xDelete<IssmDouble>(xyz_list);
2762  delete gauss;
2763  }
2764 
2765  /*Sum all J from all cpus of the cluster:*/
2768  J=J_sum;
2769 
2770  /*Assign output pointers: */
2771  *pJ=J;
2772 }
2773 /*}}}*/
2775 
2776  int elementswidth = this->GetElementsWidth();//just 2D mesh, tria elements
2777  int numberofvertices = this->vertices->NumberOfVertices();//total number of vertices
2778 
2779  IssmDouble weight = 0.;
2780  IssmDouble* totalweight = NULL;
2781  IssmDouble* Hserial = NULL;
2782  IssmDouble* H = xNew<IssmDouble>(elementswidth);
2783  Vector<IssmDouble>* vecH = new Vector<IssmDouble>(numberofvertices);
2784  Vector<IssmDouble>* vectotalweight = new Vector<IssmDouble>(numberofvertices);
2785 
2786  for(int i=0;i<this->elements->Size();i++){
2787  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
2788 
2789  /*check if there is ice in this element*/
2790  if(!element->IsIceInElement()) continue;
2791 
2792  /*get H on the vertices*/
2794 
2795  /*weight to calculate the smoothed H*/
2796  weight=1.;//simple average
2797 
2798  /*add in the serial vector*/
2799  vecH->SetValue(element->vertices[0]->Sid(),weight*H[0],ADD_VAL);
2800  vecH->SetValue(element->vertices[1]->Sid(),weight*H[1],ADD_VAL);
2801  vecH->SetValue(element->vertices[2]->Sid(),weight*H[2],ADD_VAL);
2802  /*total weight*/
2803  vectotalweight->SetValue(element->vertices[0]->Sid(),weight,ADD_VAL);
2804  vectotalweight->SetValue(element->vertices[1]->Sid(),weight,ADD_VAL);
2805  vectotalweight->SetValue(element->vertices[2]->Sid(),weight,ADD_VAL);
2806  }
2807 
2808  /*Assemble and serialize*/
2809  vecH->Assemble();
2810  vectotalweight->Assemble();
2811  Hserial=vecH->ToMPISerial();
2812  totalweight=vectotalweight->ToMPISerial();
2813 
2814  /*Divide for the total weight*/
2815  for(int i=0;i<numberofvertices;i++){
2816  _assert_(totalweight[i]>0);
2817  Hserial[i]=Hserial[i]/totalweight[i];
2818  }
2819 
2820  /*Set element inputs*/
2821  for(int i=0;i<this->elements->Size();i++){
2822  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
2823  H[0]=Hserial[element->vertices[0]->Sid()];
2824  H[1]=Hserial[element->vertices[1]->Sid()];
2825  H[2]=Hserial[element->vertices[2]->Sid()];
2826  element->AddInput2(ThicknessEnum,H,P1Enum);
2827  }
2828 
2829  /*Cleanup*/
2830  delete vecH;
2831  delete vectotalweight;
2832  xDelete<IssmDouble>(H);
2833  xDelete<IssmDouble>(Hserial);
2834  xDelete<IssmDouble>(totalweight);
2835 }
2836 /*}}}*/
2838 
2839  /*output: */
2840  IssmDouble J=0.;
2841  IssmDouble J_sum;
2842 
2843  IssmDouble thickness,weight;
2844  IssmDouble Jdet;
2845  IssmDouble* xyz_list = NULL;
2846  IssmDouble H;
2847 
2848  /*Compute Misfit: */
2849  for(int i=0;i<elements->Size();i++){
2850  Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
2851 
2852  /*If on water, return 0: */
2853  if(!element->IsIceInElement()) continue;
2854 
2855  /* Get node coordinates*/
2856  element->GetVerticesCoordinates(&xyz_list);
2857 
2858  /*Retrieve all inputs we will be needing: */
2859  DatasetInput2* weights_input =element->GetDatasetInput2(InversionCostFunctionsCoefficientsEnum); _assert_(weights_input);
2860  Input2* thickness_input =element->GetInput2(ThicknessEnum); _assert_(thickness_input);
2861 
2862  /* Start looping on the number of gaussian points: */
2863  Gauss* gauss=element->NewGauss(2);
2864  for(int ig=gauss->begin();ig<gauss->end();ig++){
2865 
2866  gauss->GaussPoint(ig);
2867 
2868  /* Get Jacobian determinant: */
2869  element->JacobianDeterminant(&Jdet,xyz_list,gauss);
2870 
2871  /*Get all parameters at gaussian point*/
2872  weights_input->GetInputValue(&weight,gauss,ThicknessPositiveEnum);
2873  thickness_input->GetInputValue(&H,gauss);
2874 
2875  /*int min(H,0)^2 */
2876  if(H<=0){
2877  J+=weight*H*H*Jdet*gauss->weight;
2878  }
2879  }
2880 
2881  /*clean up and Return: */
2882  xDelete<IssmDouble>(xyz_list);
2883  delete gauss;
2884  }
2885 
2886  /*Sum all J from all cpus of the cluster:*/
2889  J=J_sum;
2890 
2891  /*Assign output pointers: */
2892  *pJ=J;
2893 }
2894 /*}}}*/
2896 
2897  /*output: */
2898  IssmDouble dt;
2899 
2900  /*intermediary: */
2901  IssmDouble min_dt = 0;
2902  IssmDouble node_min_dt = 0;
2903 
2904  /*Go through elements, and figure out the minimum of the time steps for each element (using CFL criterion): */
2905  Element* element=(Element*)elements->GetObjectByOffset(0); min_dt=element->TimeAdapt();
2906 
2907  for(int i=1;i<elements->Size();i++){
2908  element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
2909  dt=element->TimeAdapt();
2910  if(dt<min_dt)min_dt=dt;
2911  }
2912 
2913  /*Figure out minimum across the cluster: */
2914  ISSM_MPI_Reduce (&min_dt,&node_min_dt,1,ISSM_MPI_DOUBLE,ISSM_MPI_MIN,0,IssmComm::GetComm() );
2915  ISSM_MPI_Bcast(&node_min_dt,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
2916  min_dt=node_min_dt;
2917 
2918  /*Constrain dt */
2919  IssmDouble dt_low,dt_high;
2922  if(min_dt<dt_low) min_dt = dt_low;
2923  if(min_dt>dt_high) min_dt = dt_high;
2924 
2925  /*Assign output pointers:*/
2926  *pdt=min_dt;
2927 }
2928 /*}}}*/
2929 void FemModel::TotalCalvingFluxLevelsetx(IssmDouble* pM, bool scaled){/*{{{*/
2930 
2931  IssmDouble local_calving_flux = 0;
2932  IssmDouble total_calving_flux;
2933 
2934  for(int i=0;i<this->elements->Size();i++){
2935  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
2936  local_calving_flux+=element->TotalCalvingFluxLevelset(scaled);
2937  }
2938  ISSM_MPI_Reduce(&local_calving_flux,&total_calving_flux,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
2939  ISSM_MPI_Bcast(&total_calving_flux,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
2940 
2941  /*Assign output pointers: */
2942  *pM=total_calving_flux;
2943 
2944 }/*}}}*/
2946 
2947  IssmDouble local_calving_flux = 0;
2948  IssmDouble total_calving_flux;
2949 
2950  for(int i=0;i<this->elements->Size();i++){
2951  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
2952  local_calving_flux+=element->TotalCalvingMeltingFluxLevelset(scaled);
2953  }
2954  ISSM_MPI_Reduce(&local_calving_flux,&total_calving_flux,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
2955  ISSM_MPI_Bcast(&total_calving_flux,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
2956 
2957  /*Assign output pointers: */
2958  *pM=total_calving_flux;
2959 
2960 }/*}}}*/
2961 void FemModel::TotalFloatingBmbx(IssmDouble* pFbmb, bool scaled){/*{{{*/
2962 
2963  IssmDouble local_fbmb = 0;
2964  IssmDouble total_fbmb;
2965 
2966  for(int i=0;i<this->elements->Size();i++){
2967  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
2968  local_fbmb+=element->TotalFloatingBmb(scaled);
2969  }
2970  ISSM_MPI_Reduce(&local_fbmb,&total_fbmb,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
2972 
2973  /*Assign output pointers: */
2974  *pFbmb=total_fbmb;
2975 
2976 }/*}}}*/
2977 void FemModel::TotalGroundedBmbx(IssmDouble* pGbmb, bool scaled){/*{{{*/
2978 
2979  IssmDouble local_gbmb = 0;
2980  IssmDouble total_gbmb;
2981 
2982  for(int i=0;i<this->elements->Size();i++){
2983  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
2984  local_gbmb+=element->TotalGroundedBmb(scaled);
2985  }
2986  ISSM_MPI_Reduce(&local_gbmb,&total_gbmb,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
2988 
2989  /*Assign output pointers: */
2990  *pGbmb=total_gbmb;
2991 
2992 }/*}}}*/
2993 void FemModel::TotalSmbx(IssmDouble* pSmb, bool scaled){/*{{{*/
2994 
2995  IssmDouble local_smb = 0;
2996  IssmDouble total_smb;
2997 
2998  for(int i=0;i<this->elements->Size();i++){
2999  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
3000  local_smb+=element->TotalSmb(scaled);
3001  }
3002  ISSM_MPI_Reduce(&local_smb,&total_smb,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
3004 
3005  /*Assign output pointers: */
3006  *pSmb=total_smb;
3007 
3008 }/*}}}*/
3010 
3011  for(int i=0;i<elements->Size();i++){
3012  Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
3014  }
3015 
3016 }
3017 /*}}}*/
3019 
3020  for(int i=0;i<elements->Size();i++){
3021  Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
3023  }
3024 
3025 }
3026 /*}}}*/
3027 void FemModel::UpdateConstraintsx(void){ /*{{{*/
3028 
3029  IssmDouble time;
3030  int analysis_type,config_type;
3031 
3032  /*retrieve parameters: */
3033  parameters->FindParam(&analysis_type,AnalysisTypeEnum);
3035  parameters->FindParam(&time,TimeEnum);
3036 
3037  int index=AnalysisIndex(config_type);
3038  _assert_(this->analysis_type_list[index]==config_type);
3039 
3040  /*start module: */
3041  if(VerboseModule()) _printf0_(" Updating constraints and active domain of analysis " << EnumToStringx(analysis_type) << " for time: " << time << "\n");
3042 
3043  Analysis* analysis= EnumToAnalysis(analysis_type);
3044  analysis->UpdateConstraints(this);
3045  delete analysis;
3046 
3047  /*Second, constraints might be time dependent: */
3049 
3050  /*Now, update degrees of freedoms: */
3052 
3053 }
3054 /*}}}*/
3056 
3057  IssmDouble *surface = NULL;
3058  IssmDouble *bed = NULL;
3059 
3060  if(VerboseSolution()) _printf0_(" updating vertices positions\n");
3061 
3062  /*get vertex vectors for bed and thickness: */
3065 
3066  /*Allocate vector*/
3067  int numvert = vertices->NumberOfVertices();
3068  int numvert_local = vertices->NumberOfVerticesLocal();
3069  Vector<IssmDouble> *vx=new Vector<IssmDouble>(numvert_local,numvert);
3070  Vector<IssmDouble> *vy=new Vector<IssmDouble>(numvert_local,numvert);
3071  Vector<IssmDouble> *vz=new Vector<IssmDouble>(numvert_local,numvert);
3072 
3073  /*Update verices new geometry: */
3074  for(int i=0;i<vertices->Size();i++){
3075  Vertex* vertex=(Vertex*)vertices->GetObjectByOffset(i);
3076  vertex->UpdatePosition(vx,vy,vz,parameters,surface,bed);
3077  }
3078 
3079  /*Assemble mesh velocity*/
3080  vx->Assemble();
3081  vy->Assemble();
3082  vz->Assemble();
3083 
3084  /*Update element inputs*/
3088 
3089  /*Free ressources:*/
3090  delete vx;
3091  delete vy;
3092  delete vz;
3093  xDelete<IssmDouble>(bed);
3094  xDelete<IssmDouble>(surface);
3095  return 1;
3096 }
3097 /*}}}*/
3098 
3099 /*AMR*/
3100 #ifndef _HAVE_AD_
3101 void FemModel::ReMesh(void){/*{{{*/
3102 
3103  /*Intermediaries*/
3104  IssmDouble *newx = NULL;
3105  IssmDouble *newy = NULL;
3106  IssmDouble *newz = NULL;
3107  int *newelementslist = NULL;
3108  int newnumberofvertices = -1;
3109  int newnumberofelements = -1;
3110 
3111  int elementswidth = this->GetElementsWidth();//just tria elements in this version
3112  int amrtype,basalforcing_model;
3113  bool isgroundingline;
3114 
3115  /*Branch to specific amr depending on requested method*/
3116  this->parameters->FindParam(&amrtype,AmrTypeEnum);
3117  switch(amrtype){
3118  #if defined(_HAVE_NEOPZ_) && !defined(_HAVE_AD_)
3119  case AmrNeopzEnum: this->ReMeshNeopz(&newnumberofvertices,&newnumberofelements,&newx,&newy,&newz,&newelementslist); break;
3120  #endif
3121 
3122  #if defined(_HAVE_BAMG_) && !defined(_HAVE_AD_)
3123  case AmrBamgEnum: this->ReMeshBamg(&newnumberofvertices,&newnumberofelements,&newx,&newy,&newz,&newelementslist); break;
3124  #endif
3125 
3126  default: _error_("not implemented yet");
3127  }
3128 
3129  /*Create iomodel for model processing*/
3130  IoModel* iomodel = new IoModel();
3131  this->parameters->FindParam(&iomodel->domaintype,DomainTypeEnum);
3134  iomodel->numberofvertices = newnumberofvertices;
3135  iomodel->numberofelements = newnumberofelements;
3136  iomodel->elements = newelementslist;
3137  iomodel->AddConstant(new IoConstant(0,"md.rifts.numrifts"));
3138  iomodel->AddConstant(new IoConstant(false,"md.transient.isoceancoupling"));
3139  bool temp; int tempint;
3140  this->parameters->FindParam(&temp,FlowequationIsSIAEnum); iomodel->AddConstant(new IoConstant(temp,"md.flowequation.isSIA"));
3141  this->parameters->FindParam(&temp,FlowequationIsSSAEnum); iomodel->AddConstant(new IoConstant(temp,"md.flowequation.isSSA"));
3142  this->parameters->FindParam(&temp,FlowequationIsL1L2Enum); iomodel->AddConstant(new IoConstant(temp,"md.flowequation.isL1L2"));
3143  this->parameters->FindParam(&temp,FlowequationIsHOEnum); iomodel->AddConstant(new IoConstant(temp,"md.flowequation.isHO"));
3144  this->parameters->FindParam(&temp,FlowequationIsFSEnum); iomodel->AddConstant(new IoConstant(temp,"md.flowequation.isFS"));
3145  this->parameters->FindParam(&tempint,MasstransportStabilizationEnum); iomodel->AddConstant(new IoConstant(tempint,"md.masstransport.stabilization"));
3146  iomodel->AddConstant(new IoConstant(P1Enum,"md.flowequation.fe_SSA"));
3147 
3148  /*Partitioning the new mesh. Maybe ElementsAndVerticesPartitioning.cpp could be modified to set this without iomodel.*/
3150 
3151  /*Creating elements*/
3152  /*Just Tria in this version*/
3153  Elements* new_elements=new Elements();
3154  this->CreateElements(newnumberofelements,elementswidth,newelementslist,iomodel->my_elements,new_elements);
3155 
3156  /*Create vertices*/
3157  Vertices* new_vertices=new Vertices();
3159  ::CreateVertices(new_elements,new_vertices,iomodel,TransientSolutionEnum,true);
3160  for(int i=0;i<new_vertices->Size();i++){
3161  Vertex *vertex=(Vertex*)new_vertices->GetObjectByOffset(i);
3162  int sid = vertex->Sid();
3163  vertex->x=newx[sid];
3164  vertex->y=newy[sid];
3165  vertex->z=newz[sid];
3166  }
3167 
3168  /*Creating inputs*/
3169  Inputs2* new_inputs2=new Inputs2(newnumberofelements,newnumberofvertices);
3170 
3171  /*Creating materials*/
3172  Materials* new_materials=new Materials();
3173  this->CreateMaterials(newnumberofelements,iomodel->my_elements,new_materials);
3174 
3175  /*Creating nodes and constraints*/
3176  /*Just SSA (2D) and P1 in this version*/
3177  Constraints **new_constraints_list = xNew<Constraints*>(this->nummodels);
3178  Nodes **new_nodes_list = xNew<Nodes*>(this->nummodels);
3179 
3180  this->analysis_counter=-1;
3181  for(int i=0;i<this->nummodels;i++){//create nodes for each analysis in analysis_type_list
3182 
3183  int analysis_enum = this->analysis_type_list[i];
3184  if(VerboseMProcessor()) _printf0_(" creating datasets for analysis " << EnumToStringx(analysis_enum) << "\n");
3185 
3186  if(this->loads_list[i]->Size()!=0) _error_("not supported yet");
3187  new_constraints_list[i] = new Constraints();
3188  new_nodes_list[i] = new Nodes();
3189 
3190  /*As the domain is 2D, it is not necessary to create nodes for this analysis*/
3191  if(analysis_enum==StressbalanceVerticalAnalysisEnum) continue;
3192  Analysis* analysis = EnumToAnalysis(analysis_enum);
3193  analysis->CreateNodes(new_nodes_list[i],iomodel,true);
3194  delete analysis;
3195  this->UpdateElements(newnumberofelements,newelementslist,iomodel->my_elements,i,new_elements);
3196  this->CreateConstraints(new_vertices,analysis_enum,new_constraints_list[i]);
3197 
3198  new_constraints_list[i]->Presort();
3199  new_nodes_list[i]->Presort();
3200  }
3201 
3202  new_elements->Presort();
3203  new_vertices->Presort();
3204  //this->loads->Presort();
3205  new_materials->Presort();
3206 
3207  /*reset hooks*/
3208  new_elements->ResetHooks();
3209  //this->loads->ResetHooks();
3210  new_materials->ResetHooks();
3211 
3212  /*do the post-processing of the datasets to get an FemModel that can actually run analyses: */
3213  int analysis_type;
3214  for(int i=0;i<this->nummodels;i++){
3215  analysis_type=this->analysis_type_list[i];
3216  SetCurrentConfiguration(analysis_type);
3217 
3218  this->analysis_counter=i;
3219  /*Now, plug analysis_counter and analysis_type inside the parameters: */
3221  this->parameters->SetParam(analysis_type,AnalysisTypeEnum);
3222  this->parameters->SetParam(analysis_type,ConfigurationTypeEnum);
3223 
3224  /*configure elements, loads and nodes, for this new analysis: */
3225  new_elements->SetCurrentConfiguration(new_elements,this->loads,new_nodes_list[i],new_vertices,new_materials,this->parameters);
3226  this->loads->SetCurrentConfiguration(new_elements,this->loads,new_nodes_list[i],new_vertices,new_materials,this->parameters);
3227 
3228  /*take care of toolkits options, that depend on this analysis type (present only after model processor)*/
3230  ToolkitsOptionsFromAnalysis(this->parameters,analysis_type);
3231  if(VerboseSolver()) _printf0_(" toolkits Options set for analysis type: " << EnumToStringx(analysis_type) << "\n");
3232  }
3233 
3234  ConfigureObjectsx(new_elements,this->loads,new_nodes_list[i],new_vertices,new_materials,this->parameters,new_inputs2);
3235  SpcNodesx(new_nodes_list[i],new_constraints_list[i],this->parameters);
3236  NodesDofx(new_nodes_list[i],this->parameters);
3237  }
3238 
3239  /*Interpolate all inputs and insert them into the new elements.*/
3240  this->InterpolateInputs(new_vertices,new_elements,new_inputs2);
3241 
3242  /*Delete old structure and set new pointers*/
3243  delete this->inputs2; this->inputs2 = new_inputs2;
3244  delete this->vertices; this->vertices = new_vertices;
3245  delete this->elements; this->elements = new_elements;
3246  delete this->materials; this->materials = new_materials;
3247  if(this->constraints_list && this->nummodels){
3248  for(int i=0;i<this->nummodels;i++) delete this->constraints_list[i];
3249  xDelete<Constraints*>(this->constraints_list);
3250  }
3251  this->constraints_list= new_constraints_list;
3252  if(this->nodes_list && this->nummodels){
3253  for(int i=0;i<this->nummodels;i++) delete this->nodes_list[i];
3254  xDelete<Nodes*>(this->nodes_list);
3255  }
3256  this->nodes_list = new_nodes_list;
3257 
3258  /*Reset mask*/
3260 
3261  /*Insert MISMIP+ bed topography FIXME it could be stay in another place*/
3262  this->parameters->FindParam(&basalforcing_model,BasalforcingsEnum);
3263  if(basalforcing_model==MismipFloatingMeltRateEnum) this->BedrockFromMismipPlus();
3264 
3265  /*Adjust base, thickness and mask grounded ice leve set*/
3266  this->parameters->FindParam(&isgroundingline,TransientIsgroundinglineEnum);
3267  if(isgroundingline) this->AdjustBaseThicknessAndMask();
3268 
3269  /*Reset current configuration: */
3270  analysis_type=this->analysis_type_list[this->analysis_counter];
3271  SetCurrentConfiguration(analysis_type);
3272 
3273  /*Set the new mesh*/
3274  this->SetMesh(&newelementslist,&newx,&newy,&newnumberofvertices,&newnumberofelements);
3275 
3276  /*Cleanup*/
3277  xDelete<IssmDouble>(newz);
3278  /*Delete iomodel, but make sure to not erase some pointers*/
3279  iomodel->elements = NULL;
3280  delete iomodel;
3281 }
3282 /*}}}*/
3284 
3285  /*Insert bedrock from mismip+ setup*/
3286  /*This was used to Misomip project/simulations*/
3287 
3288  if(VerboseSolution())_printf0_(" call Mismip bedrock adjust module\n");
3289 
3290  IssmDouble x,y,bx,by;
3291  int numvertices = this->GetElementsWidth();
3292  IssmDouble* xyz_list = NULL;
3293  IssmDouble* r = xNew<IssmDouble>(numvertices);
3294 
3295  for(int el=0;el<this->elements->Size();el++){
3296  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(el));
3297  element->GetVerticesCoordinates(&xyz_list);
3298  for(int i=0;i<numvertices;i++){
3299  x = xyz_list[3*i+0];
3300  y = xyz_list[3*i+1];
3301  bx = -150.-728.8*pow(x/300000.,2)+343.91*pow(x/300000.,4)-50.57*pow(x/300000.,6);
3302  by = 500./(1.+exp((-2./4000.)*(y-80000./2.-24000.)))+500./(1.+exp((2./4000.)*(y-80000./2.+24000.)));
3303  r[i] = max(bx+by,-720.);
3304  }
3305  /*insert new bedrock*/
3306  element->AddInput2(BedEnum,&r[0],P1Enum);
3307  /*Cleanup*/
3308  xDelete<IssmDouble>(xyz_list);
3309  }
3310  /*Delete*/
3311  xDelete<IssmDouble>(r);
3312 }
3313 /*}}}*/
3315 
3316  if(VerboseSolution())_printf0_(" call adjust base and thickness module\n");
3317 
3318  int numvertices = this->GetElementsWidth();
3319  IssmDouble rho_water,rho_ice,density,base_float;
3320  IssmDouble* phi = xNew<IssmDouble>(numvertices);
3321  IssmDouble* h = xNew<IssmDouble>(numvertices);
3322  IssmDouble* s = xNew<IssmDouble>(numvertices);
3323  IssmDouble* b = xNew<IssmDouble>(numvertices);
3324  IssmDouble* r = xNew<IssmDouble>(numvertices);
3325  IssmDouble* sl = xNew<IssmDouble>(numvertices);
3326 
3327  for(int el=0;el<this->elements->Size();el++){
3328  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(el));
3329 
3330  element->GetInputListOnVertices(&s[0],SurfaceEnum);
3331  element->GetInputListOnVertices(&r[0],BedEnum);
3332  element->GetInputListOnVertices(&sl[0],SealevelEnum);
3333  rho_water = element->FindParam(MaterialsRhoSeawaterEnum);
3334  rho_ice = element->FindParam(MaterialsRhoIceEnum);
3335  density = rho_ice/rho_water;
3336 
3337  for(int i=0;i<numvertices;i++){
3338  /*calculate base floatation (which supports given surface*/
3339  base_float = rho_ice*s[i]/(rho_ice-rho_water);
3340  if(r[i]>base_float){
3341  b[i] = r[i];
3342  }
3343  else {
3344  b[i] = base_float;
3345  }
3346 
3347  if(fabs(sl[i])>0) _error_("Sea level value "<<sl[i]<<" not supported!");
3348  /*update thickness and mask grounded ice level set*/
3349  h[i] = s[i]-b[i];
3350  phi[i] = h[i]+r[i]/density;
3351  }
3352 
3353  /*Update inputs*/
3354  element->AddInput2(MaskOceanLevelsetEnum,&phi[0],P1Enum);
3355  element->AddInput2(ThicknessEnum,&h[0],P1Enum);
3356  element->AddInput2(BaseEnum,&b[0],P1Enum);
3357  }
3358 
3359  /*Delete*/
3360  xDelete<IssmDouble>(phi);
3361  xDelete<IssmDouble>(h);
3362  xDelete<IssmDouble>(s);
3363  xDelete<IssmDouble>(b);
3364  xDelete<IssmDouble>(r);
3365  xDelete<IssmDouble>(sl);
3366 }
3367 /*}}}*/
3368 void FemModel::GetInputs(int* pnumP0inputs,IssmDouble** pP0inputs,int** pP0input_enums,int** pP0input_interp,int* pnumP1inputs,IssmDouble** pP1inputs,int** pP1input_enums,int** pP1input_interp){/*{{{*/
3369 
3370  int numberofvertices = this->vertices->NumberOfVertices();
3371  int numberofelements = this->elements->NumberOfElements();
3372  int elementswidth = this->GetElementsWidth();
3373  int numinputs,numP0inputs,numP1inputs;
3374  IssmDouble* P0inputs = NULL;
3375  Vector<IssmDouble>* vP0inputs = NULL;
3376  int* P0input_enums = NULL;
3377  int* P0input_interp = NULL;
3378  IssmDouble* P1inputs = NULL;
3379  Vector<IssmDouble>* vP1inputs = NULL;
3380  int* P1input_enums = NULL;
3381  int* P1input_interp = NULL;
3382  int* input_interpolations = NULL;
3383  int* input_enums = NULL;
3384  int* pos = NULL;
3385  IssmDouble value = 0;
3386 
3387  /*Figure out how many inputs we have and their respective interpolation*/
3388  this->inputs2->GetInputsInterpolations(&numinputs,&input_interpolations,&input_enums);
3389 
3390  /*Count and get enums of all inputs in old mesh*/
3391  for(int step=0;step<2;step++){
3392  if(step){
3393  P0input_enums = xNew<int>(numP0inputs);
3394  P0input_interp = xNew<int>(numP0inputs);
3395  P1input_enums = xNew<int>(numP1inputs);
3396  P1input_interp = xNew<int>(numP1inputs);
3397  }
3398  numP0inputs = 0;
3399  numP1inputs = 0;
3400  for(int i=0;i<numinputs;i++){
3401  int inputinterp = input_interpolations[i];
3402  switch(inputinterp){
3403  case 0:
3404  /*Input not found, go to the next*/
3405  break;
3406  case P1Enum:
3407  if(step){
3408  P1input_enums[numP1inputs] = input_enums[i];
3409  P1input_interp[numP1inputs] = inputinterp;
3410  }
3411  numP1inputs++;
3412  break;
3413  case P0Enum:
3414  case IntInput2Enum:
3415  case BoolInput2Enum:
3416  if(step){
3417  P0input_enums[numP0inputs] = input_enums[i];
3418  P0input_interp[numP0inputs] = inputinterp;
3419  }
3420  numP0inputs++;
3421  break;
3422  default:
3423  _error_(EnumToStringx(inputinterp)<<" ("<<inputinterp<<") Not supported yet");
3424  }
3425  }
3426  }
3427 
3428  /*Get P0 and P1 inputs over the elements*/
3429  pos = xNew<int>(elementswidth);
3430  vP0inputs= new Vector<IssmDouble>(numberofelements*numP0inputs);
3431  vP1inputs= new Vector<IssmDouble>(numberofvertices*numP1inputs);
3432  for(int i=0;i<this->elements->Size();i++){
3433  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
3434 
3435  /*Get P0 inputs*/
3436  for(int j=0;j<numP0inputs;j++){
3437  switch(P0input_interp[j]){
3438  case P0Enum:{
3439  Input2* input=element->GetInput2(P0input_enums[j]);
3440  input->GetInputAverage(&value);
3441  }
3442  break;
3443  case IntInput2Enum:{
3444  int valueint;
3445  element->GetInput2Value(&valueint,P0input_enums[j]);
3446  value = reCast<IssmDouble>(valueint);
3447  }
3448  break;
3449  case BoolInput2Enum:{
3450  bool valuebool;
3451  element->GetInput2Value(&valuebool,P0input_enums[j]);
3452  value = reCast<IssmDouble>(valuebool);
3453  }
3454  break;
3455  default:
3456  _error_(EnumToStringx(P0input_interp[j])<<" ("<<P0input_interp[j]<<") Not supported yet");
3457  }
3458  pos[0]=element->Sid()*numP0inputs+j;
3459  /*Insert input in the vector*/
3460  vP0inputs->SetValues(1,pos,&value,INS_VAL);
3461  }
3462 
3463  /*Get P1 inputs*/
3464  for(int j=0;j<numP1inputs;j++){
3465  Input2* temp = element->GetInput2(P1input_enums[j]); _assert_(temp);
3466  ElementInput2* input=xDynamicCast<ElementInput2*>(temp);
3467  pos[0]=element->vertices[0]->Sid()*numP1inputs+j;
3468  pos[1]=element->vertices[1]->Sid()*numP1inputs+j;
3469  pos[2]=element->vertices[2]->Sid()*numP1inputs+j;
3470  /*Insert input in the vector*/
3471  vP1inputs->SetValues(elementswidth,pos,input->element_values,INS_VAL);
3472  }
3473  }
3474 
3475  /*Assemble and serialize*/
3476  vP0inputs->Assemble();
3477  vP1inputs->Assemble();
3478  P0inputs=vP0inputs->ToMPISerial();
3479  P1inputs=vP1inputs->ToMPISerial();
3480 
3481  /*Assign pointers*/
3482  *pnumP0inputs = numP0inputs;
3483  *pP0inputs = P0inputs;
3484  *pP0input_enums = P0input_enums;
3485  *pP0input_interp = P0input_interp;
3486  *pnumP1inputs = numP1inputs;
3487  *pP1inputs = P1inputs;
3488  *pP1input_enums = P1input_enums;
3489  *pP1input_interp = P1input_interp;
3490 
3491  /*Cleanup*/
3492  delete vP0inputs;
3493  delete vP1inputs;
3494  xDelete<int>(input_interpolations);
3495  xDelete<int>(input_enums);
3496  xDelete<int>(pos);
3497 }
3498 /*}}}*/
3499 void FemModel::InterpolateInputs(Vertices* newfemmodel_vertices,Elements* newfemmodel_elements,Inputs2* newinputs2){/*{{{*/
3500 
3501  int numberofelements = -1; //global, entire old mesh
3502  int newnumberofelements = newfemmodel_elements->Size(); //just on the new partition
3503  int numberofvertices = -1; //global, entire old mesh
3504  int newnumberofvertices = newfemmodel_vertices->Size(); //just on the new partition
3505  int elementswidth = this->GetElementsWidth(); //just tria in this version
3506  int numP0inputs = -1;
3507  IssmDouble* P0inputs = NULL; //global, entire old mesh
3508  IssmDouble* newP0inputs = NULL; //just on the new partition
3509  int* P0input_enums = NULL;
3510  int* P0input_interp = NULL;
3511  int numP1inputs = -1;
3512  IssmDouble* P1inputs = NULL; //global, entire old mesh
3513  IssmDouble* newP1inputs = NULL; //just on the new partition
3514  int* P1input_enums = NULL;
3515  int* P1input_interp = NULL;
3516  IssmDouble* values = NULL;
3517  IssmDouble* vector = NULL;
3518  IssmDouble* x = NULL;//global, entire old mesh
3519  IssmDouble* y = NULL;//global, entire old mesh
3520  int* elementslist = NULL;//global, entire old mesh
3521  IssmDouble* newx = NULL;//just on the new partition
3522  IssmDouble* newy = NULL;//just on the new partition
3523  IssmDouble* newz = NULL;//just on the new partition
3524  IssmDouble* newxc = NULL;//just on the new partition
3525  IssmDouble* newyc = NULL;//just on the new partition
3526  int* newelementslist = NULL;//just on the new partition
3527  int* sidtoindex = NULL;//global vertices sid to partition index
3528 
3529  /*Get old P0 and P1 inputs (entire mesh)*/
3530  this->GetInputs(&numP0inputs,&P0inputs,&P0input_enums,&P0input_interp,&numP1inputs,&P1inputs,&P1input_enums,&P1input_interp);
3531 
3532  /*Get the old mesh (global, entire mesh)*/
3533  this->GetMesh(&elementslist,&x,&y,&numberofvertices,&numberofelements);
3534 
3535  /*Get the new mesh (just on the new partition)*/
3536  this->GetMeshOnPartition(newfemmodel_vertices,newfemmodel_elements,&newx,&newy,&newz,&newelementslist,&sidtoindex);
3537 
3538  /*Calculate the center points xc and xy (new mesh, new partition)*/
3539  newxc=xNewZeroInit<IssmDouble>(newnumberofelements);
3540  newyc=xNewZeroInit<IssmDouble>(newnumberofelements);
3541  for(int i=0;i<newnumberofelements;i++){
3542  for(int j=0;j<elementswidth;j++){
3543  int vid = newelementslist[i*elementswidth+j]-1;//Transform to C indexing
3544  newxc[i]+=newx[vid]/elementswidth;
3545  newyc[i]+=newy[vid]/elementswidth;
3546  }
3547  }
3548 
3549  /*Interplate P0 inputs in the new mesh (just on the new partition)*/
3550  InterpFromMeshToMesh2dx(&newP0inputs,elementslist,x,y,numberofvertices,numberofelements,
3551  P0inputs,numberofelements,numP0inputs,
3552  newxc,newyc,newnumberofelements,NULL);
3553 
3554  /*Interpolate P1 inputs in the new mesh (just on the new partition)*/
3555  InterpFromMeshToMesh2dx(&newP1inputs,elementslist,x,y,numberofvertices,numberofelements,
3556  P1inputs,numberofvertices,numP1inputs,
3557  newx,newy,newnumberofvertices,NULL);
3558 
3559  /*Insert P0 and P1 inputs into the new elements (just on the new partition)*/
3560  int vertexlids[3];
3561  values=xNew<IssmDouble>(elementswidth);
3562  for(int i=0;i<newfemmodel_elements->Size();i++){//just on the new partition
3563  Element* element=xDynamicCast<Element*>(newfemmodel_elements->GetObjectByOffset(i));
3564  /*newP0inputs is just on the new partition*/
3565  for(int j=0;j<numP0inputs;j++){
3566  switch(P0input_interp[j]){
3567  case P0Enum:
3568  element->SetElementInput(newinputs2,P0input_enums[j],newP0inputs[i*numP0inputs+j]);
3569  break;
3570  case IntInput2Enum:
3571  element->SetIntInput(newinputs2,P0input_enums[j],reCast<int>(newP0inputs[i*numP0inputs+j]));
3572  break;
3573  case BoolInput2Enum:
3574  element->SetBoolInput(newinputs2,P0input_enums[j],reCast<bool>(newP0inputs[i*numP0inputs+j]));
3575  break;
3576  default:
3577  _error_(EnumToStringx(P0input_interp[j])<<" Not supported yet");
3578  }
3579  }
3580  /*newP1inputs is just on the new partition*/
3581  for(int i=0;i<3;i++) vertexlids[i]=element->vertices[i]->lid;
3582  for(int j=0;j<numP1inputs;j++){
3583  values[0]=newP1inputs[sidtoindex[element->vertices[0]->Sid()]*numP1inputs+j];
3584  values[1]=newP1inputs[sidtoindex[element->vertices[1]->Sid()]*numP1inputs+j];
3585  values[2]=newP1inputs[sidtoindex[element->vertices[2]->Sid()]*numP1inputs+j];
3586  newinputs2->SetTriaInput(P1input_enums[j],P1Enum,3,vertexlids,values);
3587  }
3588  }
3589 
3590 
3591  /*Cleanup*/
3592  xDelete<IssmDouble>(P0inputs);
3593  xDelete<IssmDouble>(newP0inputs);
3594  xDelete<int>(P0input_enums);
3595  xDelete<int>(P0input_interp);
3596  xDelete<IssmDouble>(P1inputs);
3597  xDelete<IssmDouble>(newP1inputs);
3598  xDelete<int>(P1input_enums);
3599  xDelete<int>(P1input_interp);
3600  xDelete<IssmDouble>(newx);
3601  xDelete<IssmDouble>(newy);
3602  xDelete<IssmDouble>(newz);
3603  xDelete<IssmDouble>(newxc);
3604  xDelete<IssmDouble>(newyc);
3605  xDelete<int>(newelementslist);
3606  xDelete<int>(sidtoindex);
3607  xDelete<IssmDouble>(values);
3608 }
3609 /*}}}*/
3611 
3612  /*Write the erros estimators*/
3614 
3615  int step = -1;
3616  int numberofelements = -1;
3617  int numberofvertices = -1;
3618  IssmDouble time = -1;
3619  IssmDouble* x = NULL;
3620  IssmDouble* y = NULL;
3621  int* elementslist = NULL;
3622 
3623  if(!this->elements || !this->vertices || !this->results || !this->parameters) return;
3624 
3625  parameters->FindParam(&step,StepEnum);
3626  parameters->FindParam(&time,TimeEnum);
3627 
3628  /*Get mesh. Elementslist comes in Matlab indexing*/
3629  this->GetMesh(&elementslist,&x,&y,&numberofvertices,&numberofelements);
3630 
3631  /*Write mesh in Results*/
3633  elementslist,numberofelements,this->GetElementsWidth(),step,time));
3634 
3636  x,numberofvertices,1,step,time));
3637 
3639  y,numberofvertices,1,step,time));
3640 }
3641 /*}}}*/
3643 
3644  int step = -1;
3645  int numberofelements = -1;
3646  IssmDouble time = -1;
3647  IssmDouble* stresserror = NULL;
3648  IssmDouble* thicknesserror = NULL;
3649 
3650  if(!this->elements || !this->vertices || !this->results || !this->parameters) return;
3651 
3652  parameters->FindParam(&step,StepEnum);
3653  parameters->FindParam(&time,TimeEnum);
3654  numberofelements=this->elements->NumberOfElements();
3655 
3656  /*Compute the deviatoric stress tensor*/
3657  this->ZZErrorEstimator(&stresserror);
3658 
3659  /*Compute the thickness error*/
3660  this->ThicknessZZErrorEstimator(&thicknesserror);
3661 
3662  /*Write error estimators in Results*/
3664  stresserror,numberofelements,1,step,time));
3665 
3667  thicknesserror,numberofelements,1,step,time));
3668  /*Cleanup*/
3669  xDelete<IssmDouble>(stresserror);
3670  xDelete<IssmDouble>(thicknesserror);
3671 
3672  return;
3673 }
3674 /*}}}*/
3675 void FemModel::CreateElements(int newnumberofelements,int elementswidth,int* newelementslist,bool* my_elements,Elements* elements){/*{{{*/
3676 
3677  /*newlementslist is in Matlab indexing*/
3678  int lid=0;
3679  for(int i=0;i<newnumberofelements;i++){
3680  if(my_elements[i]){
3681  /*Create element - just tria in this version*/
3682  Tria *newtria=new Tria();
3683  newtria->id=i+1;
3684  newtria->sid=i;
3685  newtria->lid=lid++;
3686  newtria->iscollapsed=0;
3687  newtria->isonsurface = true;
3688  newtria->isonbase = true;
3689  newtria->parameters=NULL;
3690  newtria->inputs2=NULL;
3691  newtria->nodes=NULL;
3692  newtria->vertices=NULL;
3693  newtria->material=NULL;
3694  if(this->nummodels>0){
3695  newtria->element_type_list=xNew<int>(this->nummodels);
3696  for(int j=0;j<nummodels;j++) newtria->element_type_list[j]=0;
3697  }
3698  else newtria->element_type_list=NULL;
3699 
3700  /*Element hook*/
3701  int material_id=i+1; // retrieve material_id = i+1;
3702  /*retrieve vertices ids*/
3703  int* vertex_ids=xNew<int>(elementswidth);
3704  for(int j=0;j<elementswidth;j++) vertex_ids[j]=reCast<int>(newelementslist[elementswidth*i+j]);//this Hook wants Matlab indexing
3705  /*Setting the hooks*/
3706  newtria->numanalyses =this->nummodels;
3707  newtria->hnodes =new Hook*[this->nummodels];
3708  newtria->hvertices =new Hook(&vertex_ids[0],elementswidth);
3709  newtria->hmaterial =new Hook(&material_id,1);
3710  newtria->hneighbors =NULL;
3711  /*Initialize hnodes as NULL*/
3712  for(int j=0;j<this->nummodels;j++) newtria->hnodes[j]=NULL;
3713  /*Clean up*/
3714  xDelete<int>(vertex_ids);
3715  elements->AddObject(newtria);
3716  }
3717  }
3718 
3719 }
3720 /*}}}*/
3721 void FemModel::CreateMaterials(int newnumberofelements,bool* my_elements,Materials* materials){/*{{{*/
3722 
3723  /*Just Matice in this version*/
3724  for(int i=0;i<newnumberofelements;i++){
3725  if(my_elements[i]){
3726  materials->AddObject(new Matice(i+1,i,MaticeEnum));
3727  }
3728  }
3729 }
3730 /*}}}*/
3731 void FemModel::GetMesh(Vertices* femmodel_vertices, Elements* femmodel_elements,IssmDouble** px, IssmDouble** py, int** pelementslist){/*{{{*/
3732 
3733  if(!femmodel_vertices) _error_("GetMesh: vertices are NULL.");
3734  if(!femmodel_elements) _error_("GetMesh: elements are NULL.");
3735 
3736  int numberofvertices = femmodel_vertices->NumberOfVertices();
3737  int numberofelements = femmodel_elements->NumberOfElements();
3738  int elementswidth = this->GetElementsWidth(); // just 2D mesh in this version (just tria elements)
3739  IssmDouble* x = NULL;
3740  IssmDouble* y = NULL;
3741  IssmDouble* z = NULL;
3742  int* elementslist = NULL;
3743  int* elem_vertices = NULL;
3744  IssmDouble *id1 = NULL;
3745  IssmDouble *id2 = NULL;
3746  IssmDouble *id3 = NULL;
3747 
3748  /*Get vertices coordinates*/
3749  VertexCoordinatesx(&x,&y,&z,femmodel_vertices,false) ;
3750 
3751  /*Get element vertices*/
3752  elem_vertices = xNew<int>(elementswidth);
3753  Vector<IssmDouble>* vid1= new Vector<IssmDouble>(numberofelements);
3754  Vector<IssmDouble>* vid2= new Vector<IssmDouble>(numberofelements);
3755  Vector<IssmDouble>* vid3= new Vector<IssmDouble>(numberofelements);
3756 
3757  /*Go through elements, and for each element, get vertices*/
3758  for(int i=0;i<femmodel_elements->Size();i++){
3759  Element* element=xDynamicCast<Element*>(femmodel_elements->GetObjectByOffset(i));
3760  element->GetVerticesSidList(elem_vertices);
3761  vid1->SetValue(element->sid,elem_vertices[0],INS_VAL);
3762  vid2->SetValue(element->sid,elem_vertices[1],INS_VAL);
3763  vid3->SetValue(element->sid,elem_vertices[2],INS_VAL);
3764  }
3765 
3766  /*Assemble*/
3767  vid1->Assemble();
3768  vid2->Assemble();
3769  vid3->Assemble();
3770 
3771  /*Serialize*/
3772  id1 = vid1->ToMPISerial();
3773  id2 = vid2->ToMPISerial();
3774  id3 = vid3->ToMPISerial();
3775 
3776  /*Construct elements list*/
3777  elementslist=xNew<int>(numberofelements*elementswidth);
3778  if(numberofelements*elementswidth<0) _error_("numberofelements negative.");
3779  for(int i=0;i<numberofelements;i++){
3780  elementslist[elementswidth*i+0] = reCast<int>(id1[i])+1; //InterpMesh wants Matlab indexing
3781  elementslist[elementswidth*i+1] = reCast<int>(id2[i])+1; //InterpMesh wants Matlab indexing
3782  elementslist[elementswidth*i+2] = reCast<int>(id3[i])+1; //InterpMesh wants Matlab indexing
3783  }
3784 
3785  /*Assign pointers*/
3786  *px = x;
3787  *py = y;
3788  *pelementslist = elementslist; //Matlab indexing. InterMesh uses this type.
3789 
3790  /*Cleanup*/
3791  xDelete<int>(elem_vertices);
3792  xDelete<IssmDouble>(id1);
3793  xDelete<IssmDouble>(id2);
3794  xDelete<IssmDouble>(id3);
3795  xDelete<IssmDouble>(z);
3796  delete vid1;
3797  delete vid2;
3798  delete vid3;
3799 }
3800 /*}}}*/
3801 void FemModel::GetMesh(int** elementslist, IssmDouble** x, IssmDouble** y, int* numberofvertices, int* numberofelements){/*{{{*/
3802 
3803  int amrtype;
3804  this->parameters->FindParam(&amrtype,AmrTypeEnum);
3805 
3806  switch(amrtype){
3807 
3808  #if defined(_HAVE_NEOPZ_)
3809  case AmrNeopzEnum: this->amr->GetMesh(elementslist,x,y,numberofvertices,numberofelements); break;
3810  #endif
3811 
3812  #if defined(_HAVE_BAMG_)
3813  case AmrBamgEnum: this->amrbamg->GetMesh(elementslist,x,y,numberofvertices,numberofelements); break;
3814  #endif
3815 
3816  default: _error_("not implemented yet");
3817  }
3818 }/*}}}*/
3819 void FemModel::SetMesh(int** elementslist, IssmDouble** x, IssmDouble** y, int* numberofvertices, int* numberofelements){/*{{{*/
3820 
3821  int amrtype;
3822  this->parameters->FindParam(&amrtype,AmrTypeEnum);
3823 
3824  switch(amrtype){
3825 
3826  #if defined(_HAVE_NEOPZ_)
3827  case AmrNeopzEnum: this->amr->SetMesh(elementslist,x,y,numberofvertices,numberofelements); break;
3828  #endif
3829 
3830  #if defined(_HAVE_BAMG_)
3831  case AmrBamgEnum: this->amrbamg->SetMesh(elementslist,x,y,numberofvertices,numberofelements); break;
3832  #endif
3833 
3834  default: _error_("not implemented yet");
3835  }
3836 }/*}}}*/
3837 void FemModel::GetMeshOnPartition(Vertices* femmodel_vertices,Elements* femmodel_elements,IssmDouble** px,IssmDouble** py,IssmDouble** pz,int** pelementslist,int** psidtoindex){/*{{{*/
3838 
3839  if(!femmodel_vertices) _error_("GetMesh: vertices are NULL.");
3840  if(!femmodel_elements) _error_("GetMesh: elements are NULL.");
3841 
3842  int numberofvertices = femmodel_vertices->Size(); //number of vertices of this partition
3843  int numbertotalofvertices = femmodel_vertices->NumberOfVertices(); //number total of vertices (entire mesh)
3844  int numberofelements = femmodel_elements->Size(); //number of elements of this partition
3845  int elementswidth = this->GetElementsWidth(); //just 2D mesh in this version (just tria elements)
3846  IssmDouble* x = NULL;
3847  IssmDouble* y = NULL;
3848  IssmDouble* z = NULL;
3849  int* elementslist = NULL;
3850  int* sidtoindex = NULL;
3851  int* elem_vertices = NULL;
3852 
3853  /*Get vertices coordinates of this partition*/
3854  sidtoindex = xNewZeroInit<int>(numbertotalofvertices);//entire mesh, all vertices
3855  x = xNew<IssmDouble>(numberofvertices);//just this partition
3856  y = xNew<IssmDouble>(numberofvertices);//just this partitio;
3857  z = xNew<IssmDouble>(numberofvertices);//just this partitio;
3858 
3859  /*Go through in this partition (vertices)*/
3860  for(int i=0;i<numberofvertices;i++){//just this partition
3861  Vertex* vertex=(Vertex*)femmodel_vertices->GetObjectByOffset(i);
3862  /*Attention: no spherical coordinates*/
3863  x[i]=vertex->GetX();
3864  y[i]=vertex->GetY();
3865  z[i]=vertex->GetZ();
3866  /*Keep the index and sid pair*/
3867  sidtoindex[vertex->Sid()]=i;
3868  }
3869 
3870  /*Go through in this partition (elements) and build the element list*/
3871  elem_vertices= xNew<int>(elementswidth);
3872  elementslist = xNew<int>(numberofelements*elementswidth);
3873  if(numberofelements*elementswidth<0) _error_("numberofelements negative.");
3874 
3875  for(int i=0;i<numberofelements;i++){//just this partition
3876  Element* element=xDynamicCast<Element*>(femmodel_elements->GetObjectByOffset(i));
3877  element->GetVerticesSidList(elem_vertices);
3878  elementslist[elementswidth*i+0] = sidtoindex[elem_vertices[0]]+1; //InterpMesh wants Matlab indexing
3879  elementslist[elementswidth*i+1] = sidtoindex[elem_vertices[1]]+1; //InterpMesh wants Matlab indexing
3880  elementslist[elementswidth*i+2] = sidtoindex[elem_vertices[2]]+1; //InterpMesh wants Matlab indexing
3881  }
3882 
3883  /*Assign pointers*/
3884  *px = x;
3885  *py = y;
3886  *pz = z;
3887  *pelementslist = elementslist; //Matlab indexing. InterMesh uses this type.
3888  *psidtoindex = sidtoindex; //it is ncessary to insert inputs
3889 
3890  /*Cleanup*/
3891  xDelete<int>(elem_vertices);
3892 }
3893 /*}}}*/
3894 void FemModel::CreateConstraints(Vertices* newfemmodel_vertices,int analysis_enum,Constraints* newfemmodel_constraints){/*{{{*/
3895 
3896  /*ATTENTION: JUST SPCVX AND SPCVY*/
3897  /*OTHERS CONSTRAINTS MUST BE IMPLEMENTED*/
3898  if(analysis_enum!=StressbalanceAnalysisEnum) return;
3899  int analysis_index = AnalysisIndex(analysis_enum);
3900 
3901  int numberofnodes_analysistype= this->nodes_list[analysis_index]->NumberOfNodes();
3902  int dofpernode = 2; //vx and vy
3903  int numberofcols = dofpernode*2; //to keep dofs and flags in the vspc vector
3904  int numberofvertices = -1; //global, entire old mesh
3905  int numberofelements = -1; //global, entire old mesh
3906  int newnumberofvertices = newfemmodel_vertices->Size(); //local, just the new partition
3907  int count = 0;
3908  IssmDouble* x = NULL; //global, entire old mesh
3909  IssmDouble* y = NULL; //global, entire old mesh
3910  int* elementslist = NULL; //global, entire old mesh
3911  IssmDouble* spc = NULL; //global, entire old mesh
3912  IssmDouble* newx = NULL; //local, just new partition
3913  IssmDouble* newy = NULL; //local, just new partition
3914  IssmDouble* newspc = NULL; //local, just new partition
3915  IssmDouble eps = 1.e-8;
3916  Vector<IssmDouble>* vspc = new Vector<IssmDouble>(numberofnodes_analysistype*numberofcols);
3917 
3918  /*Get old mesh (global, entire mesh). Elementslist comes in Matlab indexing*/
3919  this->GetMesh(&elementslist,&x,&y,&numberofvertices,&numberofelements);
3920 
3921  /*Get vertices coordinates of the new partition*/
3922  newx=xNew<IssmDouble>(newnumberofvertices);//just the new partition
3923  newy=xNew<IssmDouble>(newnumberofvertices);//just the new partition
3924  for(int i=0;i<newnumberofvertices;i++){//just the new partition
3925  Vertex* vertex=(Vertex*)newfemmodel_vertices->GetObjectByOffset(i);
3926  /*Attention: no spherical coordinates*/
3927  newx[i]=vertex->GetX();
3928  newy[i]=vertex->GetY();
3929  }
3930 
3931  /*Get spcvx and spcvy of old mesh*/
3932  for(int i=0;i<this->constraints_list[analysis_index]->Size();i++){
3933 
3934  Constraint* constraint=(Constraint*)this->constraints_list[analysis_index]->GetObjectByOffset(i);
3935 
3936  SpcStatic* spcstatic = xDynamicCast<SpcStatic*>(constraint);
3937  int dof = spcstatic->GetDof();
3938  int node = spcstatic->GetNodeId();
3939  IssmDouble spcvalue = spcstatic->GetValue();
3940  int nodeindex = node-1;
3941 
3942  /*vx and vx flag insertion*/
3943  if(dof==0) {//vx
3944  vspc->SetValue(nodeindex*numberofcols,spcvalue,INS_VAL); //vx
3945  vspc->SetValue(nodeindex*numberofcols+dofpernode,1,INS_VAL);//vxflag
3946  }
3947  /*vy and vy flag insertion*/
3948  if(dof==1){//vy
3949  vspc->SetValue(nodeindex*numberofcols+1,spcvalue,INS_VAL); //vy
3950  vspc->SetValue(nodeindex*numberofcols+dofpernode+1,1,INS_VAL);//vyflag
3951  }
3952  }
3953 
3954  /*Assemble and serialize*/
3955  vspc->Assemble();
3956  spc=vspc->ToMPISerial();
3957 
3958  /*Interpolate spc values and flags in the new partition*/
3959  InterpFromMeshToMesh2dx(&newspc,elementslist,x,y,numberofvertices,numberofelements,
3960  spc,numberofvertices,numberofcols,
3961  newx,newy,newnumberofvertices,NULL);
3962 
3963  /*Now, insert the interpolated constraints in the data set (constraints)*/
3964  count=0;
3965  for(int i=0;i<newnumberofvertices;i++){//just in the new partition
3966  Vertex* vertex=(Vertex*)newfemmodel_vertices->GetObjectByOffset(i);
3967  /*spcvx*/
3968  if(!xIsNan<IssmDouble>(newspc[i*numberofcols]) && newspc[i*numberofcols+dofpernode]>(1-eps)){
3969  newfemmodel_constraints->AddObject(new SpcStatic(count+1,vertex->Sid()+1,0,newspc[i*numberofcols],analysis_enum));
3970  //add count'th spc, on node i+1, setting dof 1 to vx.
3971  count++;
3972  }
3973  }
3974  count=0;
3975  for(int i=0;i<newnumberofvertices;i++){//just in the new partition
3976  Vertex* vertex=(Vertex*)newfemmodel_vertices->GetObjectByOffset(i);
3977  /*spcvy*/
3978  if(!xIsNan<IssmDouble>(newspc[i*numberofcols+1]) && newspc[i*numberofcols+dofpernode+1]>(1-eps) ){
3979  newfemmodel_constraints->AddObject(new SpcStatic(count+1,vertex->Sid()+1,1,newspc[i*numberofcols+1],analysis_enum));
3980  //add count'th spc, on node i+1, setting dof 1 to vx.
3981  count++;
3982  }
3983  }
3984 
3985  /*Cleanup*/
3986  xDelete<IssmDouble>(spc);
3987  xDelete<IssmDouble>(newspc);
3988  xDelete<IssmDouble>(newx);
3989  xDelete<IssmDouble>(newy);
3990  delete vspc;
3991 }
3992 /*}}}*/
3993 void FemModel::UpdateElements(int newnumberofelements,int* newelementslist,bool* my_elements,int analysis_counter,Elements* newelements){/*{{{*/
3994 
3995  /*newelementslist is in Matlab indexing*/
3996 
3997  /*Update elements, set hnode.
3998  This code is in all analysis */
3999  int elemcounter=0;
4000  for(int iel=0;iel<newnumberofelements;iel++){
4001  if(my_elements[iel]){
4002  Tria* tria=(Tria*)newelements->GetObjectByOffset(elemcounter);
4003  //element update
4005  int numnodes=3;
4006  int* tria_node_ids=xNew<int>(numnodes);
4007  tria_node_ids[0]=newelementslist[3*iel+0]; //matlab indexing
4008  tria_node_ids[1]=newelementslist[3*iel+1]; //matlab indexing
4009  tria_node_ids[2]=newelementslist[3*iel+2]; //matlab indexing
4010  tria->SetHookNodes(tria_node_ids,numnodes,analysis_counter); tria->nodes=NULL;
4011  xDelete<int>(tria_node_ids);
4012  elemcounter++;
4013  }
4014  }
4015  return;
4016 }
4017 /*}}}*/
4019 
4020  int elementswidth = this->GetElementsWidth();//just 2D mesh, tria elements
4021  int numberofvertices = this->vertices->NumberOfVertices();
4022  IssmDouble weight = 0.;
4023  IssmDouble* tauxx = NULL;
4024  IssmDouble* tauyy = NULL;
4025  IssmDouble* tauxy = NULL;
4026  IssmDouble* totalweight = NULL;
4027  IssmDouble* deviatoricstressxx = xNew<IssmDouble>(elementswidth);
4028  IssmDouble* deviatoricstressyy = xNew<IssmDouble>(elementswidth);
4029  IssmDouble* deviatoricstressxy = xNew<IssmDouble>(elementswidth);
4030  int* elem_vertices = xNew<int>(elementswidth);
4031  Vector<IssmDouble>* vectauxx = new Vector<IssmDouble>(numberofvertices);
4032  Vector<IssmDouble>* vectauyy = new Vector<IssmDouble>(numberofvertices);
4033  Vector<IssmDouble>* vectauxy = new Vector<IssmDouble>(numberofvertices);
4034  Vector<IssmDouble>* vectotalweight = new Vector<IssmDouble>(numberofvertices);
4035 
4036  /*Update the Deviatoric Stress tensor over the elements*/
4037  this->DeviatoricStressx();
4038 
4039  /*Calculate the Smoothed Deviatoric Stress tensor*/
4040  for(int i=0;i<this->elements->Size();i++){
4041  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
4042  element->GetInputListOnVertices(deviatoricstressxx,DeviatoricStressxxEnum);
4043  element->GetInputListOnVertices(deviatoricstressyy,DeviatoricStressyyEnum);
4044  element->GetInputListOnVertices(deviatoricstressxy,DeviatoricStressxyEnum);
4045  element->GetVerticesSidList(elem_vertices);
4046 
4047  /*weight to calculate the smoothed deviatoric stress*/
4048  Tria* triaelement = xDynamicCast<Tria*>(element);
4049  weight = triaelement->GetArea();//the tria area is a choice for the weight
4050 
4051  /*taux xx*/
4052  vectauxx->SetValue(elem_vertices[0],weight*deviatoricstressxx[0],ADD_VAL);
4053  vectauxx->SetValue(elem_vertices[1],weight*deviatoricstressxx[1],ADD_VAL);
4054  vectauxx->SetValue(elem_vertices[2],weight*deviatoricstressxx[2],ADD_VAL);
4055  /*tau yy*/
4056  vectauyy->SetValue(elem_vertices[0],weight*deviatoricstressyy[0],ADD_VAL);
4057  vectauyy->SetValue(elem_vertices[1],weight*deviatoricstressyy[1],ADD_VAL);
4058  vectauyy->SetValue(elem_vertices[2],weight*deviatoricstressyy[2],ADD_VAL);
4059  /*tau xy*/
4060  vectauxy->SetValue(elem_vertices[0],weight*deviatoricstressxy[0],ADD_VAL);
4061  vectauxy->SetValue(elem_vertices[1],weight*deviatoricstressxy[1],ADD_VAL);
4062  vectauxy->SetValue(elem_vertices[2],weight*deviatoricstressxy[2],ADD_VAL);
4063  /*total weight*/
4064  vectotalweight->SetValue(elem_vertices[0],weight,ADD_VAL);
4065  vectotalweight->SetValue(elem_vertices[1],weight,ADD_VAL);
4066  vectotalweight->SetValue(elem_vertices[2],weight,ADD_VAL);
4067  }
4068 
4069  /*Assemble*/
4070  vectauxx->Assemble();
4071  vectauyy->Assemble();
4072  vectauxy->Assemble();
4073  vectotalweight->Assemble();
4074 
4075  /*Serialize*/
4076  tauxx = vectauxx->ToMPISerial();
4077  tauyy = vectauyy->ToMPISerial();
4078  tauxy = vectauxy->ToMPISerial();
4079  totalweight = vectotalweight->ToMPISerial();
4080 
4081  /*Divide for the total weight*/
4082  for(int i=0;i<numberofvertices;i++){
4083  _assert_(totalweight[i]>0);
4084  tauxx[i] = tauxx[i]/totalweight[i];
4085  tauyy[i] = tauyy[i]/totalweight[i];
4086  tauxy[i] = tauxy[i]/totalweight[i];
4087  }
4088 
4089  /*Set output*/
4090  (*ptauxx) = tauxx;
4091  (*ptauyy) = tauyy;
4092  (*ptauxy) = tauxy;
4093 
4094  /*Cleanup*/
4095  delete vectauxx;
4096  delete vectauyy;
4097  delete vectauxy;
4098  delete vectotalweight;
4099  xDelete<IssmDouble>(deviatoricstressxx);
4100  xDelete<IssmDouble>(deviatoricstressyy);
4101  xDelete<IssmDouble>(deviatoricstressxy);
4102  xDelete<IssmDouble>(totalweight);
4103  xDelete<int>(elem_vertices);
4104 }
4105 /*}}}*/
4106 void FemModel::ZZErrorEstimator(IssmDouble** pelementerror){/*{{{*/
4107 
4108  /*Compute the Zienkiewicz and Zhu (ZZ) error estimator for the deviatoric stress tensor.
4109  * Ref.: Zienkiewicz and Zhu, A Simple Error Estimator and Adaptive Procedure for Practical Engineering Analysis, Int. J. Numer. Meth. Eng, 1987*/
4110 
4111  IssmDouble Jdet,error,ftxx,ftyy,ftxy;
4112  int sid;
4113  int numnodes = this->GetElementsWidth();//just 2D mesh, tria elements, P1
4114  int numberofelements = this->elements->NumberOfElements();
4115  IssmDouble* xyz_list = NULL;
4116  IssmDouble* smoothedtauxx = NULL;
4117  IssmDouble* smoothedtauyy = NULL;
4118  IssmDouble* smoothedtauxy = NULL;
4119  IssmDouble* tauxx = xNew<IssmDouble>(numnodes);
4120  IssmDouble* tauyy = xNew<IssmDouble>(numnodes);
4121  IssmDouble* tauxy = xNew<IssmDouble>(numnodes);
4122  IssmDouble* basis = xNew<IssmDouble>(numnodes);
4123  int* elem_vertices = xNew<int>(numnodes);
4124  Vector<IssmDouble>* velementerror= new Vector<IssmDouble>(numberofelements);
4125 
4126  /*Get smoothed deviatoric stress tensor*/
4127  this->SmoothedDeviatoricStressTensor(&smoothedtauxx,&smoothedtauyy,&smoothedtauxy);
4128 
4129  /*Integrate the error over elements*/
4130  for(int i=0;i<this->elements->Size();i++){
4131  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
4135  element->GetVerticesSidList(elem_vertices);
4136 
4137  /*Integrate*/
4138  element->GetVerticesCoordinates(&xyz_list);
4139  Gauss* gauss=element->NewGauss(2);
4140  error=0.;
4141  for(int ig=gauss->begin();ig<gauss->end();ig++){
4142  gauss->GaussPoint(ig);
4143  element->JacobianDeterminant(&Jdet,xyz_list,gauss);
4144  element->NodalFunctions(basis,gauss);
4145  ftxx=0;ftyy=0;ftxy=0;
4146  for(int n=0;n<numnodes;n++) {
4147  ftxx+=(tauxx[n]-smoothedtauxx[elem_vertices[n]])*basis[n];
4148  ftyy+=(tauyy[n]-smoothedtauyy[elem_vertices[n]])*basis[n];
4149  ftxy+=(tauxy[n]-smoothedtauxy[elem_vertices[n]])*basis[n];
4150  }
4151  error+=Jdet*gauss->weight*( pow(ftxx,2)+pow(ftyy,2)+pow(ftxy,2) ); //e^2
4152  }
4153  /*Set the error in the global vector*/
4154  sid=element->Sid();
4155  error = sqrt(error);//sqrt(e^2)
4156  velementerror->SetValue(sid,error,INS_VAL);
4157  /*Cleanup intermediaries*/
4158  xDelete<IssmDouble>(xyz_list);
4159  delete gauss;
4160  }
4161 
4162  /*Assemble*/
4163  velementerror->Assemble();
4164 
4165  /*Serialize and set output*/
4166  (*pelementerror)=velementerror->ToMPISerial();
4167 
4168  /*Cleanup*/
4169  xDelete<IssmDouble>(smoothedtauxx);
4170  xDelete<IssmDouble>(smoothedtauyy);
4171  xDelete<IssmDouble>(smoothedtauxy);
4172  xDelete<IssmDouble>(tauxx);
4173  xDelete<IssmDouble>(tauyy);
4174  xDelete<IssmDouble>(tauxy);
4175  xDelete<IssmDouble>(basis);
4176  xDelete<int>(elem_vertices);
4177  delete velementerror;
4178 }
4179 /*}}}*/
4181 
4182  int elementswidth = this->GetElementsWidth();//just 2D mesh, tria elements
4183  int numberofvertices = this->vertices->NumberOfVertices();
4184 
4185  IssmDouble weight = 0.;
4186  IssmDouble* dHdx = NULL;
4187  IssmDouble* dHdy = NULL;
4188  IssmDouble* totalweight = NULL;
4189  IssmDouble* xyz_list = NULL;
4190  IssmDouble* H = xNew<IssmDouble>(elementswidth);
4191  IssmDouble* GradH = xNew<IssmDouble>(2);
4192  int* elem_vertices = xNew<int>(elementswidth);
4193  Vector<IssmDouble>* vecdHdx = new Vector<IssmDouble>(numberofvertices);
4194  Vector<IssmDouble>* vecdHdy = new Vector<IssmDouble>(numberofvertices);
4195  Vector<IssmDouble>* vectotalweight = new Vector<IssmDouble>(numberofvertices);
4196 
4197  for(int i=0;i<this->elements->Size();i++){
4198  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
4200  element->GetVerticesSidList(elem_vertices);
4201  element->GetVerticesCoordinates(&xyz_list);
4202 
4203  /*Get the gradient of thickness at the center point (in fact, GradH is constante over the element)*/
4204  Gauss* gauss=element->NewGauss(1);
4205  gauss->GaussPoint(gauss->begin());
4206  element->ValueP1DerivativesOnGauss(GradH,H,xyz_list,gauss);
4207 
4208  /*weight to calculate the smoothed grad H*/
4209  Tria* triaelement = xDynamicCast<Tria*>(element);
4210  weight = triaelement->GetArea();//the tria area is a choice for the weight
4211 
4212  /*dH/dx*/
4213  vecdHdx->SetValue(elem_vertices[0],weight*GradH[0],ADD_VAL);
4214  vecdHdx->SetValue(elem_vertices[1],weight*GradH[0],ADD_VAL);
4215  vecdHdx->SetValue(elem_vertices[2],weight*GradH[0],ADD_VAL);
4216  /*dH/dy*/
4217  vecdHdy->SetValue(elem_vertices[0],weight*GradH[1],ADD_VAL);
4218  vecdHdy->SetValue(elem_vertices[1],weight*GradH[1],ADD_VAL);
4219  vecdHdy->SetValue(elem_vertices[2],weight*GradH[1],ADD_VAL);
4220  /*total weight*/
4221  vectotalweight->SetValue(elem_vertices[0],weight,ADD_VAL);
4222  vectotalweight->SetValue(elem_vertices[1],weight,ADD_VAL);
4223  vectotalweight->SetValue(elem_vertices[2],weight,ADD_VAL);
4224  /*Cleanup intermediaries*/
4225  xDelete<IssmDouble>(xyz_list);
4226  delete gauss;
4227  }
4228 
4229  /*Assemble*/
4230  vecdHdx->Assemble();
4231  vecdHdy->Assemble();
4232  vectotalweight->Assemble();
4233 
4234  /*Serialize*/
4235  dHdx = vecdHdx->ToMPISerial();
4236  dHdy = vecdHdy->ToMPISerial();
4237  totalweight = vectotalweight->ToMPISerial();
4238 
4239  /*Divide for the total weight*/
4240  for(int i=0;i<numberofvertices;i++){
4241  _assert_(totalweight[i]>0);
4242  dHdx[i] = dHdx[i]/totalweight[i];
4243  dHdy[i] = dHdy[i]/totalweight[i];
4244  }
4245 
4246  /*Set output*/
4247  (*pdHdx) = dHdx;
4248  (*pdHdy) = dHdy;
4249 
4250  /*Cleanup*/
4251  delete vecdHdx;
4252  delete vecdHdy;
4253  delete vectotalweight;
4254  xDelete<IssmDouble>(H);
4255  xDelete<IssmDouble>(GradH);
4256  xDelete<IssmDouble>(totalweight);
4257  xDelete<int>(elem_vertices);
4258 }
4259 /*}}}*/
4261  /*Compute the Zienkiewicz and Zhu (ZZ) error estimator for the thickness
4262  * Ref.: Zienkiewicz and Zhu, A Simple Error Estimator and Adaptive Procedure for Practical Engineering Analysis, Int. J. Numer. Meth. Eng, 1987*/
4263 
4264  IssmDouble Jdet,error,fdHdx,fdHdy;
4265  int sid;
4266  int numnodes = this->GetElementsWidth();//just 2D mesh, tria elements, P1
4267  int numberofelements = this->elements->NumberOfElements();
4268  IssmDouble* xyz_list = NULL;
4269  IssmDouble* smoothed_dHdx = NULL;
4270  IssmDouble* smoothed_dHdy = NULL;
4271  IssmDouble* H = xNew<IssmDouble>(numnodes);
4272  IssmDouble* GradH = xNew<IssmDouble>(2);
4273  IssmDouble* basis = xNew<IssmDouble>(numnodes);
4274  int* elem_vertices = xNew<int>(numnodes);
4275  Vector<IssmDouble>* velementerror= new Vector<IssmDouble>(numberofelements);
4276 
4277  /*Get smoothed deviatoric stress tensor*/
4278  this->SmoothedGradThickness(&smoothed_dHdx,&smoothed_dHdy);
4279 
4280  /*Integrate the error over elements*/
4281  for(int i=0;i<this->elements->Size();i++){
4282  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
4284  element->GetVerticesSidList(elem_vertices);
4285  element->GetVerticesCoordinates(&xyz_list);
4286  /*Get the gradient of thickness*/
4287  Gauss* gaussH=element->NewGauss(1);
4288  gaussH->GaussPoint(gaussH->begin());
4289  element->ValueP1DerivativesOnGauss(GradH,H,xyz_list,gaussH);
4290  /*Integrate*/
4291  Gauss* gauss=element->NewGauss(2);
4292  error=0.;
4293  for(int ig=gauss->begin();ig<gauss->end();ig++){
4294  gauss->GaussPoint(ig);
4295  element->JacobianDeterminant(&Jdet,xyz_list,gauss);
4296  element->NodalFunctions(basis,gauss);
4297  fdHdx=0;fdHdy=0;
4298  for(int n=0;n<numnodes;n++) {
4299  fdHdx+=(GradH[0]-smoothed_dHdx[elem_vertices[n]])*basis[n];
4300  fdHdy+=(GradH[1]-smoothed_dHdy[elem_vertices[n]])*basis[n];
4301  }
4302  error+=Jdet*gauss->weight*(pow(fdHdx,2)+pow(fdHdy,2) ); //e^2
4303  }
4304  /*Set the error in the global vector*/
4305  sid=element->Sid();
4306  error = sqrt(error); //sqrt( e^2 )
4307  velementerror->SetValue(sid,error,INS_VAL);
4308  /*Cleanup intermediaries*/
4309  xDelete<IssmDouble>(xyz_list);
4310  delete gaussH;
4311  delete gauss;
4312  }
4313 
4314  /*Assemble*/
4315  velementerror->Assemble();
4316 
4317  /*Serialize and set output*/
4318  (*pelementerror)=velementerror->ToMPISerial();
4319 
4320  /*Cleanup*/
4321  xDelete<IssmDouble>(smoothed_dHdx);
4322  xDelete<IssmDouble>(smoothed_dHdy);
4323  xDelete<IssmDouble>(H);
4324  xDelete<IssmDouble>(GradH);
4325  xDelete<IssmDouble>(basis);
4326  xDelete<int>(elem_vertices);
4327  delete velementerror;
4328 }
4329 /*}}}*/
4330 void FemModel::MeanGroundedIceLevelSet(IssmDouble** pmasklevelset){/*{{{*/
4331 
4332  int elementswidth = this->GetElementsWidth();
4333  int numberofelements = this->elements->NumberOfElements();
4334  IssmDouble* elementlevelset = xNew<IssmDouble>(elementswidth);
4335  Vector<IssmDouble>* vmasklevelset = new Vector<IssmDouble>(numberofelements);
4336 
4337  for(int i=0;i<this->elements->Size();i++){
4338  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
4339  element->GetInputListOnVertices(elementlevelset,MaskOceanLevelsetEnum);
4340  int sid = element->Sid();
4341  vmasklevelset->SetValue(sid,(elementlevelset[0]+elementlevelset[1]+elementlevelset[2])/3.,INS_VAL);
4342  }
4343 
4344  /*Assemble*/
4345  vmasklevelset->Assemble();
4346 
4347  /*Serialize and set output*/
4348  (*pmasklevelset)=vmasklevelset->ToMPISerial();
4349 
4350  /*Cleanup*/
4351  xDelete<IssmDouble>(elementlevelset);
4352  delete vmasklevelset;
4353 }
4354 /*}}}*/
4356 
4357  /*Intermediaries*/
4358  int elementswidth = this->GetElementsWidth();
4359  int numberofelements = this->elements->NumberOfElements();
4360  int* elem_vertices = xNew<int>(elementswidth);
4361  Vector<IssmDouble>* vxc = new Vector<IssmDouble>(numberofelements);
4362  Vector<IssmDouble>* vyc = new Vector<IssmDouble>(numberofelements);
4363  IssmDouble* x = NULL;
4364  IssmDouble* y = NULL;
4365  IssmDouble* z = NULL;
4366  IssmDouble* xyz_list = NULL;
4367  IssmDouble x1,y1,x2,y2,x3,y3;
4368 
4369  /*Insert the element center coordinates*/
4370  for(int i=0;i<this->elements->Size();i++){
4371  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
4372  //element->GetVerticesSidList(elem_vertices);
4373  int sid = element->Sid();
4374  element->GetVerticesCoordinates(&xyz_list);
4375  x1 = xyz_list[3*0+0];y1 = xyz_list[3*0+1];
4376  x2 = xyz_list[3*1+0];y2 = xyz_list[3*1+1];
4377  x3 = xyz_list[3*2+0];y3 = xyz_list[3*2+1];
4378  vxc->SetValue(sid,(x1+x2+x3)/3.,INS_VAL);
4379  vyc->SetValue(sid,(y1+y2+y3)/3.,INS_VAL);
4380  }
4381 
4382  /*Assemble*/
4383  vxc->Assemble();
4384  vyc->Assemble();
4385 
4386  /*Serialize and set output*/
4387  (*pxc)=vxc->ToMPISerial();
4388  (*pyc)=vyc->ToMPISerial();
4389 
4390  /*Cleanup*/
4391  xDelete<IssmDouble>(x);
4392  xDelete<IssmDouble>(y);
4393  xDelete<IssmDouble>(z);
4394  xDelete<IssmDouble>(xyz_list);
4395  xDelete<int>(elem_vertices);
4396  delete vxc;
4397  delete vyc;
4398 }
4399 /*}}}*/
4400 void FemModel::GetZeroLevelSetPoints(IssmDouble** pzerolevelset_points,int &numberofpoints,int levelset_type){/*{{{*/
4401 
4402  /*Here, "zero level set" means grounding line or ice front, depending on the level set type*/
4403  /*pzerolevelset_points are the element center points with zero level set. X and Y coords*/
4404  if(levelset_type!=MaskOceanLevelsetEnum && levelset_type!=MaskIceLevelsetEnum){
4405  _error_("level set type not implemented yet!");
4406  }
4407 
4408  /*Outputs*/
4409  IssmDouble* zerolevelset_points = NULL;
4410  int npoints = 0;
4411 
4412  /*Intermediaries*/
4413  int elementswidth = this->GetElementsWidth();
4414  int numberofelements = this->elements->NumberOfElements();
4415  int* elem_vertices = xNew<int>(elementswidth);
4416  IssmDouble* levelset = xNew<IssmDouble>(elementswidth);
4417  IssmDouble* xyz_list = NULL;
4418  Vector<IssmDouble>* vx_zerolevelset = new Vector<IssmDouble>(numberofelements);
4419  Vector<IssmDouble>* vy_zerolevelset = new Vector<IssmDouble>(numberofelements);
4420  IssmDouble* x_zerolevelset = NULL;
4421  IssmDouble* y_zerolevelset = NULL;
4422  int count,sid;
4423  IssmDouble xc,yc,x1,y1,x2,y2,x3,y3;
4424 
4425  /*Use the element center coordinate if level set is zero (grounding line or ice front), otherwise set NAN*/
4426  for(int i=0;i<this->elements->Size();i++){
4427  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
4428  element->GetInputListOnVertices(levelset,levelset_type);
4429  element->GetVerticesSidList(elem_vertices);
4430  sid= element->Sid();
4431  element->GetVerticesCoordinates(&xyz_list);
4432  x1 = xyz_list[3*0+0];y1 = xyz_list[3*0+1];
4433  x2 = xyz_list[3*1+0];y2 = xyz_list[3*1+1];
4434  x3 = xyz_list[3*2+0];y3 = xyz_list[3*2+1];
4435  xc = NAN;
4436  yc = NAN;
4437  Tria* tria = xDynamicCast<Tria*>(element);
4438  if(tria->IsIceInElement()){/*verify if there is ice in the element*/
4439  if(levelset[0]*levelset[1]<0. || levelset[0]*levelset[2]<0. ||
4440  abs(levelset[0]*levelset[1])<DBL_EPSILON || abs(levelset[0]*levelset[2])<DBL_EPSILON) {
4441  xc=(x1+x2+x3)/3.;
4442  yc=(y1+y2+y3)/3.;
4443  }
4444  }
4445  vx_zerolevelset->SetValue(sid,xc,INS_VAL);
4446  vy_zerolevelset->SetValue(sid,yc,INS_VAL);
4447  xDelete<IssmDouble>(xyz_list);
4448  }
4449  /*Assemble and serialize*/
4450  vx_zerolevelset->Assemble();
4451  vy_zerolevelset->Assemble();
4452  x_zerolevelset=vx_zerolevelset->ToMPISerial();
4453  y_zerolevelset=vy_zerolevelset->ToMPISerial();
4454 
4455  /*Find the number of points*/
4456  npoints=0;
4457  for(int i=0;i<numberofelements;i++) if(!xIsNan<IssmDouble>(x_zerolevelset[i])) npoints++;
4458 
4459  /*Keep just the element center coordinates with zero level set (compact the structure)*/
4460  zerolevelset_points=xNew<IssmDouble>(2*npoints);//x and y
4461  count=0;
4462  for(int i=0;i<numberofelements;i++){
4463  if(!xIsNan<IssmDouble>(x_zerolevelset[i])){
4464  zerolevelset_points[2*count] = x_zerolevelset[i];
4465  zerolevelset_points[2*count+1] = y_zerolevelset[i];
4466  count++;
4467  }
4468  }
4469 
4470  /*Assign outputs*/
4471  numberofpoints = npoints;
4472  (*pzerolevelset_points) = zerolevelset_points;
4473 
4474  /*Cleanup*/
4475  xDelete<int>(elem_vertices);
4476  xDelete<IssmDouble>(levelset);
4477  xDelete<IssmDouble>(x_zerolevelset);
4478  xDelete<IssmDouble>(y_zerolevelset);
4479  xDelete<IssmDouble>(xyz_list);
4480  delete vx_zerolevelset;
4481  delete vy_zerolevelset;
4482 }
4483 /*}}}*/
4484 #endif
4485 
4486 #ifdef _HAVE_DAKOTA_
4487 void FemModel::DakotaResponsesx(double* d_responses,char** responses_descriptors,int numresponsedescriptors,int d_numresponses){/*{{{*/
4488 
4489  int i,j;
4490  int my_rank;
4491 
4492  /*intermediary: */
4493  char root[50];
4494  int index;
4495  double femmodel_response;
4496  int flag;
4497  double *vertex_response = NULL;
4498  double *qmu_response = NULL;
4499  double *responses_pointer = NULL;
4500 
4501  IssmDouble **response_partitions = NULL;
4502  IssmDouble * response_partition = NULL;
4503  int * response_partitions_npart = NULL;
4504  int response_partitions_num;
4505  int npart;
4506 
4507  /*retrieve partition vectors for responses that are scaled:*/
4508  this->parameters->FindParam(&response_partitions,&response_partitions_num,NULL,NULL,QmuResponsePartitionsEnum);
4509  this->parameters->FindParam(&response_partitions_npart,NULL,NULL,QmuResponsePartitionsNpartEnum);
4510 
4511  /*retrieve my_rank: */
4512  my_rank=IssmComm::GetRank();
4513 
4514  /*save the d_responses pointer: */
4515  responses_pointer=d_responses;
4516 
4517  //watch out, we have more d_numresponses than numresponsedescriptors, because the responses have been expanded if they were scaled.
4518  //because we don't know the d_responses descriptors (the scaled ones) we can't key off them, so we will key off the responses_descriptors: */
4519 
4520  for(i=0;i<numresponsedescriptors;i++){
4521 
4522  flag=DescriptorIndex(root,&index,responses_descriptors[i]);
4523 
4524  if(flag==ScaledEnum){
4525 
4526  /*this response was scaled. pick up the response from the inputs: */
4527  GetVectorFromInputsx(&vertex_response,this, StringToEnumx(root),VertexPIdEnum);
4528 
4529  /*recover partition vector: */
4530  response_partition=response_partitions[i];
4531  npart=response_partitions_npart[i];
4532 
4533  /*Now, average it onto the partition nodes: */
4534  AverageOntoPartitionx(&qmu_response,elements,nodes,vertices,loads,materials,parameters,vertex_response,response_partition,npart);
4535 
4536  /*Copy onto our dakota responses: */
4537  if(my_rank==0){
4538  /*plug response: */
4539  for(j=0;j<npart;j++)responses_pointer[j]=qmu_response[j];
4540 
4541  /*increment response_pointer :*/
4542  responses_pointer+=npart;
4543  }
4544 
4545  /*Free ressources:*/
4546  xDelete<double>(vertex_response);
4547  xDelete<double>(qmu_response);
4548 
4549  }
4550  else if (flag==IndexedEnum){
4551 
4552  /*indexed response: plug index into parameters and call response module: */
4553  parameters->SetParam(index,IndexEnum);
4554 
4555  this->Responsex(&femmodel_response,root);
4556 
4557  if(my_rank==0){
4558  /*plug response: */
4559  responses_pointer[0]=femmodel_response;
4560 
4561  /*increment response_pointer :*/
4562  responses_pointer++;
4563  }
4564  }
4565  else if (flag==NodalEnum){
4566  _error_("nodal response functions not supported yet!");
4567 
4568  /*increment response_pointer :*/
4569  responses_pointer++;
4570  }
4571  else if (flag==RegularEnum){
4572 
4573  /*perfectly normal response function: */
4574  this->Responsex(&femmodel_response,root);
4575 
4576  if(my_rank==0){
4577  /*plug response: */
4578  responses_pointer[0]=femmodel_response;
4579 
4580  /*increment response_pointer :*/
4581  responses_pointer++;
4582  }
4583  }
4584  else _error_("flag type " << flag << " not supported yet for response analysis");
4585  }
4586 
4587  /*Synthesize echo: {{{*/
4588  if(my_rank==0){
4589  _printf_(" responses: " << d_numresponses << ": ");
4590  for(i=0;i<d_numresponses-1;i++)_printf_(d_responses[i] << "|");
4591  _printf_(d_responses[d_numresponses-1]);
4592  _printf_("\n");
4593  }
4594  /*}}}*/
4595 
4596  /*Free ressources:*/
4597  for(i=0;i<response_partitions_num;i++){
4598  IssmDouble* matrix=response_partitions[i];
4599  xDelete<IssmDouble>(matrix);
4600  }
4601  xDelete<IssmDouble*>(response_partitions);
4602 
4603 }
4604 /*}}}*/
4605 #endif
4606 #ifdef _HAVE_GIA_
4607 void FemModel::Deflection(Vector<IssmDouble>* wg,Vector<IssmDouble>* dwgdt, IssmDouble* x, IssmDouble* y){ /*{{{*/
4608 
4609  /*Go through elements, and add contribution from each element to the deflection vector wg:*/
4610  for(int i=0;i<elements->Size();i++){
4611  Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
4612  element->GiaDeflection(wg,dwgdt, x,y);
4613  }
4614 }
4615 /*}}}*/
4616 #endif
4617 #ifdef _HAVE_ESA_
4618 void FemModel::EsaGeodetic2D(Vector<IssmDouble>* pUp, Vector<IssmDouble>* pNorth, Vector<IssmDouble>* pEast, Vector<IssmDouble>* pX, Vector<IssmDouble>* pY, IssmDouble* xx, IssmDouble* yy){/*{{{*/
4619 
4620  int ns,nsmax;
4621 
4622  /*Go through elements, and add contribution from each element to the deflection vector wg:*/
4623  ns = elements->Size();
4624 
4625  /*Figure out max of ns: */
4628 
4629  /*Call the esa geodetic core: */
4630  for(int i=0;i<nsmax;i++){
4631  if(i<ns){
4632  Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
4633  element->EsaGeodetic2D(pUp,pNorth,pEast,pX,pY,xx,yy);
4634  }
4635  if(i%100==0){
4636  pUp->Assemble();
4637  pNorth->Assemble();
4638  pEast->Assemble();
4639  pX->Assemble();
4640  pY->Assemble();
4641  }
4642  }
4643 
4644  /*One last time: */
4645  pUp->Assemble();
4646  pNorth->Assemble();
4647  pEast->Assemble();
4648  pX->Assemble();
4649  pY->Assemble();
4650 
4651  /*Free ressources:*/
4652  xDelete<IssmDouble>(xx);
4653  xDelete<IssmDouble>(yy);
4654 }
4655 /*}}}*/
4656 void FemModel::EsaGeodetic3D(Vector<IssmDouble>* pUp, Vector<IssmDouble>* pNorth, Vector<IssmDouble>* pEast, IssmDouble* latitude, IssmDouble* longitude, IssmDouble* radius, IssmDouble* xx, IssmDouble* yy, IssmDouble* zz){/*{{{*/
4657 
4658  int ns,nsmax;
4659 
4660  /*Go through elements, and add contribution from each element to the deflection vector wg:*/
4661  ns = elements->Size();
4662 
4663  /*Figure out max of ns: */
4666 
4667  /*Call the esa geodetic core: */
4668  for(int i=0;i<nsmax;i++){
4669  if(i<ns){
4670  Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
4671  element->EsaGeodetic3D(pUp,pNorth,pEast,latitude,longitude,radius,xx,yy,zz);
4672  }
4673  if(i%100==0){
4674  pUp->Assemble();
4675  pNorth->Assemble();
4676  pEast->Assemble();
4677  }
4678  }
4679 
4680  /*One last time: */
4681  pUp->Assemble();
4682  pNorth->Assemble();
4683  pEast->Assemble();
4684 
4685  /*Free ressources:*/
4686  xDelete<IssmDouble>(latitude);
4687  xDelete<IssmDouble>(longitude);
4688  xDelete<IssmDouble>(radius);
4689  xDelete<IssmDouble>(xx);
4690  xDelete<IssmDouble>(yy);
4691  xDelete<IssmDouble>(zz);
4692 }
4693 /*}}}*/
4694 #endif
4695 #ifdef _HAVE_SEALEVELRISE_
4696 void FemModel::SealevelriseEustatic(Vector<IssmDouble>* pRSLgi, IssmDouble* poceanarea, IssmDouble* peustatic, SealevelMasks* masks) { /*{{{*/
4697 
4698  /*serialized vectors:*/
4699  IssmDouble eustatic = 0.;
4700  IssmDouble eustatic_cpu = 0.;
4701  IssmDouble eustatic_cpu_e = 0.;
4702  IssmDouble area = 0.;
4703  IssmDouble oceanarea = 0.;
4704  IssmDouble oceanarea_cpu = 0.;
4705 
4706  /*Initialize temporary vector that will be used to sum eustatic components
4707  * on all local elements, prior to assembly:*/
4708  int gsize = this->nodes->NumberOfDofs(GsetEnum);
4709  IssmDouble* RSLgi=xNewZeroInit<IssmDouble>(gsize);
4710  int* indices=xNew<int>(gsize);
4711  for(int i=0;i<gsize;i++) indices[i]=i;
4712 
4713  /*First, figure out the area of the ocean, which is needed to compute the eustatic component: */
4714  for(int i=0;i<elements->Size();i++){
4715  Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
4716  element->GetInput2Value(&area,AreaEnum);
4717  if (masks->isoceanin[i]) oceanarea_cpu += area;
4718  }
4719  ISSM_MPI_Reduce (&oceanarea_cpu,&oceanarea,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
4721  _assert_(oceanarea>0.);
4722 
4723  /*Call the sea level rise core: */
4724  for(int i=0;i<elements->Size();i++){
4725  Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
4726  element->SealevelriseEustatic(RSLgi,&eustatic_cpu_e,masks, oceanarea);
4727  eustatic_cpu+=eustatic_cpu_e;
4728  }
4729 
4730  /*Plug values once and assemble: */
4731  pRSLgi->SetValues(gsize,indices,RSLgi,ADD_VAL);
4732  pRSLgi->Assemble();
4733 
4734  /*Sum all eustatic components from all cpus:*/
4735  ISSM_MPI_Reduce (&eustatic_cpu,&eustatic,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
4737  _assert_(!xIsNan<IssmDouble>(eustatic));
4738 
4739  /*Free ressources:*/
4740  xDelete<int>(indices);
4741  xDelete<IssmDouble>(RSLgi);
4742 
4743  /*Assign output pointers:*/
4744  *poceanarea = oceanarea;
4745  *peustatic = eustatic;
4746 
4747 }
4748 /*}}}*/
4749 void FemModel::SealevelriseNonEustatic(Vector<IssmDouble>* pRSLgo, Vector<IssmDouble>* pRSLg_old, SealevelMasks* masks, bool verboseconvolution){/*{{{*/
4750 
4751  /*serialized vectors:*/
4752  IssmDouble* RSLg_old=NULL;
4753 
4754  IssmDouble* RSLgo = NULL;
4755  int* indices = NULL;
4756  int gsize;
4757 
4758  bool computerigid = true;
4759  bool computeelastic= true;
4760 
4761  /*recover computational flags: */
4762  this->parameters->FindParam(&computerigid,SolidearthSettingsRigidEnum);
4763  this->parameters->FindParam(&computeelastic,SolidearthSettingsElasticEnum);
4764 
4765  /*Initialize temporary vector that will be used to sum eustatic components on all local elements, prior
4766  * to assembly:*/
4767  gsize = this->nodes->NumberOfDofs(GsetEnum);
4768  RSLgo=xNewZeroInit<IssmDouble>(gsize);
4769  indices=xNew<int>(gsize); for (int i=0;i<gsize;i++)indices[i]=i;
4770 
4771  /*Serialize vectors from previous iteration:*/
4772  RSLg_old=pRSLg_old->ToMPISerial();
4773 
4774  /*Call the sea level rise non-eustatic core only if required: */
4775  if(computerigid | computeelastic){
4776  for(int i=0;i<elements->Size();i++){
4777  Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
4778  element->SealevelriseNonEustatic(RSLgo,RSLg_old,masks);
4779  }
4780  }
4781  pRSLgo->SetValues(gsize,indices,RSLgo,ADD_VAL);
4782  pRSLgo->Assemble();
4783 
4784  /*Free ressources:*/
4785  xDelete<int>(indices);
4786  xDelete<IssmDouble>(RSLgo);
4787  xDelete<IssmDouble>(RSLg_old);
4788 
4789 }
4790 /*}}}*/
4791 void FemModel::SealevelriseRotationalFeedback(Vector<IssmDouble>* pRSLgo_rot, Vector<IssmDouble>* pRSLg_old, IssmDouble* pIxz, IssmDouble* pIyz, IssmDouble* pIzz, SealevelMasks* masks){/*{{{*/
4792 
4793  /*serialized vectors:*/
4794  bool spherical=true;
4795  IssmDouble* RSLg_old=NULL;
4796  IssmDouble* tide_love_h = NULL;
4797  IssmDouble* tide_love_k = NULL;
4798  IssmDouble* load_love_k = NULL;
4799  IssmDouble tide_love_k2secular;
4800  IssmDouble moi_e, moi_p, omega, g;
4801  IssmDouble m1, m2, m3;
4802  IssmDouble lati, longi, radi, value;
4803  IssmDouble *latitude = NULL;
4804  IssmDouble *longitude = NULL;
4805  IssmDouble *radius = NULL;
4806 
4807  /*Serialize vectors from previous iteration:*/
4808  RSLg_old=pRSLg_old->ToMPISerial();
4809 
4810  IssmDouble moi_list[3]={0,0,0};
4811  IssmDouble moi_list_cpu[3]={0,0,0};
4812  for(int i=0;i<elements->Size();i++){
4813  Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
4814  element->SealevelriseMomentOfInertia(&moi_list[0],RSLg_old,masks );
4815  moi_list_cpu[0] += moi_list[0];
4816  moi_list_cpu[1] += moi_list[1];
4817  moi_list_cpu[2] += moi_list[2];
4818  }
4819  ISSM_MPI_Reduce (&moi_list_cpu[0],&moi_list[0],1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
4820  ISSM_MPI_Bcast(&moi_list[0],1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
4821  //
4822  ISSM_MPI_Reduce (&moi_list_cpu[1],&moi_list[1],1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
4823  ISSM_MPI_Bcast(&moi_list[1],1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
4824  //
4825  ISSM_MPI_Reduce (&moi_list_cpu[2],&moi_list[2],1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
4826  ISSM_MPI_Bcast(&moi_list[2],1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
4827 
4828  /*pull out some useful parameters: */
4829  parameters->FindParam(&load_love_k,NULL,NULL,LoadLoveKEnum);
4830  parameters->FindParam(&tide_love_h,NULL,NULL,TidalLoveHEnum);
4831  parameters->FindParam(&tide_love_k,NULL,NULL,TidalLoveKEnum);
4832  parameters->FindParam(&tide_love_k2secular,TidalLoveK2SecularEnum);
4836 
4837  /*compute perturbation terms for angular velocity vector: */
4838  m1 = 1/(1-tide_love_k[2]/tide_love_k2secular) * (1+load_love_k[2])/(moi_p-moi_e) * moi_list[0];
4839  m2 = 1/(1-tide_love_k[2]/tide_love_k2secular) * (1+load_love_k[2])/(moi_p-moi_e) * moi_list[1];
4840  m3 = -(1+load_love_k[2])/moi_p * moi_list[2]; // term associated with fluid number (3-order-of-magnitude smaller) is negelected
4841 
4842  /*recover lat,long and radius vectors from vertices: */
4843  VertexCoordinatesx(&latitude,&longitude,&radius,this->vertices,spherical);
4844 
4845  /* Green's function (1+k_2-h_2/g): checked against Glenn Milne's thesis Chapter 3 (eqs: 3.3-4, 3.10-11)
4846  * Perturbation terms for angular velocity vector (m1, m2, m3): checked against Mitrovica (2005 Appendix) & Jensen et al (2013 Appendix A3)
4847  * Sea level rotational feedback: checked against GMD eqs 8-9 (only first order terms, i.e., degree 2 order 0 & 1 considered)
4848  * all DONE in Geographic coordinates: theta \in [-90,90], lambda \in [-180 180]
4849  */
4850  for(int i=0;i<vertices->Size();i++){
4851  int sid;
4852  //Vertex* vertex=(Vertex*)vertices->GetObjectByOffset(i);
4853  Vertex* vertex=xDynamicCast<Vertex*>(vertices->GetObjectByOffset(i));
4854  sid=vertex->Sid();
4855 
4856  lati=latitude[sid]/180*PI; longi=longitude[sid]/180*PI; radi=radius[sid];
4857 
4858  /*only first order terms are considered now: */
4859  value=((1.0+tide_love_k[2]-tide_love_h[2])/9.81)*pow(omega*radi,2.0)*
4860  (-m3/6.0 + 0.5*m3*cos(2.0*lati) - 0.5*sin(2.*lati)*(m1*cos(longi)+m2*sin(longi)));
4861 
4862  pRSLgo_rot->SetValue(sid,value,INS_VAL); //INS_VAL ensures that you don't add several times
4863  }
4864 
4865  /*Assemble mesh velocity*/
4866  pRSLgo_rot->Assemble();
4867 
4868  /*Assign output pointers:*/
4869  if(pIxz)*pIxz=moi_list[0];
4870  if(pIyz)*pIyz=moi_list[1];
4871  if(pIzz)*pIzz=moi_list[2];
4872  xDelete<IssmDouble>(latitude);
4873  xDelete<IssmDouble>(longitude);
4874  xDelete<IssmDouble>(tide_love_h);
4875  xDelete<IssmDouble>(tide_love_k);
4876  xDelete<IssmDouble>(load_love_k);
4877 
4878  xDelete<IssmDouble>(radius);
4879 
4880  /*Free ressources:*/
4881  xDelete<IssmDouble>(RSLg_old);
4882 
4883 }
4884 /*}}}*/
4885 void FemModel::SealevelriseElastic(Vector<IssmDouble>* pUp, Vector<IssmDouble>* pNorth, Vector<IssmDouble>* pEast, Vector<IssmDouble>* pRSLg, SealevelMasks* masks){/*{{{*/
4886 
4887  /*serialized vectors:*/
4888  IssmDouble* RSLg=NULL;
4889 
4890  IssmDouble* Up = NULL;
4891  IssmDouble* North = NULL;
4892  IssmDouble* East = NULL;
4893  int* indices = NULL;
4894  int gsize;
4895  int horiz;
4896 
4897  /*retrieve parameters:*/
4899 
4900  /*Serialize vectors from previous iteration:*/
4901  RSLg=pRSLg->ToMPISerial();
4902 
4903  /*Initialize temporary vector that will be used to sum eustatic components on all local elements, prior
4904  * to assembly:*/
4905  gsize = this->nodes->NumberOfDofs(GsetEnum);
4906  Up=xNewZeroInit<IssmDouble>(gsize);
4907  if(horiz){
4908  North=xNewZeroInit<IssmDouble>(gsize);
4909  East=xNewZeroInit<IssmDouble>(gsize);
4910  }
4911  indices=xNew<int>(gsize); for (int i=0;i<gsize;i++)indices[i]=i;
4912 
4913  /*Call the sea level rise core: */
4914  for(int i=0;i<elements->Size();i++){
4915  Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
4916  element->SealevelriseGeodetic(Up,North,East,RSLg,masks);
4917  }
4918 
4919  pUp->SetValues(gsize,indices,Up,ADD_VAL);
4920  pUp->Assemble();
4921  if (horiz){
4922  pNorth->SetValues(gsize,indices,North,ADD_VAL);
4923  pNorth->Assemble();
4924  pEast->SetValues(gsize,indices,East,ADD_VAL);
4925  pEast->Assemble();
4926  }
4927 
4928  /*Free ressources:*/
4929  xDelete<IssmDouble>(Up);
4930  if(horiz){
4931  xDelete<IssmDouble>(North);
4932  xDelete<IssmDouble>(East);
4933  }
4934  xDelete<int>(indices);
4935  xDelete<IssmDouble>(RSLg);
4936 }
4937 /*}}}*/
4938 IssmDouble FemModel::SealevelriseOceanAverage(Vector<IssmDouble>* RSLg,SealevelMasks* masks, IssmDouble oceanarea) { /*{{{*/
4939 
4940  IssmDouble* RSLg_serial=NULL;
4941  IssmDouble oceanvalue,oceanvalue_cpu;
4942 
4943  /*Serialize vectors from previous iteration:*/
4944  RSLg_serial=RSLg->ToMPISerial();
4945 
4946  /*Initialize:*/
4947  oceanvalue_cpu=0;
4948 
4949  /*Go through elements, and add contribution from each element and divide by overall ocean area:*/
4950  for(int i=0;i<elements->Size();i++){
4951  Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
4952  oceanvalue_cpu += element->OceanAverage(RSLg_serial,masks);
4953  }
4954 
4955  ISSM_MPI_Reduce (&oceanvalue_cpu,&oceanvalue,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
4957 
4958  /*Free ressources:*/
4959  xDelete<IssmDouble>(RSLg_serial);
4960 
4961  return oceanvalue/oceanarea;
4962 }
4963 /*}}}*/
4964 #endif
4966 
4967  Vector<IssmDouble> *mask = NULL;
4968  Vector<IssmDouble> *recurence = NULL;
4969  Vector<IssmDouble> *active = NULL;
4970  IssmDouble *serial_mask = NULL;
4971  IssmDouble *serial_rec = NULL;
4972  IssmDouble *serial_active = NULL;
4973  IssmDouble *old_active = NULL;
4974  int *eplzigzag_counter = NULL;
4975  int eplflip_lock;
4976 
4979 
4980  /*Step 1: update mask, the mask might be extended by residual and/or using downstream sediment head*/
4981  int numnodes = this->nodes->NumberOfNodes();
4982  mask=new Vector<IssmDouble>(numnodes);
4983  recurence=new Vector<IssmDouble>(numnodes);
4984  this->parameters->FindParam(&eplzigzag_counter,NULL,EplZigZagCounterEnum);
4985  this->parameters->FindParam(&eplflip_lock,HydrologydcEplflipLockEnum);
4987 
4988  for (int i=0;i<elements->Size();i++){
4989  Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
4990  effanalysis->HydrologyEPLGetMask(mask,recurence,element);
4991  }
4992 
4993  /*check for changes and increment zigzag counter, change the mask if necessary*/
4994  recurence->Assemble();
4995  serial_rec=recurence->ToMPISerial();
4996  for (int i=0;i<nodes->Size();i++){
4997  Node* node=xDynamicCast<Node*>(nodes->GetObjectByOffset(i));
4998  if(serial_rec[node->Sid()]==1.)eplzigzag_counter[node->Lid()] ++;
4999  if(eplzigzag_counter[node->Lid()]>eplflip_lock && eplflip_lock!=0){
5000  mask->SetValue(node->Sid(),old_active[node->Sid()],INS_VAL);
5001  }
5002  }
5003  this->parameters->SetParam(eplzigzag_counter,this->nodes->Size(),EplZigZagCounterEnum);
5004  /*Assemble and serialize*/
5005  mask->Assemble();
5006  serial_mask=mask->ToMPISerial();
5007 
5008  xDelete<int>(eplzigzag_counter);
5009  xDelete<IssmDouble>(serial_rec);
5010  xDelete<IssmDouble>(old_active);
5011  delete mask;
5012  delete recurence;
5013 
5014  /*Update Mask*/
5016  xDelete<IssmDouble>(serial_mask);
5017  inefanalysis->ElementizeEplMask(this);
5018  /*Step 2: update node activity. If one element is connected to mask=1, all nodes are active*/
5019  active=new Vector<IssmDouble>(nodes->NumberOfNodes());
5020  for (int i=0;i<elements->Size();i++){
5021  Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
5022  effanalysis->HydrologyEPLGetActive(active,element);
5023  }
5024 
5025  /*Assemble and serialize*/
5026  active->Assemble();
5027  serial_active=active->ToMPISerial();
5028  delete active;
5029 
5030 
5031  /*Update node activation accordingly*/
5032  int counter = 0; //this is probably not acurate but we are only interested in positivity
5033  for(int i=0;i<elements->Size();i++){
5034  Element *element = xDynamicCast<Element*>(elements->GetObjectByOffset(i));
5035  int numnodes = element->GetNumberOfNodes();
5036  IssmDouble *base = xNew<IssmDouble>(numnodes);
5037  element->GetInputListOnNodes(&base[0],BaseEnum);
5038  for(int in=0;in<numnodes;in++){
5039  Node* node=element->GetNode(in);
5040  if(serial_active[node->Sid()]==1.){
5041  node->Activate();
5042  if(!node->IsClone()) counter++;
5043  }
5044  else{
5045  node->Deactivate();
5046  node->ApplyConstraint(0,base[in]);
5047  }
5048  }
5049  xDelete<IssmDouble>(base);
5050  }
5051  xDelete<IssmDouble>(serial_active);
5052  delete effanalysis;
5053  delete inefanalysis;
5054  int sum_counter;
5055  ISSM_MPI_Reduce(&counter,&sum_counter,1,ISSM_MPI_INT,ISSM_MPI_SUM,0,IssmComm::GetComm() );
5056  ISSM_MPI_Bcast(&sum_counter,1,ISSM_MPI_INT,0,IssmComm::GetComm());
5057  counter=sum_counter;
5058  *pEplcount = counter;
5059  if(VerboseSolution()) {
5060  if(counter==0){
5061  _printf0_(" No nodes are active in EPL layer \n");
5062  }
5063  else {
5064  _printf0_(" Some active nodes in EPL layer \n");
5065  }
5066  }
5067 
5068  /*Update dof indexings*/
5069  this->UpdateConstraintsx();
5070 }
5071 /*}}}*/
5073 
5074  bool isthermal;
5075  Vector<IssmDouble>* mask = NULL;
5076  Vector<IssmDouble>* active = NULL;
5077  IssmDouble* serial_mask = NULL;
5078  IssmDouble* serial_active = NULL;
5079 
5082 
5083  /*When solving a thermal model we update the thawed nodes*/
5084  if(isthermal){
5085  /*Step 1: update mask, the mask correspond to thawed nodes (that have a meltingrate)*/
5086  mask=new Vector<IssmDouble>(this->nodes->NumberOfNodes());
5087 
5088  for (int i=0;i<elements->Size();i++){
5089  Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
5090  inefanalysis->HydrologyIDSGetMask(mask,element);
5091  }
5092  /*Assemble and serialize*/
5093  mask->Assemble();
5094  serial_mask=mask->ToMPISerial();
5095  delete mask;
5096  }
5097  /*for other cases we just grab the mask from the initialisation value*/
5098  else{
5100  }
5101  /*Update Mask and elementize*/
5103  xDelete<IssmDouble>(serial_mask);
5104  inefanalysis->ElementizeIdsMask(this);
5105 
5106  /*get node mask coherent with element mask*/
5107  active=new Vector<IssmDouble>(nodes->NumberOfNodes());
5108  for (int i=0;i<elements->Size();i++){
5109  Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
5110  inefanalysis->HydrologyIdsGetActive(active,element);
5111  }
5112 
5113  /*Assemble and serialize*/
5114  active->Assemble();
5115  serial_active=active->ToMPISerial();
5116  delete active;
5117 
5118  /*Update node activation accordingly*/
5119  int counter = 0; //this is probably not acurate but we are only interested in positivity
5120  for(int i=0;i<elements->Size();i++){
5121  Element *element = xDynamicCast<Element*>(elements->GetObjectByOffset(i));
5122  int numnodes = element->GetNumberOfNodes();
5123  IssmDouble *base = xNew<IssmDouble>(numnodes);
5124 
5125  element->GetInputListOnNodes(&base[0],BaseEnum);
5126 
5127  for(int in=0;in<numnodes;in++){
5128  Node* node=element->GetNode(in);
5129  if(serial_active[node->Sid()]==1.){
5130  node->Activate();
5131  if(!node->IsClone()) counter++;
5132  }
5133  else{
5134  node->Deactivate();
5135  node->ApplyConstraint(0,base[in]);
5136  }
5137  }
5138  xDelete<IssmDouble>(base);
5139  }
5140  xDelete<IssmDouble>(serial_active);
5141  delete inefanalysis;
5142  int sum_counter;
5143  ISSM_MPI_Reduce(&counter,&sum_counter,1,ISSM_MPI_INT,ISSM_MPI_SUM,0,IssmComm::GetComm() );
5144  ISSM_MPI_Bcast(&sum_counter,1,ISSM_MPI_INT,0,IssmComm::GetComm());
5145  counter=sum_counter;
5146  *pIDScount = counter;
5147  if(VerboseSolution()) {
5148  if(counter==0){
5149  _printf0_(" No nodes are active in IDS layer \n");
5150  }
5151  else {
5152  _printf0_(" Some active nodes in IDS layer \n");
5153  }
5154  }
5155  /*Update dof indexings*/
5156  this->UpdateConstraintsx();
5157 
5158 }
5159 /*}}}*/
5161 
5162  Vector<IssmDouble>* active = NULL;
5163  IssmDouble* serial_active = NULL;
5165 
5166  /*update node activity. If one element is connected to mask=1, all nodes are active*/
5168  active=new Vector<IssmDouble>(nodes->NumberOfNodes());
5169  for (int i=0;i<elements->Size();i++){
5170  Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i));
5171  effanalysis->HydrologyEPLGetActive(active,element);
5172  }
5173 
5174  /*Assemble and serialize*/
5175  active->Assemble();
5176  serial_active=active->ToMPISerial();
5177  delete active;
5178  delete effanalysis;
5179 
5180  /*Update node activation accordingly*/
5181  int counter =0;
5183  for (int i=0;i<nodes->Size();i++){
5184  Node* node=xDynamicCast<Node*>(nodes->GetObjectByOffset(i));
5185  if(serial_active[node->Sid()]==1.){
5186  node->Activate();
5187  if(!node->IsClone()) counter++;
5188  }
5189  else{
5190  node->Deactivate();
5191  }
5192  }
5193  xDelete<IssmDouble>(serial_active);
5194  int sum_counter;
5195  ISSM_MPI_Reduce(&counter,&sum_counter,1,ISSM_MPI_INT,ISSM_MPI_SUM,0,IssmComm::GetComm() );
5196  ISSM_MPI_Bcast(&sum_counter,1,ISSM_MPI_INT,0,IssmComm::GetComm());
5197  counter=sum_counter;
5198  *pL2count = counter;
5199  if(VerboseSolution()) _printf0_(" Number of active nodes L2 Projection: "<< counter <<"\n");
5200 }
5201 /*}}}*/
5202 void FemModel::InitTransientInputx(int* transientinput_enum,int numoutputs){ /*{{{*/
5203 
5204  for(int i=0;i<numoutputs;i++){
5205  this->inputs2->DeleteInput(transientinput_enum[i]);
5206  this->inputs2->SetTransientInput(transientinput_enum[i],NULL,0);
5207  /*We need to configure this input!*/
5208  TransientInput2* transientinput = this->inputs2->GetTransientInput(transientinput_enum[i]); _assert_(transientinput);
5209  transientinput->Configure(this->parameters);
5210  }
5211 }
5212 /*}}}*/
5213 void FemModel::StackTransientInputx(int* input_enum,int* transientinput_enum,IssmDouble subtime,int numoutputs){ /*{{{*/
5214 
5215  for(int i=0;i<numoutputs;i++){
5216  if(input_enum[i]<0){
5217  _error_("Can't deal with non enum fields for result Stack");
5218  }
5219  else{
5220  for(int j=0;j<elements->Size();j++){
5221 
5222  /*Get the right transient input*/
5223  Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(j));
5224  TransientInput2* transientinput = this->inputs2->GetTransientInput(transientinput_enum[i]);
5225 
5226  /*Get values and lid list*/
5227  const int numvertices = element->GetNumberOfVertices();
5228  IssmDouble* values=xNew<IssmDouble>(numvertices);
5229  int *vertexlids = xNew<int>(numvertices);
5230  element->GetInputListOnVertices(&values[0],input_enum[i]); //this is the enum to stack
5231 
5232  element->GetVerticesLidList(vertexlids);
5233 
5234  switch(element->ObjectEnum()){
5235  case TriaEnum: transientinput->AddTriaTimeInput(subtime,numvertices,vertexlids,values,P1Enum); break;
5236  case PentaEnum: transientinput->AddPentaTimeInput(subtime,numvertices,vertexlids,values,P1Enum); break;
5237  default: _error_("Not implemented yet");
5238  }
5239  xDelete<IssmDouble>(values);
5240  xDelete<int>(vertexlids);
5241  }
5242  }
5243  }
5244 }
5245 /*}}}*/
5246 void FemModel::AverageTransientInputx(int* transientinput_enum,int* averagedinput_enum,IssmDouble init_time,IssmDouble end_time,int numoutputs, int averaging_method){ /*{{{*/
5247 
5248  for(int i=0;i<numoutputs;i++){
5249  for(int j=0;j<this->elements->Size();j++){
5250  Element* element = xDynamicCast<Element*>(elements->GetObjectByOffset(j));
5251  element->CreateInputTimeAverage(transientinput_enum[i],averagedinput_enum[i],init_time,end_time,averaging_method);
5252  }
5253  }
5254 }/*}}}*/
5255 #ifdef _HAVE_JAVASCRIPT_
5256 FemModel::FemModel(IssmDouble* buffer, int buffersize, char* toolkits, char* solution, char* modelname,ISSM_MPI_Comm incomm, bool trace){ /*{{{*/
5257  /*configuration: */
5258  int solution_type;
5259  int ierr;
5260 
5261  /*First things first, store the communicator, and set it as a global variable: */
5262  IssmComm::SetComm(incomm);
5263 
5264  /*Start profiler: */
5265  this->profiler=new Profiler();
5266  profiler->Start(TOTAL);
5267 
5268  /*From command line arguments, retrieve different filenames needed to create the FemModel: */
5269  solution_type=StringToEnumx(solution);
5270 
5271  /*Create femmodel from input files: */
5273  this->InitFromBuffers((char*)buffer,buffersize,toolkits, solution_type,trace,NULL);
5275 
5276  /*Save communicator in the parameters dataset: */
5278 
5279 }
5280 /*}}}*/
5281 void FemModel::CleanUpJs(char** poutput, size_t* psize){/*{{{*/
5282 
5283  /*Intermediary*/
5284  FILE *output_fid;
5285  GenericParam<char**>* outputbufferparam=NULL;
5286  GenericParam<size_t*>* outputbuffersizeparam=NULL;
5287  char** poutputbuffer;
5288  size_t* poutputbuffersize;
5289 
5290  /*Before we delete the profiler, report statistics for this run: */
5291  profiler->Stop(TOTAL); //final tagging
5292  _printf0_("\n");
5293  _printf0_(" "<<setw(40)<<left<<"FemModel initialization elapsed time:"<<profiler->TotalTime(MPROCESSOR) << "\n");
5294  _printf0_(" "<<setw(40)<<left<<"Core solution elapsed time:"<<profiler->TotalTime(CORE) << "\n");
5295  _printf0_("\n");
5296  _printf0_(" Total elapsed time: "
5297  <<profiler->TotalTimeModHour(TOTAL)<<" hrs "
5298  <<profiler->TotalTimeModMin(TOTAL)<<" min "
5299  <<profiler->TotalTimeModSec(TOTAL)<<" sec"
5300  );
5301  _printf0_("\n");
5302 
5303  /*Before we close the output file, recover the buffer and size:*/
5304  outputbufferparam = xDynamicCast<GenericParam<char**>*>(this->parameters->FindParamObject(OutputBufferPointerEnum));
5305  poutputbuffer=outputbufferparam->GetParameterValue();
5306  outputbuffersizeparam = xDynamicCast<GenericParam<size_t*>*>(this->parameters->FindParamObject(OutputBufferSizePointerEnum));
5307  poutputbuffersize=outputbuffersizeparam->GetParameterValue();
5308 
5309  /*Assign output values: */
5310  *poutput=*poutputbuffer;
5311  *psize=*poutputbuffersize;
5312 }
5313 /*}}}*/
5314 void FemModel::InitFromBuffers(char* buffer, int buffersize, char* toolkits, int in_solution_type, bool trace, IssmPDouble* X){/*{{{*/
5315 
5316  /*intermediary*/
5317  FILE *IOMODEL = NULL;
5318  FILE *toolkitsoptionsfid = NULL;
5319  FILE *output_fid = NULL;
5320  int my_rank;
5321  size_t outputsize;
5322  char *outputbuffer;
5323  const char *rootpath = ""; //needed for Dakota runs only, which we won't do here.
5324 
5325  /*recover my_rank:*/
5326  my_rank=IssmComm::GetRank();
5327 
5328  /*Open input file descriptor on cpu 0: */
5329  if(my_rank==0) IOMODEL = fmemopen((void*)buffer, buffersize, "rb");
5330 
5331  /*Open toolkits file descriptor: */
5332  toolkitsoptionsfid=fmemopen((void*)toolkits, strlen(toolkits)+1, "r");
5333 
5334  /*Now, go create FemModel:*/
5335  this->InitFromFids((char*)rootpath,IOMODEL,toolkitsoptionsfid,in_solution_type,trace,X);
5336 
5337  /*Close input file and toolkits file descriptors: */
5338  if(my_rank==0) fclose(IOMODEL);
5339  fclose(toolkitsoptionsfid);
5340 
5341  /*Open output file once for all and add output file descriptor to parameters*/
5342  output_fid=open_memstream(&outputbuffer,&outputsize);
5343  if(output_fid==NULL)_error_("could not initialize output stream");
5344  this->parameters->SetParam(output_fid,OutputFilePointerEnum);
5347 
5348 }/*}}}*/
5349 #endif
5350 
5351 #if defined(_HAVE_BAMG_) && !defined(_HAVE_AD_)
5352 void FemModel::ReMeshBamg(int* pnewnumberofvertices,int* pnewnumberofelements,IssmDouble** pnewx,IssmDouble** pnewy,IssmDouble** pnewz,int** pnewelementslist){/*{{{*/
5353 
5354  /*Output*/
5355  IssmDouble *newx = NULL;
5356  IssmDouble *newy = NULL;
5357  IssmDouble *newz = NULL;
5358  IssmDouble *newxylist = NULL;
5359  int *newelementslist = NULL;
5360  int* newdatalist = NULL;
5361  int newnumberofvertices = -1;
5362  int newnumberofelements = -1;
5363 
5364  /*Get Rank*/
5365  int my_rank = IssmComm::GetRank();
5366 
5367  /*Intermediaries*/
5368  int numberofvertices = this->vertices->NumberOfVertices();
5369  IssmDouble* vector_serial = NULL;
5370  IssmDouble* hmaxvertices_serial = NULL;
5371  Vector<IssmDouble> *vector = NULL;
5372 
5373  /*Get vector to create metric*/
5374  if(this->amrbamg->fieldenum!=NoneEnum){
5375  GetVectorFromInputsx(&vector,this,this->amrbamg->fieldenum,VertexSIdEnum);
5376  vector->Assemble();
5377  vector_serial = vector->ToMPISerial();
5378  }
5379 
5380  /*Get hmaxVertices to create metric*/
5381  if(this->amrbamg->groundingline_distance>0||this->amrbamg->icefront_distance>0||
5382  this->amrbamg->thicknesserror_threshold>0||this->amrbamg->deviatoricerror_threshold>0){
5383  /*Initialize hmaxvertices with NAN*/
5384  hmaxvertices_serial=xNew<IssmDouble>(numberofvertices);
5385  for(int i=0;i<numberofvertices;i++) hmaxvertices_serial[i]=NAN;
5386  /*Fill hmaxvertices*/
5387  if(this->amrbamg->thicknesserror_threshold>0) this->GethmaxVerticesFromEstimators(hmaxvertices_serial,ThicknessErrorEstimatorEnum);
5388  if(this->amrbamg->deviatoricerror_threshold>0) this->GethmaxVerticesFromEstimators(hmaxvertices_serial,DeviatoricStressErrorEstimatorEnum);
5389  if(this->amrbamg->groundingline_distance>0) this->GethmaxVerticesFromZeroLevelSetDistance(hmaxvertices_serial,MaskOceanLevelsetEnum);
5390  if(this->amrbamg->icefront_distance>0) this->GethmaxVerticesFromZeroLevelSetDistance(hmaxvertices_serial,MaskIceLevelsetEnum);
5391  }
5392 
5393  if(my_rank==0){
5394  this->amrbamg->ExecuteRefinementBamg(vector_serial,hmaxvertices_serial,&newdatalist,&newxylist,&newelementslist);
5395  if(newdatalist[0]<=0 || newdatalist[1]<=0) _error_("Error in the refinement process.");
5396  }
5397 
5398  /*Send new mesh to others CPU's*/
5399  if(my_rank) newdatalist=xNew<int>(2);
5400  ISSM_MPI_Bcast(newdatalist,2,ISSM_MPI_INT,0,IssmComm::GetComm());
5401  newnumberofvertices=newdatalist[0];
5402  newnumberofelements=newdatalist[1];
5403  if(my_rank){
5404  newxylist =xNew<IssmDouble>(newnumberofvertices*2);
5405  newelementslist=xNew<int>(newnumberofelements*this->GetElementsWidth());
5406  }
5407  ISSM_MPI_Bcast(newxylist,newnumberofvertices*2,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
5408  ISSM_MPI_Bcast(newelementslist,newnumberofelements*this->GetElementsWidth(),ISSM_MPI_INT,0,IssmComm::GetComm());
5409 
5410  /*Reorganize the data*/
5411  newx=xNew<IssmDouble>(newnumberofvertices);
5412  newy=xNew<IssmDouble>(newnumberofvertices);
5413  newz=xNewZeroInit<IssmDouble>(newnumberofvertices);
5414  for(int i=0;i<newnumberofvertices;i++){
5415  newx[i] = newxylist[2*i];
5416  newy[i] = newxylist[2*i+1];
5417  }
5418 
5419  /*Assign output pointers*/
5420  *pnewnumberofvertices = newnumberofvertices;
5421  *pnewnumberofelements = newnumberofelements;
5422  *pnewx = newx;
5423  *pnewy = newy;
5424  *pnewz = newz;
5425  *pnewelementslist = newelementslist;
5426 
5427  /*Cleanup*/
5428  xDelete<int>(newdatalist);
5429  xDelete<IssmDouble>(newxylist);
5430  xDelete<IssmDouble>(vector_serial);
5431  xDelete<IssmDouble>(hmaxvertices_serial);
5432  delete vector;
5433 }
5434 /*}}}*/
5435 void FemModel::InitializeAdaptiveRefinementBamg(void){/*{{{*/
5436 
5437  /*Define variables*/
5438  int numberofvertices = this->vertices->NumberOfVertices();
5439  int numberofelements = this->elements->NumberOfElements();
5440  IssmDouble* x = NULL;
5441  IssmDouble* y = NULL;
5442  int* elements = NULL;
5443  IssmDouble hmin,hmax,err,gradation;
5444 
5445  /*Get rank*/
5446  int my_rank = IssmComm::GetRank();
5447 
5448  /*Initialize field as NULL for now*/
5449  this->amrbamg = NULL;
5450 
5451  /*Get vertices coordinates of the coarse mesh (father mesh)*/
5452  this->GetMesh(this->vertices,this->elements,&x,&y,&elements);
5453 
5454  /*Create bamg data structures for bamg*/
5455  this->amrbamg = new AmrBamg();
5456 
5457  /*Get amr parameters*/
5458  this->parameters->FindParam(&hmin,AmrHminEnum);
5459  this->parameters->FindParam(&hmax,AmrHmaxEnum);
5460  this->parameters->FindParam(&err,AmrErrEnum);
5461  this->parameters->FindParam(&gradation,AmrGradationEnum);
5462  this->parameters->FindParam(&this->amrbamg->fieldenum,AmrFieldEnum);
5463  this->parameters->FindParam(&this->amrbamg->keepmetric,AmrKeepMetricEnum);
5464  this->parameters->FindParam(&this->amrbamg->groundingline_resolution,AmrGroundingLineResolutionEnum);
5465  this->parameters->FindParam(&this->amrbamg->groundingline_distance,AmrGroundingLineDistanceEnum);
5466  this->parameters->FindParam(&this->amrbamg->icefront_resolution,AmrIceFrontResolutionEnum);
5467  this->parameters->FindParam(&this->amrbamg->icefront_distance,AmrIceFrontDistanceEnum);
5468  this->parameters->FindParam(&this->amrbamg->thicknesserror_resolution,AmrThicknessErrorResolutionEnum);
5469  this->parameters->FindParam(&this->amrbamg->thicknesserror_threshold,AmrThicknessErrorThresholdEnum);
5470  this->parameters->FindParam(&this->amrbamg->thicknesserror_groupthreshold,AmrThicknessErrorGroupThresholdEnum);
5471  this->parameters->FindParam(&this->amrbamg->thicknesserror_maximum,AmrThicknessErrorMaximumEnum);
5472  this->parameters->FindParam(&this->amrbamg->deviatoricerror_resolution,AmrDeviatoricErrorResolutionEnum);
5473  this->parameters->FindParam(&this->amrbamg->deviatoricerror_threshold,AmrDeviatoricErrorThresholdEnum);
5474  this->parameters->FindParam(&this->amrbamg->deviatoricerror_groupthreshold,AmrDeviatoricErrorGroupThresholdEnum);
5475  this->parameters->FindParam(&this->amrbamg->deviatoricerror_maximum,AmrDeviatoricErrorMaximumEnum);
5476  /*Set BamgOpts*/
5477  this->amrbamg->SetBamgOpts(hmin,hmax,err,gradation);
5478 
5479  /*Re-create original mesh and put it in bamg structure (only cpu 0)*/
5480  this->amrbamg->SetMesh(&elements,&x,&y,&numberofvertices,&numberofelements);
5481  if(my_rank==0){
5482  this->amrbamg->Initialize();
5483  }
5484 }
5485 /*}}}*/
5486 void FemModel::GethmaxVerticesFromZeroLevelSetDistance(IssmDouble* hmaxvertices,int levelset_type){/*{{{*/
5487 
5488  if(!hmaxvertices) _error_("hmaxvertices is NULL!\n");
5489 
5490  /*Intermediaries*/
5491  int numberofvertices = this->vertices->NumberOfVertices();
5492  Vector<IssmDouble>* vminvertexdistance = new Vector<IssmDouble>(numberofvertices);
5493  IssmDouble* pminvertexdistance = NULL;
5494  IssmDouble* levelset_points = NULL;
5495  IssmDouble x,y;
5496  IssmDouble threshold,resolution;
5497  IssmDouble minvertexdistance,distance;
5498  int sid,numberofpoints;
5499 
5500  switch(levelset_type){
5501  case MaskOceanLevelsetEnum:
5502  threshold = this->amrbamg->groundingline_distance;
5503  resolution = this->amrbamg->groundingline_resolution;
5504  break;
5505  case MaskIceLevelsetEnum:
5506  threshold = this->amrbamg->icefront_distance;
5507  resolution = this->amrbamg->icefront_resolution;
5508  break;
5509  default: _error_("not implemented yet");
5510  }
5511 
5512  /*Get points which level set is zero (center of elements with zero level set)*/
5513  this->GetZeroLevelSetPoints(&levelset_points,numberofpoints,levelset_type);//levelset_points is serial (global)
5514 
5515  for(int i=0;i<this->vertices->Size();i++){//only on this partition
5516  Vertex* vertex=(Vertex*)this->vertices->GetObjectByOffset(i);
5517  /*Attention: no spherical coordinates*/
5518  x = vertex->GetX();
5519  y = vertex->GetY();
5520  sid= vertex->Sid();
5521  minvertexdistance=INFINITY;
5522 
5523  /*Find the minimum vertex distance*/
5524  for(int j=0;j<numberofpoints;j++){
5525  distance=sqrt((x-levelset_points[2*j])*(x-levelset_points[2*j])+(y-levelset_points[2*j+1])*(y-levelset_points[2*j+1]));
5526  minvertexdistance=min(distance,minvertexdistance);
5527  }
5528  /*Now, insert in the vector*/
5529  vminvertexdistance->SetValue(sid,minvertexdistance,INS_VAL);
5530  }
5531  /*Assemble*/
5532  vminvertexdistance->Assemble();
5533 
5534  /*Assign the pointer*/
5535  pminvertexdistance=vminvertexdistance->ToMPISerial();
5536 
5537  /*Fill hmaxVertices*/
5538  for(int i=0;i<numberofvertices;i++){
5539  if(pminvertexdistance[i]<threshold){ //hmaxvertices is serial (global)
5540  if(xIsNan<IssmDouble>(hmaxvertices[i])) hmaxvertices[i]=resolution;
5541  else hmaxvertices[i]=min(resolution,hmaxvertices[i]);
5542  }
5543  }
5544 
5545  /*Cleanup*/
5546  xDelete<IssmDouble>(pminvertexdistance);
5547  xDelete<IssmDouble>(levelset_points);
5548  delete vminvertexdistance;
5549 }
5550 /*}}}*/
5551 void FemModel::GethmaxVerticesFromEstimators(IssmDouble* hmaxvertices,int errorestimator_type){/*{{{*/
5552 
5553  if(!hmaxvertices) _error_("hmaxvertices is NULL!\n");
5554 
5555  /*Intermediaries*/
5556  int elementswidth = this->GetElementsWidth();
5557  int numberofelements = -1;
5558  int numberofvertices = -1;
5559  IssmDouble hmax = this->amrbamg->GetBamgOpts()->hmax;
5560  IssmDouble* maxlength = NULL;
5561  IssmDouble* error_vertices = NULL;
5562  IssmDouble* error_elements = NULL;
5563  IssmDouble* x = NULL;
5564  IssmDouble* y = NULL;
5565  int* index = NULL;
5566  IssmDouble maxerror,threshold,groupthreshold,resolution,length;
5567  IssmDouble L1,L2,L3;
5568  int vid,v1,v2,v3;
5569  bool refine;
5570 
5571 
5572  /*Fill variables*/
5573  switch(errorestimator_type){
5575  threshold = this->amrbamg->thicknesserror_threshold;
5576  groupthreshold = this->amrbamg->thicknesserror_groupthreshold;
5577  resolution = this->amrbamg->thicknesserror_resolution;
5578  maxerror = this->amrbamg->thicknesserror_maximum;
5579  this->ThicknessZZErrorEstimator(&error_elements);//error is serial, but the calculation is parallel
5580  break;
5582  threshold = this->amrbamg->deviatoricerror_threshold;
5583  groupthreshold = this->amrbamg->deviatoricerror_groupthreshold;
5584  resolution = this->amrbamg->deviatoricerror_resolution;
5585  maxerror = this->amrbamg->deviatoricerror_maximum;
5586  this->ZZErrorEstimator(&error_elements);//error is serial, but the calculation is parallel
5587  break;
5588  default: _error_("not implemented yet");
5589  }
5590  if(!error_elements) _error_("error_elements is NULL!\n");
5591  if(groupthreshold<DBL_EPSILON) _error_("group threshold is too small!");
5592 
5593  /*Get mesh*/
5594  this->GetMesh(&index,&x,&y,&numberofvertices,&numberofelements);
5595  if(numberofelements<0) _error_("number of elements is negative!\n");
5596  if(numberofvertices<0) _error_("number of vertices is negative!\n");
5597  maxlength = xNew<IssmDouble>(numberofelements);
5598  error_vertices = xNewZeroInit<IssmDouble>(numberofvertices);
5599 
5600  /*Find the max of the estimators if it was not provided*/
5601  if(maxerror<DBL_EPSILON){
5602  for(int i=0;i<numberofelements;i++) maxerror=max(maxerror,error_elements[i]);
5603  switch(errorestimator_type){
5604  case ThicknessErrorEstimatorEnum: this->amrbamg->thicknesserror_maximum = maxerror;break;
5605  case DeviatoricStressErrorEstimatorEnum: this->amrbamg->deviatoricerror_maximum = maxerror;break;
5606  }
5607  }
5608 
5609  /*Fill error_vertices (this is the sum of all elements connected to the vertex)*/
5610  for(int i=0;i<numberofelements;i++){
5611  v1=index[i*elementswidth+0]-1;//Matlab to C indexing
5612  v2=index[i*elementswidth+1]-1;//Matlab to C indexing
5613  v3=index[i*elementswidth+2]-1;//Matlab to C indexing
5614  L1=sqrt(pow(x[v2]-x[v1],2)+pow(y[v2]-y[v1],2));
5615  L2=sqrt(pow(x[v3]-x[v2],2)+pow(y[v3]-y[v2],2));
5616  L3=sqrt(pow(x[v1]-x[v3],2)+pow(y[v1]-y[v3],2));
5617  /*Fill the vectors*/
5618  maxlength[i] =max(L1,max(L2,L3));
5619  error_vertices[v1]+=error_elements[i];
5620  error_vertices[v2]+=error_elements[i];
5621  error_vertices[v3]+=error_elements[i];
5622  }
5623 
5624  /*Fill hmaxvertices with the criteria*/
5625  for(int i=0;i<numberofelements;i++){
5626  /*Refine any element if its error > phi*maxerror*/
5627  if(error_elements[i]>threshold*maxerror){
5628  /*Now, fill the hmaxvertices if requested*/
5629  for(int j=0;j<elementswidth;j++){
5630  vid=index[i*elementswidth+j]-1;//Matlab to C indexing
5631  if(xIsNan<IssmDouble>(hmaxvertices[vid])) hmaxvertices[vid]=max(maxlength[i]/2.,resolution);//Try first dividing the element
5632  else hmaxvertices[vid]=min(max(maxlength[i]/2.,resolution),hmaxvertices[vid]);//Try first dividing the element
5633  }
5634  }
5635  else {
5636  /*Try unrefine the element*/
5637  if(maxlength[i] < 1.1*hmax/2.){
5638  for(int j=0;j<elementswidth;j++){
5639  vid=index[i*elementswidth+j]-1;//Matlab to C indexing
5640  if(error_vertices[vid]>groupthreshold*maxerror) hmaxvertices[vid]=maxlength[i]; //keep the current resolution
5641  else{
5642  if(xIsNan<IssmDouble>(hmaxvertices[vid])) hmaxvertices[vid]=min(maxlength[i]*2.,hmax);
5643  else hmaxvertices[vid]=min(min(maxlength[i]*2.,hmax),hmaxvertices[vid]);//Try first to duplicate the element
5644  }
5645  }
5646  }
5647  }
5648  }
5649 
5650  /*Cleanup*/
5651  xDelete<IssmDouble>(error_elements);
5652  xDelete<IssmDouble>(error_vertices);
5653  xDelete<IssmDouble>(maxlength);
5654 }
5655 /*}}}*/
5656 void FemModel::GetVerticeDistanceToZeroLevelSet(IssmDouble** pverticedistance,int levelset_type){/*{{{*/
5657 
5658  //itapopo esse metodo pode ser deletado
5659 
5660 
5661  /*Here, "zero level set" means grounding line or ice front, depending on the level set type*/
5662  /*pverticedistance is the minimal vertice distance to the grounding line or ice front*/
5663  if(levelset_type!=MaskOceanLevelsetEnum && levelset_type!=MaskIceLevelsetEnum){
5664  _error_("level set type not implemented yet!");
5665  }
5666 
5667  /*Output*/
5668  IssmDouble* verticedistance;
5669 
5670  /*Intermediaries*/
5671  int numberofvertices = -1;
5672  int numberofelements = -1;
5673  IssmDouble* levelset_points= NULL;
5674  IssmDouble* x = NULL;
5675  IssmDouble* y = NULL;
5676  int* elementslist = NULL;
5677  int numberofpoints;
5678  IssmDouble distance;
5679 
5680  /*Get vertices coordinates*/
5681  this->GetMesh(&elementslist,&x,&y,&numberofvertices,&numberofelements);
5682  //this->GetMeshOnPartition(this->vertices,this->elements,&x,&y,&z,&elementslist,&sidtoindex);
5683 
5684  /*Get points which level set is zero (center of elements with zero level set)*/
5685  this->GetZeroLevelSetPoints(&levelset_points,numberofpoints,levelset_type);
5686 
5687  /*Find the minimal vertice distance to the zero levelset (grounding line or ice front)*/
5688  verticedistance=xNew<IssmDouble>(numberofvertices);
5689  for(int i=0;i<numberofvertices;i++){
5690  verticedistance[i]=INFINITY;
5691  for(int j=0;j<numberofpoints;j++){
5692  distance=sqrt((x[i]-levelset_points[2*j])*(x[i]-levelset_points[2*j])+(y[i]-levelset_points[2*j+1])*(y[i]-levelset_points[2*j+1]));
5693  verticedistance[i]=min(distance,verticedistance[i]);
5694  }
5695  }
5696 
5697  /*Assign the pointer*/
5698  (*pverticedistance)=verticedistance;
5699 
5700  /*Cleanup*/
5701  xDelete<IssmDouble>(levelset_points);
5702 }
5703 /*}}}*/
5704 #endif
5705 
5706 #if defined(_HAVE_NEOPZ_) && !defined(_HAVE_AD_)
5707 void FemModel::ReMeshNeopz(int* pnewnumberofvertices,int* pnewnumberofelements,IssmDouble** pnewx,IssmDouble** pnewy,IssmDouble** pnewz,int** pnewelementslist){/*{{{*/
5708 
5709  /*pnewelementslist keep vertices in Matlab indexing*/
5710  int my_rank = IssmComm::GetRank();
5711  IssmDouble* gl_distance = NULL;
5712  IssmDouble* if_distance = NULL;
5713  IssmDouble* deviatoricerror= NULL;
5714  IssmDouble* thicknesserror = NULL;
5715  IssmDouble* newx = NULL;
5716  IssmDouble* newy = NULL;
5717  IssmDouble* newz = NULL;
5718  IssmDouble* newxylist = NULL;
5719  int* newelementslist = NULL;
5720  int* newdatalist = NULL;
5721  int newnumberofvertices = -1;
5722  int newnumberofelements = -1;
5723 
5724  /*Get fields, if requested*/
5725  if(this->amr->groundingline_distance>0) this->GetElementDistanceToZeroLevelSet(&gl_distance,MaskOceanLevelsetEnum);
5726  if(this->amr->icefront_distance>0) this->GetElementDistanceToZeroLevelSet(&if_distance,MaskIceLevelsetEnum);
5727  if(this->amr->thicknesserror_threshold>0) this->ThicknessZZErrorEstimator(&thicknesserror);
5728  if(this->amr->deviatoricerror_threshold>0) this->ZZErrorEstimator(&deviatoricerror);
5729 
5730  if(my_rank==0){
5731  this->amr->ExecuteRefinement(gl_distance,if_distance,deviatoricerror,thicknesserror,
5732  &newdatalist,&newxylist,&newelementslist);
5733  if(newdatalist[0]<=0 || newdatalist[1]<=0) _error_("Error in the ReMeshNeopz.");
5734  }
5735 
5736  /*Send new mesh to others CPU's*/
5737  if(my_rank) newdatalist=xNew<int>(2);
5738  ISSM_MPI_Bcast(newdatalist,2,ISSM_MPI_INT,0,IssmComm::GetComm());
5739  newnumberofvertices=newdatalist[0];
5740  newnumberofelements=newdatalist[1];
5741  if(my_rank){
5742  newxylist =xNew<IssmDouble>(newnumberofvertices*2);
5743  newelementslist=xNew<int>(newnumberofelements*this->GetElementsWidth());
5744  }
5745  ISSM_MPI_Bcast(newxylist,newnumberofvertices*2,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
5746  ISSM_MPI_Bcast(newelementslist,newnumberofelements*this->GetElementsWidth(),ISSM_MPI_INT,0,IssmComm::GetComm());
5747 
5748  /*Reorganize the data*/
5749  newx=xNew<IssmDouble>(newnumberofvertices);
5750  newy=xNew<IssmDouble>(newnumberofvertices);
5751  newz=xNewZeroInit<IssmDouble>(newnumberofvertices);
5752  for(int i=0;i<newnumberofvertices;i++){
5753  newx[i] = newxylist[2*i];
5754  newy[i] = newxylist[2*i+1];
5755  }
5756 
5757  /*Assign the pointers*/
5758  (*pnewelementslist) = newelementslist; //Matlab indexing
5759  (*pnewx) = newx;
5760  (*pnewy) = newy;
5761  (*pnewz) = newz;
5762  *pnewnumberofvertices= newnumberofvertices;
5763  *pnewnumberofelements= newnumberofelements;
5764 
5765  /*Cleanup*/
5766  xDelete<int>(newdatalist);
5767  xDelete<IssmDouble>(newxylist);
5768  xDelete<IssmDouble>(deviatoricerror);
5769  xDelete<IssmDouble>(thicknesserror);
5770  xDelete<IssmDouble>(gl_distance);
5771  xDelete<IssmDouble>(if_distance);
5772 }
5773 /*}}}*/
5774 void FemModel::InitializeAdaptiveRefinementNeopz(void){/*{{{*/
5775 
5776  /*Define variables*/
5777  int my_rank = IssmComm::GetRank();
5778  int numberofvertices = this->vertices->NumberOfVertices();
5779  int numberofelements = this->elements->NumberOfElements();
5780  IssmDouble* x = NULL;
5781  IssmDouble* y = NULL;
5782  int* elements = NULL;
5783  int amr_restart;
5784 
5785  /*Initialize field as NULL for now*/
5786  this->amr = NULL;
5787 
5788  /*Get vertices coordinates of the coarse mesh (father mesh)*/
5789  /*elements comes in Matlab indexing*/
5790  this->GetMesh(this->vertices,this->elements,&x,&y,&elements);
5791 
5792  /*Create initial mesh (coarse mesh) in neopz data structure*/
5793  /*Just CPU #0 should keep AMR object*/
5794  /*Initialize refinement pattern*/
5795  this->SetRefPatterns();
5796  this->amr = new AdaptiveMeshRefinement();
5797  this->amr->refinement_type=1;//1 is refpattern; 0 is uniform (faster)
5798  /*Get amr parameters*/
5799  this->parameters->FindParam(&this->amr->level_max,AmrLevelMaxEnum);
5800  this->parameters->FindParam(&this->amr->gradation,AmrGradationEnum);
5801  this->parameters->FindParam(&this->amr->lag,AmrLagEnum);
5802  this->parameters->FindParam(&this->amr->groundingline_distance,AmrGroundingLineDistanceEnum);
5803  this->parameters->FindParam(&this->amr->icefront_distance,AmrIceFrontDistanceEnum);
5804  this->parameters->FindParam(&this->amr->thicknesserror_threshold,AmrThicknessErrorThresholdEnum);
5805  this->parameters->FindParam(&this->amr->thicknesserror_groupthreshold,AmrThicknessErrorGroupThresholdEnum);
5806  this->parameters->FindParam(&this->amr->thicknesserror_maximum,AmrThicknessErrorMaximumEnum);
5807  this->parameters->FindParam(&this->amr->deviatoricerror_threshold,AmrDeviatoricErrorThresholdEnum);
5808  this->parameters->FindParam(&this->amr->deviatoricerror_groupthreshold,AmrDeviatoricErrorGroupThresholdEnum);
5809  this->parameters->FindParam(&this->amr->deviatoricerror_maximum,AmrDeviatoricErrorMaximumEnum);
5810 
5811  /*Initialize NeoPZ data structure*/
5812  this->amr->SetMesh(&elements,&x,&y,&numberofvertices,&numberofelements);
5813  if(my_rank==0){
5814  this->parameters->FindParam(&amr_restart,AmrRestartEnum);
5815  if(amr_restart){//experimental
5816  this->amr->ReadMesh();
5817  } else {//this is the default method
5818  this->amr->Initialize();
5819  }
5820  }
5821 }
5822 /*}}}*/
5823 void FemModel::GetElementDistanceToZeroLevelSet(IssmDouble** pelementdistance,int levelset_type){/*{{{*/
5824 
5825  /*Here, "zero level set" means grounding line or ice front, depending on the level set type*/
5826  /*pverticedistance is the minimal vertice distance to the grounding line or ice front*/
5827  if(levelset_type!=MaskOceanLevelsetEnum && levelset_type!=MaskIceLevelsetEnum){
5828  _error_("level set type not implemented yet!");
5829  }
5830 
5831  /*Output*/
5832  IssmDouble* elementdistance;
5833 
5834  /*Intermediaries*/
5835  int numberofelements = this->elements->NumberOfElements();
5836  Vector<IssmDouble>* velementdistance = new Vector<IssmDouble>(numberofelements);
5837  IssmDouble* levelset_points = NULL;
5838  IssmDouble* xyz_list = NULL;
5839  IssmDouble mindistance,distance;
5840  IssmDouble xc,yc,x1,y1,x2,y2,x3,y3;
5841  int numberofpoints;
5842 
5843  /*Get points which level set is zero (center of elements with zero level set, levelset_points is serial)*/
5844  this->GetZeroLevelSetPoints(&levelset_points,numberofpoints,levelset_type);
5845 
5846  for(int i=0;i<this->elements->Size();i++){//parallel
5847  Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i));
5848  int sid = element->Sid();
5849  element->GetVerticesCoordinates(&xyz_list);
5850  x1 = xyz_list[3*0+0];y1 = xyz_list[3*0+1];
5851  x2 = xyz_list[3*1+0];y2 = xyz_list[3*1+1];
5852  x3 = xyz_list[3*2+0];y3 = xyz_list[3*2+1];
5853  xc = (x1+x2+x3)/3.;
5854  yc = (y1+y2+y3)/3.;
5855  mindistance=INFINITY;
5856  /*Loop over each point (where level set is zero)*/
5857  for(int j=0;j<numberofpoints;j++){
5858  distance =sqrt((xc-levelset_points[2*j])*(xc-levelset_points[2*j])+(yc-levelset_points[2*j+1])*(yc-levelset_points[2*j+1]));
5859  mindistance=min(distance,mindistance);
5860  }
5861  velementdistance->SetValue(sid,mindistance,INS_VAL);
5862  xDelete<IssmDouble>(xyz_list);
5863  }
5864 
5865  /*Assemble*/
5866  velementdistance->Assemble();
5867 
5868  /*Assign the pointer*/
5869  (*pelementdistance)=velementdistance->ToMPISerial();
5870 
5871  /*Cleanup*/
5872  xDelete<IssmDouble>(levelset_points);
5873  xDelete<IssmDouble>(xyz_list);
5874  delete velementdistance;
5875 }
5876 /*}}}*/
5877 void FemModel::SetRefPatterns(){/*{{{*/
5878 
5879  /*Initialize the global variable of refinement patterns*/
5880  gRefDBase.InitializeUniformRefPattern(ETriangle);
5881 
5882  /*Insert specifics patterns to ISSM core*/
5883  std::string filepath = REFPATTERNDIR;
5884  std::string filename1 = filepath + "/2D_Triang_Rib_3.rpt";
5885  std::string filename2 = filepath + "/2D_Triang_Rib_4.rpt";
5886  std::string filename3 = filepath + "/2D_Triang_Rib_5.rpt";
5887  std::string filename4 = filepath + "/2D_Triang_Rib_OnlyTriang_Side_3_4.rpt";
5888  std::string filename5 = filepath + "/2D_Triang_Rib_OnlyTriang_Side_3_4_permuted.rpt";
5889  std::string filename6 = filepath + "/2D_Triang_Rib_OnlyTriang_Side_3_5.rpt";
5890  std::string filename7 = filepath + "/2D_Triang_Rib_OnlyTriang_Side_3_5_permuted.rpt";
5891  std::string filename8 = filepath + "/2D_Triang_Rib_OnlyTriang_Side_4_5.rpt";
5892  std::string filename9 = filepath + "/2D_Triang_Rib_OnlyTriang_Side_4_5_permuted.rpt";
5893 
5894  TPZAutoPointer<TPZRefPattern> refpat1 = new TPZRefPattern(filename1);
5895  TPZAutoPointer<TPZRefPattern> refpat2 = new TPZRefPattern(filename2);
5896  TPZAutoPointer<TPZRefPattern> refpat3 = new TPZRefPattern(filename3);
5897  TPZAutoPointer<TPZRefPattern> refpat4 = new TPZRefPattern(filename4);
5898  TPZAutoPointer<TPZRefPattern> refpat5 = new TPZRefPattern(filename5);
5899  TPZAutoPointer<TPZRefPattern> refpat6 = new TPZRefPattern(filename6);
5900  TPZAutoPointer<TPZRefPattern> refpat7 = new TPZRefPattern(filename7);
5901  TPZAutoPointer<TPZRefPattern> refpat8 = new TPZRefPattern(filename8);
5902  TPZAutoPointer<TPZRefPattern> refpat9 = new TPZRefPattern(filename9);
5903 
5904  if(!gRefDBase.FindRefPattern(refpat1)) gRefDBase.InsertRefPattern(refpat1);
5905  if(!gRefDBase.FindRefPattern(refpat2)) gRefDBase.InsertRefPattern(refpat2);
5906  if(!gRefDBase.FindRefPattern(refpat3)) gRefDBase.InsertRefPattern(refpat3);
5907  if(!gRefDBase.FindRefPattern(refpat4)) gRefDBase.InsertRefPattern(refpat4);
5908  if(!gRefDBase.FindRefPattern(refpat5)) gRefDBase.InsertRefPattern(refpat5);
5909  if(!gRefDBase.FindRefPattern(refpat6)) gRefDBase.InsertRefPattern(refpat6);
5910  if(!gRefDBase.FindRefPattern(refpat7)) gRefDBase.InsertRefPattern(refpat7);
5911  if(!gRefDBase.FindRefPattern(refpat8)) gRefDBase.InsertRefPattern(refpat8);
5912  if(!gRefDBase.FindRefPattern(refpat9)) gRefDBase.InsertRefPattern(refpat9);
5913 }
5914 /*}}}*/
5915 #endif
AmrNeopzEnum
@ AmrNeopzEnum
Definition: EnumDefinitions.h:975
DataSet::Size
int Size()
Definition: DataSet.cpp:399
FreeSurfaceTopAnalysisEnum
@ FreeSurfaceTopAnalysisEnum
Definition: EnumDefinitions.h:1072
Tria::iscollapsed
int iscollapsed
Definition: Tria.h:32
IceVolumeAboveFloatationScaledEnum
@ IceVolumeAboveFloatationScaledEnum
Definition: EnumDefinitions.h:1113
BalancethicknessAnalysisEnum
@ BalancethicknessAnalysisEnum
Definition: EnumDefinitions.h:981
SOLVER
#define SOLVER
Definition: Profiler.h:16
HydrologySolutionEnum
@ HydrologySolutionEnum
Definition: EnumDefinitions.h:1105
FemModel::TotalCalvingFluxLevelsetx
void TotalCalvingFluxLevelsetx(IssmDouble *pGbmb, bool scaled)
Definition: FemModel.cpp:2929
FrictionCoefficientEnum
@ FrictionCoefficientEnum
Definition: EnumDefinitions.h:574
FemModel::MaxAbsVzx
void MaxAbsVzx(IssmDouble *presponse)
Definition: FemModel.cpp:1811
DamageDOldEnum
@ DamageDOldEnum
Definition: EnumDefinitions.h:517
Element::TotalFloatingBmb
IssmDouble TotalFloatingBmb(IssmDouble *mask, bool scaled)
Definition: Element.cpp:4260
FemModel::AnalysisIndex
int AnalysisIndex(int)
Definition: FemModel.cpp:220
depthaverage_core
void depthaverage_core(FemModel *femmodel)
Definition: depthaverage_core.cpp:12
Vertices::NumberOfVerticesLocal
int NumberOfVerticesLocal(void)
Definition: Vertices.cpp:258
Profiler::TotalTimeModSec
int TotalTimeModSec(int tag)
Definition: Profiler.cpp:123
NewDamageEnum
@ NewDamageEnum
Definition: EnumDefinitions.h:658
Element::lid
int lid
Definition: Element.h:46
QmuResponsePartitionsNpartEnum
@ QmuResponsePartitionsNpartEnum
Definition: EnumDefinitions.h:298
Vertices::Copy
Vertices * Copy()
Definition: Vertices.cpp:57
Vertices::common_recv
int * common_recv
Definition: Vertices.h:22
BaseEnum
@ BaseEnum
Definition: EnumDefinitions.h:495
Vertices
Declaration of Vertices class.
Definition: Vertices.h:15
EnthalpyAnalysisEnum
@ EnthalpyAnalysisEnum
Definition: EnumDefinitions.h:1052
Element::SetIntInput
void SetIntInput(Inputs2 *inputs2, int enum_in, int value)
Definition: Element.cpp:3362
Loads::ResetHooks
void ResetHooks()
Definition: Loads.cpp:164
SmbMassBalanceEnum
@ SmbMassBalanceEnum
Definition: EnumDefinitions.h:748
FemModel::Solve
void Solve(void)
Definition: FemModel.cpp:883
Channel
Definition: Channel.h:18
FemModel::CreateElements
void CreateElements(int newnumberofelements, int elementswidth, int *newelementslist, bool *my_elements, Elements *elements)
Definition: FemModel.cpp:3675
LoveAnalysisEnum
@ LoveAnalysisEnum
Definition: EnumDefinitions.h:1146
Profiler::Memory
IssmPDouble Memory(int tag)
Definition: Profiler.cpp:129
Element::ComputeStrainRate
void ComputeStrainRate()
Definition: Element.cpp:244
AmrGroundingLineDistanceEnum
@ AmrGroundingLineDistanceEnum
Definition: EnumDefinitions.h:20
Element::GetInputListOnNodes
void GetInputListOnNodes(IssmDouble *pvalue, int enumtype)
Definition: Element.cpp:1106
SmbAnalysisEnum
@ SmbAnalysisEnum
Definition: EnumDefinitions.h:1274
FemModel::ElementOperationx
void ElementOperationx(void(Element::*function)(void))
Definition: FemModel.cpp:1243
FemModel::InitFromFiles
void InitFromFiles(char *rootpath, char *inputfilename, char *outputfilename, char *petscfilename, char *lockfilename, char *restartfilename, const int solution_type, bool trace, IssmPDouble *X=NULL)
Definition: FemModel.cpp:393
RotationalPolarMoiEnum
@ RotationalPolarMoiEnum
Definition: EnumDefinitions.h:326
Vertex::z
IssmDouble z
Definition: Vertex.h:30
_assert_
#define _assert_(ignore)
Definition: exceptions.h:37
FemModel::vertices
Vertices * vertices
Definition: FemModel.h:49
IndexEnum
@ IndexEnum
Definition: EnumDefinitions.h:201
TidalLoveK2SecularEnum
@ TidalLoveK2SecularEnum
Definition: EnumDefinitions.h:314
Balancethickness2SolutionEnum
@ Balancethickness2SolutionEnum
Definition: EnumDefinitions.h:980
IssmDouble
double IssmDouble
Definition: types.h:37
IceVolumeScaledEnum
@ IceVolumeScaledEnum
Definition: EnumDefinitions.h:1115
GetMaskOfIceVerticesLSMx0
void GetMaskOfIceVerticesLSMx0(FemModel *femmodel)
Definition: SetActiveNodesLSMx.cpp:59
FemModel::MaxVelx
void MaxVelx(IssmDouble *presponse)
Definition: FemModel.cpp:1855
Element::IsOnBase
bool IsOnBase()
Definition: Element.cpp:1984
Nodes
Declaration of Nodes class.
Definition: Nodes.h:19
InputToDepthaverageOutEnum
@ InputToDepthaverageOutEnum
Definition: EnumDefinitions.h:204
AutodiffDependentObjectsEnum
@ AutodiffDependentObjectsEnum
Definition: EnumDefinitions.h:43
DatasetInput2
Definition: DatasetInput2.h:14
Element::GetIcefrontArea
virtual IssmDouble GetIcefrontArea()
Definition: Element.h:248
FrontalForcingsBasinIcefrontAreaEnum
@ FrontalForcingsBasinIcefrontAreaEnum
Definition: EnumDefinitions.h:152
Element::GetNumberOfNodes
virtual int GetNumberOfNodes(void)=0
InversionNumControlParametersEnum
@ InversionNumControlParametersEnum
Definition: EnumDefinitions.h:223
FemModel::MaxAbsVyx
void MaxAbsVyx(IssmDouble *presponse)
Definition: FemModel.cpp:1786
ExtrudeFromBaseAnalysisEnum
@ ExtrudeFromBaseAnalysisEnum
Definition: EnumDefinitions.h:1058
MasstransportAnalysisEnum
@ MasstransportAnalysisEnum
Definition: EnumDefinitions.h:1163
Vertices::common_send
int * common_send
Definition: Vertices.h:24
BalancevelocityAnalysisEnum
@ BalancevelocityAnalysisEnum
Definition: EnumDefinitions.h:987
_printf0_
#define _printf0_(StreamArgs)
Definition: Print.h:29
ISSM_MPI_Allreduce
int ISSM_MPI_Allreduce(void *sendbuf, void *recvbuf, int count, ISSM_MPI_Datatype datatype, ISSM_MPI_Op op, ISSM_MPI_Comm comm)
Definition: issmmpi.cpp:116
Gradient2Enum
@ Gradient2Enum
Definition: EnumDefinitions.h:1087
FemModel::GetLocalVectorWithClonesGset
void GetLocalVectorWithClonesGset(IssmDouble **plocal_ug, Vector< IssmDouble > *ug)
Definition: FemModel.cpp:1337
Element::FindParam
void FindParam(bool *pvalue, int paramenum)
Definition: Element.cpp:933
ElementHook::SetHookNodes
void SetHookNodes(int *node_ids, int numnodes, int analysis_counter)
Definition: ElementHook.cpp:188
Element::SetBoolInput
void SetBoolInput(Inputs2 *inputs2, int enum_in, bool value)
Definition: Element.cpp:3355
Profiler::TotalFlops
IssmPDouble TotalFlops(int tag)
Definition: Profiler.cpp:87
MeshElementsEnum
@ MeshElementsEnum
Definition: EnumDefinitions.h:1183
AmrThicknessErrorResolutionEnum
@ AmrThicknessErrorResolutionEnum
Definition: EnumDefinitions.h:32
GroundinglineMassFluxEnum
@ GroundinglineMassFluxEnum
Definition: EnumDefinitions.h:1092
StressbalanceAnalysisEnum
@ StressbalanceAnalysisEnum
Definition: EnumDefinitions.h:1285
BasalforcingsEnum
@ BasalforcingsEnum
Definition: EnumDefinitions.h:64
FloatingAreaScaledEnum
@ FloatingAreaScaledEnum
Definition: EnumDefinitions.h:1068
BalancethicknessThickeningRateEnum
@ BalancethicknessThickeningRateEnum
Definition: EnumDefinitions.h:474
AdaptiveMeshRefinement
Definition: AdaptiveMeshRefinement.h:12
FemModel::InputMakeDiscontinuous
void InputMakeDiscontinuous(int enum_in)
Definition: FemModel.cpp:1611
RestartFileNameEnum
@ RestartFileNameEnum
Definition: EnumDefinitions.h:299
StepEnum
@ StepEnum
Definition: EnumDefinitions.h:403
Parameters::Exist
bool Exist(int enum_type)
Definition: Parameters.cpp:254
FemModel::MinVyx
void MinVyx(IssmDouble *presponse)
Definition: FemModel.cpp:2005
HydrologydcEnum
@ HydrologydcEnum
Definition: EnumDefinitions.h:1106
DebugProfilingEnum
@ DebugProfilingEnum
Definition: EnumDefinitions.h:122
TransientInput2::Configure
void Configure(Parameters *params)
Definition: TransientInput2.cpp:104
DataSet::AddObject
int AddObject(Object *object)
Definition: DataSet.cpp:252
Nodes::common_send
int * common_send
Definition: Nodes.h:28
FlowequationIsSSAEnum
@ FlowequationIsSSAEnum
Definition: EnumDefinitions.h:142
_printf_
#define _printf_(StreamArgs)
Definition: Print.h:22
HydrologydcMaskEplactiveNodeEnum
@ HydrologydcMaskEplactiveNodeEnum
Definition: EnumDefinitions.h:608
BalancethicknessMisfitEnum
@ BalancethicknessMisfitEnum
Definition: EnumDefinitions.h:471
InversionControlParametersEnum
@ InversionControlParametersEnum
Definition: EnumDefinitions.h:209
RotationalAngularVelocityEnum
@ RotationalAngularVelocityEnum
Definition: EnumDefinitions.h:307
TotalFloatingBmbScaledEnum
@ TotalFloatingBmbScaledEnum
Definition: EnumDefinitions.h:1308
FemModel::InitTransientInputx
void InitTransientInputx(int *transientinput_enum, int numoutputs)
Definition: FemModel.cpp:5202
DescriptorIndex
int DescriptorIndex(char *root, int *pindex, char *descriptor)
Definition: DescriptorIndex.cpp:20
MinVyEnum
@ MinVyEnum
Definition: EnumDefinitions.h:1188
FemModel::nummodels
int nummodels
Definition: FemModel.h:39
MaskOceanLevelsetEnum
@ MaskOceanLevelsetEnum
Definition: EnumDefinitions.h:640
Balancethickness2AnalysisEnum
@ Balancethickness2AnalysisEnum
Definition: EnumDefinitions.h:979
FemModel::BalancethicknessMisfitx
void BalancethicknessMisfitx(IssmDouble *pV)
Definition: FemModel.cpp:962
InversionCostFunctionsCoefficientsEnum
@ InversionCostFunctionsCoefficientsEnum
Definition: EnumDefinitions.h:629
Parameters
Declaration of Parameters class.
Definition: Parameters.h:18
ExtrudeFromTopAnalysisEnum
@ ExtrudeFromTopAnalysisEnum
Definition: EnumDefinitions.h:1059
FemModel::EtaDiffx
void EtaDiffx(IssmDouble *pJ)
Definition: FemModel.cpp:2112
TransientSolutionEnum
@ TransientSolutionEnum
Definition: EnumDefinitions.h:1317
MaskIceLevelsetEnum
@ MaskIceLevelsetEnum
Definition: EnumDefinitions.h:641
VerboseMProcessor
bool VerboseMProcessor(void)
Definition: Verbosity.cpp:22
ISSM_MPI_SUM
#define ISSM_MPI_SUM
Definition: issmmpi.h:134
BalancethicknessSoftSolutionEnum
@ BalancethicknessSoftSolutionEnum
Definition: EnumDefinitions.h:984
FemModel::parameters
Parameters * parameters
Definition: FemModel.h:46
Vertex::clone
bool clone
Definition: Vertex.h:22
TimeEnum
@ TimeEnum
Definition: EnumDefinitions.h:427
ADD_VAL
@ ADD_VAL
Definition: toolkitsenums.h:14
CreateVertices
void CreateVertices(Elements *elements, Vertices *vertices, IoModel *iomodel, int solution_type, bool isamr)
Definition: CreateElementsVerticesAndMaterials.cpp:301
MARSHALLING_ENUM
#define MARSHALLING_ENUM(EN)
Definition: Marshalling.h:14
IssmComm::GetComm
static ISSM_MPI_Comm GetComm(void)
Definition: IssmComm.cpp:30
DepthAverageAnalysisEnum
@ DepthAverageAnalysisEnum
Definition: EnumDefinitions.h:1036
DeviatoricStressxxEnum
@ DeviatoricStressxxEnum
Definition: EnumDefinitions.h:524
BalancevelocitySolutionEnum
@ BalancevelocitySolutionEnum
Definition: EnumDefinitions.h:988
Constraints
Declaration of Constraints class.
Definition: Constraints.h:13
DamageEvolutionAnalysisEnum
@ DamageEvolutionAnalysisEnum
Definition: EnumDefinitions.h:1026
BedEnum
@ BedEnum
Definition: EnumDefinitions.h:499
AmrThicknessErrorThresholdEnum
@ AmrThicknessErrorThresholdEnum
Definition: EnumDefinitions.h:33
Element::SpawnBasalElement
virtual Element * SpawnBasalElement(void)=0
P0Enum
@ P0Enum
Definition: EnumDefinitions.h:661
TransientInput2
Definition: TransientInput2.h:13
HydrologydcMaskThawedNodeEnum
@ HydrologydcMaskThawedNodeEnum
Definition: EnumDefinitions.h:610
OutputFileNameEnum
@ OutputFileNameEnum
Definition: EnumDefinitions.h:283
FemModel::Size
int Size(void)
Definition: FemModel.cpp:638
FemModel::StrainRateeffectivex
void StrainRateeffectivex()
Definition: FemModel.cpp:2646
Element::IceVolumeAboveFloatation
IssmDouble IceVolumeAboveFloatation(IssmDouble *mask, bool scaled)
Definition: Element.cpp:1607
FemModel::CostFunctionx
void CostFunctionx(IssmDouble *pJ, IssmDouble **pJlist, int *pn)
Definition: FemModel.cpp:1062
Element::CalvingRateVonmises
virtual void CalvingRateVonmises(void)
Definition: Element.h:221
Element::ResultToVector
void ResultToVector(Vector< IssmDouble > *vector, int output_enum)
Definition: Element.cpp:3299
GROUNDINGLINECORE
#define GROUNDINGLINECORE
Definition: Profiler.h:25
ToolkitsOptionsFromAnalysis
void ToolkitsOptionsFromAnalysis(Parameters *parameters, int analysis_type)
Element::TimeAdapt
virtual IssmDouble TimeAdapt()=0
AmrLagEnum
@ AmrLagEnum
Definition: EnumDefinitions.h:27
Element::MassFlux
virtual IssmDouble MassFlux(IssmDouble *segment)=0
MARSHALLING_SIZE
@ MARSHALLING_SIZE
Definition: Marshalling.h:11
Nodes::NumberOfNodesLocalAll
int NumberOfNodesLocalAll(void)
Definition: Nodes.cpp:364
FemModel::GetMeshOnPartition
void GetMeshOnPartition(Vertices *femmodel_vertices, Elements *femmodel_elements, IssmDouble **px, IssmDouble **py, IssmDouble **pz, int **pelementslist, int **psidtoindex)
Definition: FemModel.cpp:3837
Elements
Declaration of Elements class.
Definition: Elements.h:17
GetVectorFromInputsx
void GetVectorFromInputsx(IssmDouble **pvector, int *pvector_size, FemModel *femmodel, int name)
Definition: GetVectorFromInputsx.cpp:81
ThicknessAbsMisfitx
void ThicknessAbsMisfitx(IssmDouble *pJ, Elements *elements, Nodes *nodes, Vertices *vertices, Loads *loads, Materials *materials, Parameters *parameters)
Definition: ThicknessAbsMisfitx.cpp:11
FemModel::SolutionAnalysesList
void SolutionAnalysesList(int **panalyses, int *pnumanalyses, IoModel *iomodel, int solutiontype)
Definition: FemModel.cpp:646
FemModel::results
Results * results
Definition: FemModel.h:48
Vertices::NumberOfVertices
int NumberOfVertices(void)
Definition: Vertices.cpp:255
Vector::GetLocalVector
void GetLocalVector(doubletype **pvector, int **pindices)
Definition: Vector.h:219
BalancethicknessSolutionEnum
@ BalancethicknessSolutionEnum
Definition: EnumDefinitions.h:985
ElementInput2.h
ISSM_MPI_MAX
#define ISSM_MPI_MAX
Definition: issmmpi.h:131
TotalSmbScaledEnum
@ TotalSmbScaledEnum
Definition: EnumDefinitions.h:1312
MaterialsRhoIceEnum
@ MaterialsRhoIceEnum
Definition: EnumDefinitions.h:264
MismipFloatingMeltRateEnum
@ MismipFloatingMeltRateEnum
Definition: EnumDefinitions.h:1190
SpcStatic::GetValue
IssmDouble GetValue()
Definition: SpcStatic.cpp:164
CORE
#define CORE
Definition: Profiler.h:15
Gradient1Enum
@ Gradient1Enum
Definition: EnumDefinitions.h:1086
FemModel::CalvingMeltingFluxLevelsetx
void CalvingMeltingFluxLevelsetx()
Definition: FemModel.cpp:1054
Element::GroundedArea
IssmDouble GroundedArea(IssmDouble *mask, bool scaled)
Definition: Element.cpp:1548
P1DGEnum
@ P1DGEnum
Definition: EnumDefinitions.h:1215
Node::clone
bool clone
Definition: Node.h:27
ThicknessPositiveEnum
@ ThicknessPositiveEnum
Definition: EnumDefinitions.h:842
FemModel::Echo
void Echo()
Definition: FemModel.cpp:382
Element::vertices
Vertex ** vertices
Definition: Element.h:49
FemModel::TotalCalvingMeltingFluxLevelsetx
void TotalCalvingMeltingFluxLevelsetx(IssmDouble *pGbmb, bool scaled)
Definition: FemModel.cpp:2945
SurfaceRelVelMisfitEnum
@ SurfaceRelVelMisfitEnum
Definition: EnumDefinitions.h:828
Element::WriteFieldIsovalueSegment
virtual void WriteFieldIsovalueSegment(DataSet *segments, int fieldenum, IssmDouble fieldvalue)
Definition: Element.h:366
FreeSurfaceBaseAnalysisEnum
@ FreeSurfaceBaseAnalysisEnum
Definition: EnumDefinitions.h:1071
DamageEvolutionSolutionEnum
@ DamageEvolutionSolutionEnum
Definition: EnumDefinitions.h:1027
HydrologyShaktiAnalysisEnum
@ HydrologyShaktiAnalysisEnum
Definition: EnumDefinitions.h:1103
AnalysisCounterEnum
@ AnalysisCounterEnum
Definition: EnumDefinitions.h:35
SpcStatic::GetNodeId
int GetNodeId()
Definition: SpcStatic.cpp:159
IoModel::my_elements
bool * my_elements
Definition: IoModel.h:66
AmrGroundingLineResolutionEnum
@ AmrGroundingLineResolutionEnum
Definition: EnumDefinitions.h:21
BasalforcingsPicoEnum
@ BasalforcingsPicoEnum
Definition: EnumDefinitions.h:990
pfopen
FILE * pfopen(char *filename, const char *format, bool errorout=true)
Definition: pfopen.cpp:30
EsaAnalysisEnum
@ EsaAnalysisEnum
Definition: EnumDefinitions.h:1053
FemModel::~FemModel
~FemModel()
Definition: FemModel.cpp:172
MasstransportStabilizationEnum
@ MasstransportStabilizationEnum
Definition: EnumDefinitions.h:249
Element::StrainRateparallel
virtual void StrainRateparallel(void)=0
Nodes::common_recv_ids
int ** common_recv_ids
Definition: Nodes.h:27
FemModel::AdjustBaseThicknessAndMask
void AdjustBaseThicknessAndMask(void)
Definition: FemModel.cpp:3314
Contour
Definition: Contour.h:15
Vertex::x
IssmDouble x
Definition: Vertex.h:28
SolidearthSettingsRigidEnum
@ SolidearthSettingsRigidEnum
Definition: EnumDefinitions.h:329
AmrRestartEnum
@ AmrRestartEnum
Definition: EnumDefinitions.h:29
Outputdefinition100Enum
@ Outputdefinition100Enum
Definition: EnumDefinitions.h:964
FemModel::ThicknessAverage
void ThicknessAverage()
Definition: FemModel.cpp:2774
HydrologyPismAnalysisEnum
@ HydrologyPismAnalysisEnum
Definition: EnumDefinitions.h:1102
FemModel::Marshall
void Marshall(char **pmarshalled_data, int *pmarshalled_data_size, int marshall_direction)
Definition: FemModel.cpp:464
FemModel::OutputControlsx
void OutputControlsx(Results **presults)
Definition: FemModel.cpp:2171
AmrLevelMaxEnum
@ AmrLevelMaxEnum
Definition: EnumDefinitions.h:28
AmrHmaxEnum
@ AmrHmaxEnum
Definition: EnumDefinitions.h:22
FemModel::CalvingFluxLevelsetx
void CalvingFluxLevelsetx()
Definition: FemModel.cpp:1046
Element::TotalCalvingFluxLevelset
virtual IssmDouble TotalCalvingFluxLevelset(bool scaled)
Definition: Element.h:350
FemModel::TimeAdaptx
void TimeAdaptx(IssmDouble *pdt)
Definition: FemModel.cpp:2895
DeviatoricStressxyEnum
@ DeviatoricStressxyEnum
Definition: EnumDefinitions.h:525
FemModel::constraints_list
Constraints ** constraints_list
Definition: FemModel.h:53
Element::Sid
int Sid()
Definition: Element.cpp:3578
SealevelriseSolutionEnum
@ SealevelriseSolutionEnum
Definition: EnumDefinitions.h:1267
FemModel::SmoothedDeviatoricStressTensor
void SmoothedDeviatoricStressTensor(IssmDouble **ptauxx, IssmDouble **ptauyy, IssmDouble **ptauxy)
Definition: FemModel.cpp:4018
Element::ResultToPatch
void ResultToPatch(IssmDouble *values, int nodesperelement, int output_enum)
Definition: Element.cpp:3270
HydrologyDCEfficientAnalysis::HydrologyEPLGetActive
void HydrologyEPLGetActive(Vector< IssmDouble > *active_vec, Element *element)
Definition: HydrologyDCEfficientAnalysis.cpp:808
DatasetInput2::GetInputValue
void GetInputValue(IssmDouble *pvalue, Gauss *gauss, int index)
Definition: DatasetInput2.cpp:199
ExternalResult::GetValue
virtual double GetValue(void)=0
SolidearthSettingsHorizEnum
@ SolidearthSettingsHorizEnum
Definition: EnumDefinitions.h:323
Element::ControlToVectors
virtual void ControlToVectors(Vector< IssmPDouble > *vector_control, Vector< IssmPDouble > *vector_gradient, int control_enum)=0
SettingsResultsOnNodesEnum
@ SettingsResultsOnNodesEnum
Definition: EnumDefinitions.h:338
VerboseModule
bool VerboseModule(void)
Definition: Verbosity.cpp:23
TransientIsgroundinglineEnum
@ TransientIsgroundinglineEnum
Definition: EnumDefinitions.h:447
DragCoefficientAbsGradientEnum
@ DragCoefficientAbsGradientEnum
Definition: EnumDefinitions.h:537
Inputs2::SetTriaInput
void SetTriaInput(int enum_in, int interpolation, int row, IssmDouble values)
Definition: Inputs2.cpp:768
ConfigureObjectsx
int ConfigureObjectsx(Elements *elements, Loads *loads, Nodes *nodes, Vertices *vertices, Materials *materials, Parameters *parameters, Inputs2 *inputs2)
Definition: ConfigureObjectsx.cpp:11
AmrDeviatoricErrorThresholdEnum
@ AmrDeviatoricErrorThresholdEnum
Definition: EnumDefinitions.h:16
Element::isonbase
bool isonbase
Definition: Element.h:53
TidalLoveKEnum
@ TidalLoveKEnum
Definition: EnumDefinitions.h:312
FemModel::TotalSmbx
void TotalSmbx(IssmDouble *pSmb, bool scaled)
Definition: FemModel.cpp:2993
Vertices::common_recv_ids
int ** common_recv_ids
Definition: Vertices.h:23
VyEnum
@ VyEnum
Definition: EnumDefinitions.h:850
Nodes::Marshall
void Marshall(char **pmarshalled_data, int *pmarshalled_data_size, int marshall_direction)
Definition: Nodes.cpp:105
Element::ComputeNewDamage
void ComputeNewDamage()
Definition: Element.cpp:144
ProfilingCurrentFlopsEnum
@ ProfilingCurrentFlopsEnum
Definition: EnumDefinitions.h:1234
Parameters::Copy
Parameters * Copy(void)
Definition: Parameters.cpp:86
Element::FloatingArea
IssmDouble FloatingArea(IssmDouble *mask, bool scaled)
Definition: Element.cpp:948
QmuResponsePartitionsEnum
@ QmuResponsePartitionsEnum
Definition: EnumDefinitions.h:297
Parameters::AddObject
void AddObject(Param *newparam)
Definition: Parameters.cpp:67
SmoothAnalysisEnum
@ SmoothAnalysisEnum
Definition: EnumDefinitions.h:1276
Element::UpdateConstraintsExtrudeFromTop
virtual void UpdateConstraintsExtrudeFromTop(void)=0
Input2::GetInputMaxAbs
virtual IssmDouble GetInputMaxAbs(void)
Definition: Input2.h:35
FemModel::RequestedDependentsx
void RequestedDependentsx(void)
Definition: FemModel.cpp:2220
HydrologyDCEfficientAnalysis
Definition: HydrologyDCEfficientAnalysis.h:12
SpcStatic
Definition: SpcStatic.h:13
ScaledEnum
@ ScaledEnum
Definition: EnumDefinitions.h:1258
Input2::GetInputMax
virtual IssmDouble GetInputMax(void)
Definition: Input2.h:34
SurfaceLogVxVyMisfitx
void SurfaceLogVxVyMisfitx(IssmDouble *pJ, Elements *elements, Nodes *nodes, Vertices *vertices, Loads *loads, Materials *materials, Parameters *parameters)
Definition: SurfaceLogVxVyMisfitx.cpp:11
SurfaceLogVxVyMisfitEnum
@ SurfaceLogVxVyMisfitEnum
Definition: EnumDefinitions.h:826
FemModel::GetLocalVectorWithClonesVertices
void GetLocalVectorWithClonesVertices(IssmDouble **plocal_vector, Vector< IssmDouble > *vector)
Definition: FemModel.cpp:1342
Loads::Copy
Loads * Copy()
Definition: Loads.cpp:42
Vertex::UpdatePosition
void UpdatePosition(Vector< IssmDouble > *vx, Vector< IssmDouble > *vy, Vector< IssmDouble > *vz, Parameters *parameters, IssmDouble *thickness, IssmDouble *bed)
Definition: Vertex.cpp:170
Input2::GetInputDerivativeValue
virtual void GetInputDerivativeValue(IssmDouble *derivativevalues, IssmDouble *xyz_list, Gauss *gauss)
Definition: Input2.h:37
ElementHook::hmaterial
Hook * hmaterial
Definition: ElementHook.h:17
HydrologyDCInefficientAnalysisEnum
@ HydrologyDCInefficientAnalysisEnum
Definition: EnumDefinitions.h:1099
TotalGroundedBmbEnum
@ TotalGroundedBmbEnum
Definition: EnumDefinitions.h:1309
FemModel::InitFromFids
void InitFromFids(char *rootpath, FILE *IOMODEL, FILE *toolkitsoptionsfid, int in_solution_type, bool trace, IssmPDouble *X=NULL)
Definition: FemModel.cpp:424
ElementInput2
Definition: ElementInput2.h:7
MaterialsRheologyBbarEnum
@ MaterialsRheologyBbarEnum
Definition: EnumDefinitions.h:644
Vertex::GetY
IssmDouble GetY(void)
Definition: Vertex.cpp:156
SurfaceAbsVelMisfitEnum
@ SurfaceAbsVelMisfitEnum
Definition: EnumDefinitions.h:818
Element::StressIntensityFactor
virtual void StressIntensityFactor(void)=0
FemModel::MeanGroundedIceLevelSet
void MeanGroundedIceLevelSet(IssmDouble **pmasklevelset)
Definition: FemModel.cpp:4330
Element::GetInput2
virtual Input2 * GetInput2(int inputenum)=0
AmrHminEnum
@ AmrHminEnum
Definition: EnumDefinitions.h:23
Element::DeleteMaterials
void DeleteMaterials(void)
Definition: Element.cpp:429
pfopen0
FILE * pfopen0(char *filename, const char *format)
Definition: pfopen.cpp:16
SmbSolutionEnum
@ SmbSolutionEnum
Definition: EnumDefinitions.h:1275
FemModel::Divergencex
void Divergencex(IssmDouble *pdiv)
Definition: FemModel.cpp:1227
HydrologyGlaDSAnalysisEnum
@ HydrologyGlaDSAnalysisEnum
Definition: EnumDefinitions.h:1100
Element::nodes
Node ** nodes
Definition: Element.h:48
SpcStatic::GetDof
int GetDof()
Definition: SpcStatic.cpp:155
Element
Definition: Element.h:41
Element::NodalFunctions
virtual void NodalFunctions(IssmDouble *basis, Gauss *gauss)=0
EtaDiffEnum
@ EtaDiffEnum
Definition: EnumDefinitions.h:569
FemModel::CalvingRateLevermannx
void CalvingRateLevermannx()
Definition: FemModel.cpp:1038
MARSHALLING_DYNAMIC
#define MARSHALLING_DYNAMIC(FIELD, TYPE, SIZE)
Definition: Marshalling.h:61
Element::IcefrontMassFlux
virtual IssmDouble IcefrontMassFlux(bool scaled)
Definition: Element.h:271
MaxVxEnum
@ MaxVxEnum
Definition: EnumDefinitions.h:1178
IoModel::numberofvertices
int numberofvertices
Definition: IoModel.h:99
P1Enum
@ P1Enum
Definition: EnumDefinitions.h:662
FemModel::OmegaAbsGradientx
void OmegaAbsGradientx(IssmDouble *pJ)
Definition: FemModel.cpp:2055
VzMeshEnum
@ VzMeshEnum
Definition: EnumDefinitions.h:856
HydrologyDCEfficientAnalysis::HydrologyEPLGetMask
void HydrologyEPLGetMask(Vector< IssmDouble > *vec_mask, Vector< IssmDouble > *recurence, Element *element)
Definition: HydrologyDCEfficientAnalysis.cpp:714
Element::GetDatasetInput2
virtual DatasetInput2 * GetDatasetInput2(int inputenum)
Definition: Element.h:250
Domain2DhorizontalEnum
@ Domain2DhorizontalEnum
Definition: EnumDefinitions.h:534
VyMeshEnum
@ VyMeshEnum
Definition: EnumDefinitions.h:851
ISSM_MPI_DOUBLE
#define ISSM_MPI_DOUBLE
Definition: issmmpi.h:125
Element::ElementResponse
virtual void ElementResponse(IssmDouble *presponse, int response_enum)=0
ThermalSolutionEnum
@ ThermalSolutionEnum
Definition: EnumDefinitions.h:1303
ChannelEnum
@ ChannelEnum
Definition: EnumDefinitions.h:1008
MeltingAnalysisEnum
@ MeltingAnalysisEnum
Definition: EnumDefinitions.h:1182
Nodes::NumberOfNodes
int NumberOfNodes(void)
Definition: Nodes.cpp:354
ExternalResult
Definition: ExternalResult.h:21
ExtrapolationAnalysisEnum
@ ExtrapolationAnalysisEnum
Definition: EnumDefinitions.h:1057
FemModel::MaxAbsVxx
void MaxAbsVxx(IssmDouble *presponse)
Definition: FemModel.cpp:1761
UzawaPressureAnalysisEnum
@ UzawaPressureAnalysisEnum
Definition: EnumDefinitions.h:1320
IoModel::AddConstant
void AddConstant(IoConstant *constant_in)
Definition: IoModel.cpp:288
Parameters::SetParam
void SetParam(bool boolean, int enum_type)
Definition: Parameters.cpp:441
LATaylorHoodEnum
@ LATaylorHoodEnum
Definition: EnumDefinitions.h:1139
ISSM_MPI_INT
#define ISSM_MPI_INT
Definition: issmmpi.h:127
GenericParam::GetParameterValue
P & GetParameterValue()
Definition: GenericParam.h:62
BalancethicknessOmegaEnum
@ BalancethicknessOmegaEnum
Definition: EnumDefinitions.h:473
SMBCORE
#define SMBCORE
Definition: Profiler.h:24
IoModel::numberofelements
int numberofelements
Definition: IoModel.h:96
DependentObject
Definition: DependentObject.h:15
GiaSolutionEnum
@ GiaSolutionEnum
Definition: EnumDefinitions.h:1085
SurfaceAbsMisfitEnum
@ SurfaceAbsMisfitEnum
Definition: EnumDefinitions.h:817
Nodes::common_send_ids
int ** common_send_ids
Definition: Nodes.h:29
FemModel::SyncLocalVectorWithClonesVertices
void SyncLocalVectorWithClonesVertices(IssmDouble *local_vector)
Definition: FemModel.cpp:1366
Gradient3Enum
@ Gradient3Enum
Definition: EnumDefinitions.h:1088
Element::Divergence
IssmDouble Divergence(void)
Definition: Element.cpp:720
FemModel::HydrologyIDSupdateDomainx
void HydrologyIDSupdateDomainx(IssmDouble *pIDScount)
Definition: FemModel.cpp:5072
L2ProjectionBaseAnalysisEnum
@ L2ProjectionBaseAnalysisEnum
Definition: EnumDefinitions.h:1136
VertexSIdEnum
@ VertexSIdEnum
Definition: EnumDefinitions.h:1325
GiaAnalysisEnum
@ GiaAnalysisEnum
Definition: EnumDefinitions.h:1084
BasalforcingsGroundediceMeltingRateEnum
@ BasalforcingsGroundediceMeltingRateEnum
Definition: EnumDefinitions.h:478
FemModel::HydrologyEPLupdateDomainx
void HydrologyEPLupdateDomainx(IssmDouble *pEplcount)
Definition: FemModel.cpp:4965
MeshYEnum
@ MeshYEnum
Definition: EnumDefinitions.h:1185
Element::GroundinglineMassFlux
virtual IssmDouble GroundinglineMassFlux(bool scaled)
Definition: Element.h:273
Element::TotalCalvingMeltingFluxLevelset
virtual IssmDouble TotalCalvingMeltingFluxLevelset(bool scaled)
Definition: Element.h:351
Element::inputs2
Inputs2 * inputs2
Definition: Element.h:47
Materials
Declaration of Materials class.
Definition: Materials.h:16
Element::id
int id
Definition: Element.h:44
FemModel::StressIntensityFactorx
void StressIntensityFactorx()
Definition: FemModel.cpp:2654
FemModel::UpdateConstraintsx
void UpdateConstraintsx(void)
Definition: FemModel.cpp:3027
Element::IceVolume
IssmDouble IceVolume(IssmDouble *mask, bool scaled)
Definition: Element.cpp:1594
Element::sid
int sid
Definition: Element.h:45
FemModel::IceVolumex
void IceVolumex(IssmDouble *pV, bool scaled)
Definition: FemModel.cpp:1687
Vector::SetValues
void SetValues(int ssize, int *list, doubletype *values, InsMode mode)
Definition: Vector.h:153
DomainTypeEnum
@ DomainTypeEnum
Definition: EnumDefinitions.h:124
Vertex::GetX
IssmDouble GetX(void)
Definition: Vertex.cpp:152
VxAverageEnum
@ VxAverageEnum
Definition: EnumDefinitions.h:845
DAMAGECORE
#define DAMAGECORE
Definition: Profiler.h:21
FemModel::nodes
Nodes * nodes
Definition: FemModel.h:56
ProfilingSolutionTimeEnum
@ ProfilingSolutionTimeEnum
Definition: EnumDefinitions.h:1236
Element::AddInput2
virtual void AddInput2(int input_enum, IssmDouble *values, int interpolation_enum)
Definition: Element.h:216
InputUpdateFromVectorx
void InputUpdateFromVectorx(FemModel *femmodel, Vector< IssmDouble > *vector, int name, int type)
Definition: InputUpdateFromVectorx.cpp:9
Element::Id
int Id()
Definition: Element.cpp:1620
HydrologyDCInefficientAnalysis::ElementizeIdsMask
void ElementizeIdsMask(FemModel *femmodel)
Definition: HydrologyDCInefficientAnalysis.cpp:816
FemModel::MinVelx
void MinVelx(IssmDouble *presponse)
Definition: FemModel.cpp:1955
Element::NewGauss
virtual Gauss * NewGauss(void)=0
FrontalForcingsNumberofBasinsEnum
@ FrontalForcingsNumberofBasinsEnum
Definition: EnumDefinitions.h:153
InversionCostFunctionsEnum
@ InversionCostFunctionsEnum
Definition: EnumDefinitions.h:211
FemModel::analysis_counter
int analysis_counter
Definition: FemModel.h:37
FemModel::GetInputLocalMinMaxOnNodesx
void GetInputLocalMinMaxOnNodesx(IssmDouble **pmin, IssmDouble **pmax, IssmDouble *ug)
Definition: FemModel.cpp:1308
InputFileNameEnum
@ InputFileNameEnum
Definition: EnumDefinitions.h:202
ThicknessAlongGradientx
void ThicknessAlongGradientx(IssmDouble *pJ, Elements *elements, Nodes *nodes, Vertices *vertices, Loads *loads, Materials *materials, Parameters *parameters)
Definition: ThicknessAlongGradientx.cpp:11
Profiler
Definition: Profiler.h:33
VzEnum
@ VzEnum
Definition: EnumDefinitions.h:853
FemModel::materials
Materials * materials
Definition: FemModel.h:45
EnumToStringx
const char * EnumToStringx(int enum_in)
Definition: EnumToStringx.cpp:15
Hook
Definition: Hook.h:16
LevelsetAnalysisEnum
@ LevelsetAnalysisEnum
Definition: EnumDefinitions.h:1141
DeviatoricStressyyEnum
@ DeviatoricStressyyEnum
Definition: EnumDefinitions.h:527
Element::element_type_list
int * element_type_list
Definition: Element.h:55
FemModel::DeviatoricStressx
void DeviatoricStressx()
Definition: FemModel.cpp:1095
MaxAbsVxEnum
@ MaxAbsVxEnum
Definition: EnumDefinitions.h:1173
DomainDimensionEnum
@ DomainDimensionEnum
Definition: EnumDefinitions.h:123
FemModel::MinVxx
void MinVxx(IssmDouble *presponse)
Definition: FemModel.cpp:1980
CreateNumberNodeToElementConnectivity
void CreateNumberNodeToElementConnectivity(IoModel *iomodel)
Definition: CreateNumberNodeToElementConnectivity.cpp:16
IssmComm::GetSize
static int GetSize(void)
Definition: IssmComm.cpp:46
NodesDofx
void NodesDofx(Nodes *nodes, Parameters *parameters)
Definition: NodesDofx.cpp:10
GsetEnum
@ GsetEnum
Definition: EnumDefinitions.h:1093
ThicknessAlongGradientEnum
@ ThicknessAlongGradientEnum
Definition: EnumDefinitions.h:839
AmrIceFrontDistanceEnum
@ AmrIceFrontDistanceEnum
Definition: EnumDefinitions.h:24
MinVxEnum
@ MinVxEnum
Definition: EnumDefinitions.h:1187
HydrologyDCInefficientAnalysis
Definition: HydrologyDCInefficientAnalysis.h:12
FemModel::analysis_type_list
int * analysis_type_list
Definition: FemModel.h:38
Nodes::GetLocalVectorWithClonesGset
void GetLocalVectorWithClonesGset(IssmDouble **plocal_vector, Vector< IssmDouble > *vector)
Definition: Nodes.cpp:463
IssmComm::SetComm
static void SetComm(void)
Definition: IssmComm.cpp:22
FemModel::GetElementsWidth
int GetElementsWidth()
Definition: FemModel.h:79
StressbalanceSolutionEnum
@ StressbalanceSolutionEnum
Definition: EnumDefinitions.h:1288
IoModel::FindConstant
void FindConstant(bool *pvalue, const char *constant_name)
Definition: IoModel.cpp:2362
MASSTRANSPORTCORE
#define MASSTRANSPORTCORE
Definition: Profiler.h:23
TidalLoveHEnum
@ TidalLoveHEnum
Definition: EnumDefinitions.h:311
SurfaceRelVelMisfitx
void SurfaceRelVelMisfitx(IssmDouble *pJ, Elements *elements, Nodes *nodes, Vertices *vertices, Loads *loads, Materials *materials, Parameters *parameters)
Definition: SurfaceRelVelMisfitx.cpp:11
Element::TotalSmb
IssmDouble TotalSmb(IssmDouble *mask, bool scaled)
Definition: Element.cpp:4286
DamageDEnum
@ DamageDEnum
Definition: EnumDefinitions.h:516
EplZigZagCounterEnum
@ EplZigZagCounterEnum
Definition: EnumDefinitions.h:130
ToolkitsFileNameEnum
@ ToolkitsFileNameEnum
Definition: EnumDefinitions.h:438
Element::GetInput2Value
void GetInput2Value(bool *pvalue, int enum_type)
Definition: Element.cpp:1185
FemModel::CalvingRateVonmisesx
void CalvingRateVonmisesx()
Definition: FemModel.cpp:1030
FemModel::TotalFloatingBmbx
void TotalFloatingBmbx(IssmDouble *pFbmb, bool scaled)
Definition: FemModel.cpp:2961
MasstransportSolutionEnum
@ MasstransportSolutionEnum
Definition: EnumDefinitions.h:1164
AmrErrEnum
@ AmrErrEnum
Definition: EnumDefinitions.h:17
MOVINGFRONTCORE
#define MOVINGFRONTCORE
Definition: Profiler.h:22
FemModel::ZZErrorEstimator
void ZZErrorEstimator(IssmDouble **pelementerror)
Definition: FemModel.cpp:4106
FemModel::AverageTransientInputx
void AverageTransientInputx(int *transientinput_enum, int *averagedinput_enum, IssmDouble init_time, IssmDouble end_time, int numoutputs, int averaging_method)
Definition: FemModel.cpp:5246
ISSM_MPI_MIN
#define ISSM_MPI_MIN
Definition: issmmpi.h:132
MARSHALLING
#define MARSHALLING(FIELD)
Definition: Marshalling.h:29
OmegaAbsGradientEnum
@ OmegaAbsGradientEnum
Definition: EnumDefinitions.h:660
Element::GetVerticesCoordinates
void GetVerticesCoordinates(IssmDouble **xyz_list)
Definition: Element.cpp:1446
SurfaceAbsVelMisfitx
void SurfaceAbsVelMisfitx(IssmDouble *pJ, Elements *elements, Nodes *nodes, Vertices *vertices, Loads *loads, Materials *materials, Parameters *parameters)
Definition: SurfaceAbsVelMisfitx.cpp:11
Inputs2::ChangeEnum
void ChangeEnum(int enumtype, int new_enumtype)
Definition: Inputs2.cpp:170
AverageOntoPartitionx
void AverageOntoPartitionx(double **paverage, Elements *elements, Nodes *nodes, Vertices *vertices, Loads *loads, Materials *materials, Parameters *parameters, double *vertex_response, double *qmu_part, int npart)
Definition: AverageOntoPartitionx.cpp:16
FemModel::MaxVyx
void MaxVyx(IssmDouble *presponse)
Definition: FemModel.cpp:1905
MeshElementtypeEnum
@ MeshElementtypeEnum
Definition: EnumDefinitions.h:271
Element::GetNode
Node * GetNode(int nodeindex)
Definition: Element.cpp:1207
Element::ResultToMatrix
void ResultToMatrix(IssmDouble *values, int ncols, int output_enum)
Definition: Element.cpp:3290
ISSM_MPI_Send
int ISSM_MPI_Send(void *buf, int count, ISSM_MPI_Datatype datatype, int dest, int tag, ISSM_MPI_Comm comm)
Definition: issmmpi.cpp:484
FemModel::MaxVxx
void MaxVxx(IssmDouble *presponse)
Definition: FemModel.cpp:1880
Nodes::common_recv
int * common_recv
Definition: Nodes.h:26
MPROCESSOR
#define MPROCESSOR
Definition: Profiler.h:14
Element::UpdateConstraintsExtrudeFromBase
virtual void UpdateConstraintsExtrudeFromBase(void)=0
FemModel::inputs2
Inputs2 * inputs2
Definition: FemModel.h:47
GIACORE
#define GIACORE
Definition: Profiler.h:26
MaxAbsVzEnum
@ MaxAbsVzEnum
Definition: EnumDefinitions.h:1175
FemModel::ElementResponsex
void ElementResponsex(IssmDouble *presponse, int response_enum)
Definition: FemModel.cpp:1252
Outputdefinition1Enum
@ Outputdefinition1Enum
Definition: EnumDefinitions.h:865
IceMassScaledEnum
@ IceMassScaledEnum
Definition: EnumDefinitions.h:1111
ConfigurationTypeEnum
@ ConfigurationTypeEnum
Definition: EnumDefinitions.h:101
SettingsNumResultsOnNodesEnum
@ SettingsNumResultsOnNodesEnum
Definition: EnumDefinitions.h:335
Inputs2::Copy
Inputs2 * Copy(void)
Definition: Inputs2.cpp:56
INS_VAL
@ INS_VAL
Definition: toolkitsenums.h:14
FemModel::constraints
Constraints * constraints
Definition: FemModel.h:52
AutodiffIsautodiffEnum
@ AutodiffIsautodiffEnum
Definition: EnumDefinitions.h:50
TotalCalvingMeltingFluxLevelsetEnum
@ TotalCalvingMeltingFluxLevelsetEnum
Definition: EnumDefinitions.h:1306
InputDuplicatex
void InputDuplicatex(FemModel *femmodel, int original_enum, int new_enum)
Definition: InputDuplicatex.cpp:10
SolutionTypeEnum
@ SolutionTypeEnum
Definition: EnumDefinitions.h:398
TOTAL
#define TOTAL
Definition: Profiler.h:13
ThicknessAbsMisfitEnum
@ ThicknessAbsMisfitEnum
Definition: EnumDefinitions.h:837
FemModel::UpdateConstraintsExtrudeFromBasex
void UpdateConstraintsExtrudeFromBasex()
Definition: FemModel.cpp:3009
FemModel::GroundinglineMassFluxx
void GroundinglineMassFluxx(IssmDouble *presponse, bool scaled)
Definition: FemModel.cpp:1627
ISSM_MPI_Status
int ISSM_MPI_Status
Definition: issmmpi.h:121
IceVolumeEnum
@ IceVolumeEnum
Definition: EnumDefinitions.h:1114
SurfaceEnum
@ SurfaceEnum
Definition: EnumDefinitions.h:823
RheologyBAbsGradientx
void RheologyBAbsGradientx(IssmDouble *pJ, Elements *elements, Nodes *nodes, Vertices *vertices, Loads *loads, Materials *materials, Parameters *parameters)
Definition: RheologyBAbsGradientx.cpp:11
MaxVelEnum
@ MaxVelEnum
Definition: EnumDefinitions.h:1177
FemModel::GetLocalVectorWithClonesNodes
void GetLocalVectorWithClonesNodes(IssmDouble **plocal_vector, Vector< IssmDouble > *vector)
Definition: FemModel.cpp:1472
DataSet::GetEnum
int GetEnum()
Definition: DataSet.cpp:324
InversionSurfaceObsEnum
@ InversionSurfaceObsEnum
Definition: EnumDefinitions.h:630
THERMALCORE
#define THERMALCORE
Definition: Profiler.h:18
Node::IsClone
int IsClone()
Definition: Node.cpp:801
TransientAmrFrequencyEnum
@ TransientAmrFrequencyEnum
Definition: EnumDefinitions.h:442
Inputs2
Declaration of Inputs class.
Definition: Inputs2.h:23
AmrThicknessErrorMaximumEnum
@ AmrThicknessErrorMaximumEnum
Definition: EnumDefinitions.h:31
SealevelriseAnalysisEnum
@ SealevelriseAnalysisEnum
Definition: EnumDefinitions.h:1266
modules.h
header file for all the ISSM modules
NodalValuex
void NodalValuex(IssmDouble *pnodalvalue, int natureofdataenum, Elements *elements, Nodes *nodes, Vertices *vertices, Loads *loads, Materials *materials, Parameters *parameters)
Definition: NodalValuex.cpp:10
Results::AddResult
int AddResult(ExternalResult *result)
Definition: Results.cpp:33
IoModel::domaindim
int domaindim
Definition: IoModel.h:77
FemModel::loads
Loads * loads
Definition: FemModel.h:54
FemModel::UpdateConstraintsL2ProjectionEPLx
void UpdateConstraintsL2ProjectionEPLx(IssmDouble *pL2count)
Definition: FemModel.cpp:5160
WrapperCorePointerFromSolutionEnum
void WrapperCorePointerFromSolutionEnum(void(**psolutioncore)(FemModel *), Parameters *parameters, int solutiontype, bool nodakotacore=false)
Definition: WrapperCorePointerFromSolutionEnum.cpp:17
MinVzEnum
@ MinVzEnum
Definition: EnumDefinitions.h:1189
Profiler::Stop
void Stop(int tagenum, bool dontmpisync=true)
Definition: Profiler.cpp:179
DivergenceEnum
@ DivergenceEnum
Definition: EnumDefinitions.h:1038
ISSM_MPI_PDOUBLE
#define ISSM_MPI_PDOUBLE
Definition: issmmpi.h:126
TransientIsthermalEnum
@ TransientIsthermalEnum
Definition: EnumDefinitions.h:455
Domain3DEnum
@ Domain3DEnum
Definition: EnumDefinitions.h:536
MaterialsRhoSeawaterEnum
@ MaterialsRhoSeawaterEnum
Definition: EnumDefinitions.h:265
FemModel::nodes_list
Nodes ** nodes_list
Definition: FemModel.h:57
PI
const double PI
Definition: constants.h:11
FemModel::BedrockFromMismipPlus
void BedrockFromMismipPlus(void)
Definition: FemModel.cpp:3283
AmrGradationEnum
@ AmrGradationEnum
Definition: EnumDefinitions.h:19
Contour::nods
int nods
Definition: Contour.h:20
HydrologyDCEfficientAnalysisEnum
@ HydrologyDCEfficientAnalysisEnum
Definition: EnumDefinitions.h:1098
HydrologyDCInefficientAnalysis::HydrologyIdsGetActive
void HydrologyIdsGetActive(Vector< IssmDouble > *active_vec, Element *element)
Definition: HydrologyDCInefficientAnalysis.cpp:834
FemModel::solution_type
int solution_type
Definition: FemModel.h:40
FemModel::StackTransientInputx
void StackTransientInputx(int *input_enum, int *transientinput_enum, IssmDouble hydrotime, int numoutputs)
Definition: FemModel.cpp:5213
IsInputEnum
bool IsInputEnum(int enum_in)
Definition: EnumToStringx.cpp:1368
FemModel::elements
Elements * elements
Definition: FemModel.h:44
ISSM_MPI_Bcast
int ISSM_MPI_Bcast(void *buffer, int count, ISSM_MPI_Datatype datatype, int root, ISSM_MPI_Comm comm)
Definition: issmmpi.cpp:162
FemModel::Responsex
void Responsex(IssmDouble *presponse, int response_descriptor_enum)
Definition: FemModel.cpp:2558
FemModel::RignotMeltParameterizationx
void RignotMeltParameterizationx()
Definition: FemModel.cpp:2622
DependentObject::Responsex
void Responsex(IssmDouble *poutput_value, FemModel *femmodel)
Definition: DependentObject.cpp:93
FemModel::TotalGroundedBmbx
void TotalGroundedBmbx(IssmDouble *pGbmb, bool scaled)
Definition: FemModel.cpp:2977
IoConstant
Definition: IoModel.h:19
HydrologyShreveAnalysisEnum
@ HydrologyShreveAnalysisEnum
Definition: EnumDefinitions.h:1104
DamageDbarOldEnum
@ DamageDbarOldEnum
Definition: EnumDefinitions.h:519
SLRCORE
#define SLRCORE
Definition: Profiler.h:28
TransientInput2::AddPentaTimeInput
void AddPentaTimeInput(IssmDouble time, int numindices, int *indices, IssmDouble *values_in, int interp_in)
Definition: TransientInput2.cpp:180
DamageDbarEnum
@ DamageDbarEnum
Definition: EnumDefinitions.h:518
Object::ObjectEnum
virtual int ObjectEnum()=0
AmrDeviatoricErrorMaximumEnum
@ AmrDeviatoricErrorMaximumEnum
Definition: EnumDefinitions.h:14
ProcessArguments
void ProcessArguments(int *solution, char **pbinname, char **poutbinname, char **ptoolkitsname, char **plockname, char **prestartname, char **prootpath, int argc, char **argv)
Definition: ProcessArguments.cpp:10
MaxVzEnum
@ MaxVzEnum
Definition: EnumDefinitions.h:1180
Profiler::Used
bool Used(int tagenum)
Definition: Profiler.cpp:218
FemModel::GetZeroLevelSetPoints
void GetZeroLevelSetPoints(IssmDouble **pzerolevelset_points, int &numberofpoints, int levelset_type)
Definition: FemModel.cpp:4400
Vector::Assemble
void Assemble(void)
Definition: Vector.h:142
Vertices::NumberOfVerticesLocalAll
int NumberOfVerticesLocalAll(void)
Definition: Vertices.cpp:261
EnumToAnalysis
Analysis * EnumToAnalysis(int analysis_enum)
Definition: EnumToAnalysis.cpp:13
StringToEnumx
int StringToEnumx(const char *string_in, bool notfounderror=true)
Definition: StringToEnumx.cpp:14
FemModel::IceMassx
void IceMassx(IssmDouble *pV, bool scaled)
Definition: FemModel.cpp:1655
Input2
Definition: Input2.h:18
HydrologydcEplflipLockEnum
@ HydrologydcEplflipLockEnum
Definition: EnumDefinitions.h:184
FemModel::ThicknessPositivex
void ThicknessPositivex(IssmDouble *pJ)
Definition: FemModel.cpp:2837
MARSHALLING_BACKWARD
@ MARSHALLING_BACKWARD
Definition: Marshalling.h:10
RheologyBbarAbsGradientx
void RheologyBbarAbsGradientx(IssmDouble *pJ, Elements *elements, Nodes *nodes, Vertices *vertices, Loads *loads, Materials *materials, Parameters *parameters)
Definition: RheologyBbarAbsGradientx.cpp:11
FemModel
Definition: FemModel.h:31
Element::GetVerticesSidList
void GetVerticesSidList(int *sidlist)
Definition: Element.cpp:1456
AmrDeviatoricErrorResolutionEnum
@ AmrDeviatoricErrorResolutionEnum
Definition: EnumDefinitions.h:15
FemModel::IcefrontMassFluxx
void IcefrontMassFluxx(IssmDouble *presponse, bool scaled)
Definition: FemModel.cpp:1579
VertexPIdEnum
@ VertexPIdEnum
Definition: EnumDefinitions.h:1324
AmrIceFrontResolutionEnum
@ AmrIceFrontResolutionEnum
Definition: EnumDefinitions.h:25
Element::CreateDistanceInputFromSegmentlist
virtual void CreateDistanceInputFromSegmentlist(IssmDouble *distances, int distanceenum)
Definition: Element.h:236
FemModel::MinVzx
void MinVzx(IssmDouble *presponse)
Definition: FemModel.cpp:2030
OutputBufferPointerEnum
@ OutputBufferPointerEnum
Definition: EnumDefinitions.h:281
ThermalAnalysisEnum
@ ThermalAnalysisEnum
Definition: EnumDefinitions.h:1302
FemModel::StrainRateperpendicularx
void StrainRateperpendicularx()
Definition: FemModel.cpp:2638
Elements::ResetHooks
void ResetHooks()
Definition: Elements.cpp:78
LoveSolutionEnum
@ LoveSolutionEnum
Definition: EnumDefinitions.h:1155
LockFileNameEnum
@ LockFileNameEnum
Definition: EnumDefinitions.h:230
Element::SetElementInput
virtual void SetElementInput(int enum_in, IssmDouble values)
Definition: Element.h:333
Materials::ResetHooks
void ResetHooks()
Definition: Materials.cpp:46
SealevelEnum
@ SealevelEnum
Definition: EnumDefinitions.h:675
Matice
Definition: Matice.h:24
FemModel::IcefrontAreax
void IcefrontAreax()
Definition: FemModel.cpp:1546
TotalSmbEnum
@ TotalSmbEnum
Definition: EnumDefinitions.h:1311
WriteLockFile
void WriteLockFile(char *filename)
Definition: WriteLockFile.cpp:10
DataSet::Presort
void Presort()
Definition: DataSet.cpp:368
Nodes::Copy
Nodes * Copy()
Definition: Nodes.cpp:48
AreaEnum
@ AreaEnum
Definition: EnumDefinitions.h:819
Inputs2::GetTransientInput
TransientInput2 * GetTransientInput(int enum_type)
Definition: Inputs2.cpp:406
Element::ValueP1DerivativesOnGauss
virtual void ValueP1DerivativesOnGauss(IssmDouble *dvalue, IssmDouble *values, IssmDouble *xyz_list, Gauss *gauss)=0
StressbalanceSIAAnalysisEnum
@ StressbalanceSIAAnalysisEnum
Definition: EnumDefinitions.h:1287
RheologyBInitialguessMisfitx
void RheologyBInitialguessMisfitx(IssmDouble *pJ, Elements *elements, Nodes *nodes, Vertices *vertices, Loads *loads, Materials *materials, Parameters *parameters)
Definition: RheologyBAbsGradientx.cpp:82
RegularEnum
@ RegularEnum
Definition: EnumDefinitions.h:1238
Element::CalvingMeltingFluxLevelset
virtual void CalvingMeltingFluxLevelset(void)
Definition: Element.h:225
MaxDivergenceEnum
@ MaxDivergenceEnum
Definition: EnumDefinitions.h:1176
HydrologyshaktiEnum
@ HydrologyshaktiEnum
Definition: EnumDefinitions.h:1108
GenericExternalResult
Definition: GenericExternalResult.h:21
FemModel::SyncLocalVectorWithClonesVerticesAdd
void SyncLocalVectorWithClonesVerticesAdd(IssmDouble *local_vector)
Definition: FemModel.cpp:1405
IssmComm::GetRank
static int GetRank(void)
Definition: IssmComm.cpp:34
LACrouzeixRaviartEnum
@ LACrouzeixRaviartEnum
Definition: EnumDefinitions.h:1138
Element::IsIceInElement
bool IsIceInElement()
Definition: Element.cpp:2021
FemModel::IceVolumeAboveFloatationx
void IceVolumeAboveFloatationx(IssmDouble *pV, bool scaled)
Definition: FemModel.cpp:1671
FemModel::ResetLevelset
void ResetLevelset()
Definition: FemModel.cpp:2545
Loads
Declaration of Loads class.
Definition: Loads.h:16
FemModel::CheckPoint
void CheckPoint(void)
Definition: FemModel.cpp:238
IcefrontMassFluxLevelsetEnum
@ IcefrontMassFluxLevelsetEnum
Definition: EnumDefinitions.h:1117
DeviatoricStressErrorEstimatorEnum
@ DeviatoricStressErrorEstimatorEnum
Definition: EnumDefinitions.h:1037
L2ProjectionEPLAnalysisEnum
@ L2ProjectionEPLAnalysisEnum
Definition: EnumDefinitions.h:1137
Node
Definition: Node.h:23
Node::Lid
int Lid(void)
Definition: Node.cpp:618
InputToDepthaverageInEnum
@ InputToDepthaverageInEnum
Definition: EnumDefinitions.h:203
Node::Sid
int Sid(void)
Definition: Node.cpp:622
GLheightadvectionAnalysisEnum
@ GLheightadvectionAnalysisEnum
Definition: EnumDefinitions.h:1077
TimesteppingTimeStepMinEnum
@ TimesteppingTimeStepMinEnum
Definition: EnumDefinitions.h:435
Contour::y
doubletype * y
Definition: Contour.h:22
VerboseSolver
bool VerboseSolver(void)
Definition: Verbosity.cpp:25
NoneEnum
@ NoneEnum
Definition: EnumDefinitions.h:1202
StressbalanceVerticalAnalysisEnum
@ StressbalanceVerticalAnalysisEnum
Definition: EnumDefinitions.h:1289
Element::ResultInterpolation
void ResultInterpolation(int *pinterpolation, int *nodesperelement, int *parray_size, int output_enum)
Definition: Element.cpp:3162
FloatingAreaEnum
@ FloatingAreaEnum
Definition: EnumDefinitions.h:1067
FemModel::CreateMaterials
void CreateMaterials(int newnumberofelements, bool *my_elements, Materials *materials)
Definition: FemModel.cpp:3721
_error_
#define _error_(StreamArgs)
Definition: exceptions.h:49
ElementHook::hvertices
Hook * hvertices
Definition: ElementHook.h:16
Node::Deactivate
void Deactivate(void)
Definition: Node.cpp:681
Tria
Definition: Tria.h:29
AmrTypeEnum
@ AmrTypeEnum
Definition: EnumDefinitions.h:34
FemModel::GetInputs
void GetInputs(int *pnumP0inputs, IssmDouble **pP0inputs, int **pP0input_enums, int **pP0input_interp, int *pnumP1inputs, IssmDouble **pP1inputs, int **pP1input_enums, int **pP1input_interp)
Definition: FemModel.cpp:3368
Parameters::Marshall
void Marshall(char **pmarshalled_data, int *pmarshalled_data_size, int marshall_direction)
Definition: Parameters.cpp:113
FlowequationIsFSEnum
@ FlowequationIsFSEnum
Definition: EnumDefinitions.h:138
Profiler::Start
void Start(int tagenum, bool dontmpisync=true)
Definition: Profiler.cpp:139
FemModel::UpdateElements
void UpdateElements(int newnumberofelements, int *newelementslist, bool *my_elements, int analysis_counter, Elements *newelements)
Definition: FemModel.cpp:3993
Element::parameters
Parameters * parameters
Definition: Element.h:51
ChannelAreaEnum
@ ChannelAreaEnum
Definition: EnumDefinitions.h:1009
ModelProcessorx
void ModelProcessorx(Elements **pelements, Nodes ***pnodes, Vertices **pvertices, Materials **pmaterials, Constraints ***pconstraints, Loads ***ploads, Parameters **pparameters, Inputs2 **pinputs2, IoModel *iomodel, FILE *toolkitfile, char *rootpath, const int solution_enum, const int nummodels, const int *analysis_enum_list)
Definition: ModelProcessorx.cpp:15
RheologyBAbsGradientEnum
@ RheologyBAbsGradientEnum
Definition: EnumDefinitions.h:671
Gauss::begin
virtual int begin(void)=0
SurfaceSlopeSolutionEnum
@ SurfaceSlopeSolutionEnum
Definition: EnumDefinitions.h:1298
VerboseSolution
bool VerboseSolution(void)
Definition: Verbosity.cpp:24
DataSet::GetObjectByOffset
Object * GetObjectByOffset(int offset)
Definition: DataSet.cpp:334
VxEnum
@ VxEnum
Definition: EnumDefinitions.h:846
HydrologypismEnum
@ HydrologypismEnum
Definition: EnumDefinitions.h:1107
FemModel::MassFluxx
void MassFluxx(IssmDouble *presponse)
Definition: FemModel.cpp:1703
min
IssmDouble min(IssmDouble a, IssmDouble b)
Definition: extrema.cpp:14
Contour::x
doubletype * x
Definition: Contour.h:21
FemModel::Restart
void Restart(void)
Definition: FemModel.cpp:549
DoubleVecParam
Definition: DoubleVecParam.h:20
EsaSolutionEnum
@ EsaSolutionEnum
Definition: EnumDefinitions.h:1054
Profiler::TotalTimeModHour
int TotalTimeModHour(int tag)
Definition: Profiler.cpp:110
BalancethicknessOmega0Enum
@ BalancethicknessOmega0Enum
Definition: EnumDefinitions.h:472
Tria::GetArea
IssmDouble GetArea(void)
Definition: Tria.cpp:1423
Element::StrainRateperpendicular
virtual void StrainRateperpendicular(void)=0
InversionNumCostFunctionsEnum
@ InversionNumCostFunctionsEnum
Definition: EnumDefinitions.h:224
MPISERIAL
#define MPISERIAL
Definition: Profiler.h:29
FemModel::CreateConstraints
void CreateConstraints(Vertices *newfemmodel_vertices, int analysis_enum, Constraints *newfemmodel_constraints)
Definition: FemModel.cpp:3894
PentaEnum
@ PentaEnum
Definition: EnumDefinitions.h:1231
SurfaceLogVelMisfitEnum
@ SurfaceLogVelMisfitEnum
Definition: EnumDefinitions.h:825
FemModel::MaxVzx
void MaxVzx(IssmDouble *presponse)
Definition: FemModel.cpp:1930
ISSM_MPI_Comm
int ISSM_MPI_Comm
Definition: issmmpi.h:118
FemModelCommEnum
@ FemModelCommEnum
Definition: EnumDefinitions.h:136
OutputDefinitionsResponsex
IssmDouble OutputDefinitionsResponsex(FemModel *femmodel, int output_enum)
Definition: OutputDefinitionsResponsex.cpp:38
AmrBamgEnum
@ AmrBamgEnum
Definition: EnumDefinitions.h:974
Profiler::TotalTimeModMin
int TotalTimeModMin(int tag)
Definition: Profiler.cpp:117
Element::JacobianDeterminant
virtual void JacobianDeterminant(IssmDouble *Jdet, IssmDouble *xyz_list, Gauss *gauss)=0
IndexedEnum
@ IndexedEnum
Definition: EnumDefinitions.h:1119
Gauss::GaussPoint
virtual void GaussPoint(int ig)=0
Input2::GetInputMin
virtual IssmDouble GetInputMin(void)
Definition: Input2.h:36
Node::lid
int lid
Definition: Node.h:30
FemModel::SurfaceAbsMisfitx
void SurfaceAbsMisfitx(IssmDouble *pJ)
Definition: FemModel.cpp:2663
RootPathEnum
@ RootPathEnum
Definition: EnumDefinitions.h:301
NodeSIdEnum
@ NodeSIdEnum
Definition: EnumDefinitions.h:1200
AutodiffNumDependentsEnum
@ AutodiffNumDependentsEnum
Definition: EnumDefinitions.h:52
FemModel::RequestedOutputsx
void RequestedOutputsx(Results **presults, char **requested_outputs, int numoutputs, bool save_results=true)
Definition: FemModel.cpp:2267
StringParam
Definition: StringParam.h:20
MassFluxEnum
@ MassFluxEnum
Definition: EnumDefinitions.h:1159
FemModel::SetCurrentConfiguration
void SetCurrentConfiguration(int configuration_type)
Definition: FemModel.cpp:634
ad_core
void ad_core(FemModel *femmodel)
Definition: ad_core.cpp:24
Inputs2::SetTransientInput
void SetTransientInput(int enum_in, IssmDouble *times, int numtimes)
Definition: Inputs2.cpp:676
Vertex::lid
int lid
Definition: Vertex.h:27
Inputs2::DeleteInput
int DeleteInput(int enum_type)
Definition: Inputs2.cpp:195
VyAverageEnum
@ VyAverageEnum
Definition: EnumDefinitions.h:849
Element::CalvingFluxLevelset
virtual void CalvingFluxLevelset(void)
Definition: Element.h:224
STRESSBALANCECORE
#define STRESSBALANCECORE
Definition: Profiler.h:20
Elements::SetCurrentConfiguration
void SetCurrentConfiguration(Elements *elements, Loads *loads, Nodes *nodes, Vertices *vertices, Materials *materials, Parameters *parameters)
Definition: Elements.cpp:92
ElementHook::hneighbors
Hook * hneighbors
Definition: ElementHook.h:18
MARSHALLING_FORWARD
@ MARSHALLING_FORWARD
Definition: Marshalling.h:9
FemModel::GetElementCenterCoordinates
void GetElementCenterCoordinates(IssmDouble **pxc, IssmDouble **pyc)
Definition: FemModel.cpp:4355
BoolInput2Enum
@ BoolInput2Enum
Definition: EnumDefinitions.h:995
Parameters::FindParam
void FindParam(bool *pinteger, int enum_type)
Definition: Parameters.cpp:262
FemModel::CleanUp
void CleanUp(void)
Definition: FemModel.cpp:279
Loads::Marshall
void Marshall(char **pmarshalled_data, int *pmarshalled_data_size, int marshall_direction)
Definition: Loads.cpp:75
ThicknessEnum
@ ThicknessEnum
Definition: EnumDefinitions.h:840
ElementInput2::element_values
IssmDouble * element_values
Definition: ElementInput2.h:18
AmrKeepMetricEnum
@ AmrKeepMetricEnum
Definition: EnumDefinitions.h:26
Vertex::y
IssmDouble y
Definition: Vertex.h:29
GroundedAreaScaledEnum
@ GroundedAreaScaledEnum
Definition: EnumDefinitions.h:1090
DataSet::Copy
DataSet * Copy(void)
Definition: DataSet.cpp:49
FemModel::copy
FemModel * copy()
Definition: FemModel.cpp:320
FemModel::FloatingAreax
void FloatingAreax(IssmDouble *pV, bool scaled)
Definition: FemModel.cpp:1292
IceVolumeAboveFloatationEnum
@ IceVolumeAboveFloatationEnum
Definition: EnumDefinitions.h:1112
Element::TotalGroundedBmb
IssmDouble TotalGroundedBmb(IssmDouble *mask, bool scaled)
Definition: Element.cpp:4273
FrontalForcingsBasinIdEnum
@ FrontalForcingsBasinIdEnum
Definition: EnumDefinitions.h:585
ThicknessErrorEstimatorEnum
@ ThicknessErrorEstimatorEnum
Definition: EnumDefinitions.h:1304
FemModel::InterpolateInputs
void InterpolateInputs(Vertices *newfemmodel_vertices, Elements *newfemmodel_elements, Inputs2 *new_inputs)
Definition: FemModel.cpp:3499
HydrologyGlaDSEnum
@ HydrologyGlaDSEnum
Definition: EnumDefinitions.h:1101
AnalysisTypeEnum
@ AnalysisTypeEnum
Definition: EnumDefinitions.h:36
LoadLoveKEnum
@ LoadLoveKEnum
Definition: EnumDefinitions.h:316
VelEnum
@ VelEnum
Definition: EnumDefinitions.h:844
AmrThicknessErrorGroupThresholdEnum
@ AmrThicknessErrorGroupThresholdEnum
Definition: EnumDefinitions.h:30
FemModel::StrainRateparallelx
void StrainRateparallelx()
Definition: FemModel.cpp:2630
SpcNodesx
void SpcNodesx(Nodes *nodes, Constraints *constraints, Parameters *parameters)
Definition: SpcNodesx.cpp:10
FemModel::IcefrontMassFluxLevelsetx
void IcefrontMassFluxLevelsetx(IssmDouble *presponse, bool scaled)
Definition: FemModel.cpp:1595
MaxAbsVyEnum
@ MaxAbsVyEnum
Definition: EnumDefinitions.h:1174
Inputs2::GetInputsInterpolations
void GetInputsInterpolations(int *pnuminputs, int **pinterpolations, int **penum)
Definition: Inputs2.cpp:263
Elements::NumberOfElements
int NumberOfElements(void)
Definition: Elements.cpp:67
Vertex::GetZ
IssmDouble GetZ(void)
Definition: Vertex.cpp:160
Constraint
Definition: Constraint.h:17
Element::CreateInputTimeAverage
virtual void CreateInputTimeAverage(int transientinput_enum, int averagedinput_enum, IssmDouble init_time, IssmDouble end_time, int averaging_method)
Definition: Element.h:237
ElementHook::hnodes
Hook ** hnodes
Definition: ElementHook.h:15
DummyEnum
@ DummyEnum
Definition: EnumDefinitions.h:547
Node::ApplyConstraint
void ApplyConstraint(int dof, IssmDouble value)
Definition: Node.cpp:646
IoModel::elements
int * elements
Definition: IoModel.h:79
Element::CalvingRateLevermann
virtual void CalvingRateLevermann(void)=0
SteadystateSolutionEnum
@ SteadystateSolutionEnum
Definition: EnumDefinitions.h:1283
MaticeEnum
@ MaticeEnum
Definition: EnumDefinitions.h:1169
Input2::GetInputValue
virtual void GetInputValue(IssmDouble *pvalue, Gauss *gauss)
Definition: Input2.h:38
FemModel::ThicknessAbsGradientx
void ThicknessAbsGradientx(IssmDouble *pJ)
Definition: FemModel.cpp:2718
VertexCoordinatesx
void VertexCoordinatesx(IssmDouble **px, IssmDouble **py, IssmDouble **pz, Vertices *vertices, bool spherical)
Definition: VertexCoordinatesx.cpp:11
Vertex
Definition: Vertex.h:19
Gauss::weight
IssmDouble weight
Definition: Gauss.h:11
SurfaceAverageVelMisfitEnum
@ SurfaceAverageVelMisfitEnum
Definition: EnumDefinitions.h:821
BedSlopeSolutionEnum
@ BedSlopeSolutionEnum
Definition: EnumDefinitions.h:992
ISSM_MPI_Recv
int ISSM_MPI_Recv(void *buf, int count, ISSM_MPI_Datatype datatype, int source, int tag, ISSM_MPI_Comm comm, ISSM_MPI_Status *status)
Definition: issmmpi.cpp:342
IoModel
Definition: IoModel.h:48
P0ArrayEnum
@ P0ArrayEnum
Definition: EnumDefinitions.h:1213
IoModel::meshelementtype
int meshelementtype
Definition: IoModel.h:91
Vector::ToMPISerial
doubletype * ToMPISerial(void)
Definition: Vector.h:277
FemModel::ThicknessZZErrorEstimator
void ThicknessZZErrorEstimator(IssmDouble **pelementerror)
Definition: FemModel.cpp:4260
HydrologyDCInefficientAnalysis::ElementizeEplMask
void ElementizeEplMask(FemModel *femmodel)
Definition: HydrologyDCInefficientAnalysis.cpp:756
SurfaceLogVelMisfitx
void SurfaceLogVelMisfitx(IssmDouble *pJ, Elements *elements, Nodes *nodes, Vertices *vertices, Loads *loads, Materials *materials, Parameters *parameters)
Definition: SurfaceLogVelMisfitx.cpp:10
ADCORE
#define ADCORE
Definition: Profiler.h:17
TransientInput2.h
: header file for transientinput object
SettingsWaitonlockEnum
@ SettingsWaitonlockEnum
Definition: EnumDefinitions.h:341
TotalCalvingFluxLevelsetEnum
@ TotalCalvingFluxLevelsetEnum
Definition: EnumDefinitions.h:1305
ISSM_MPI_Reduce
int ISSM_MPI_Reduce(void *sendbuf, void *recvbuf, int count, ISSM_MPI_Datatype datatype, ISSM_MPI_Op op, int root, ISSM_MPI_Comm comm)
Definition: issmmpi.cpp:373
Element::RignotMeltParameterization
virtual void RignotMeltParameterization(void)
Definition: Element.h:332
NodalEnum
@ NodalEnum
Definition: EnumDefinitions.h:1198
FemModel::loads_list
Loads ** loads_list
Definition: FemModel.h:55
max
IssmDouble max(IssmDouble a, IssmDouble b)
Definition: extrema.cpp:24
HydrologyshreveEnum
@ HydrologyshreveEnum
Definition: EnumDefinitions.h:1109
ToolkitsOptionsStringsEnum
@ ToolkitsOptionsStringsEnum
Definition: EnumDefinitions.h:440
IssmPDouble
IssmDouble IssmPDouble
Definition: types.h:38
Element::IceMass
IssmDouble IceMass(bool scaled)
Definition: Element.cpp:1569
TimesteppingTimeStepMaxEnum
@ TimesteppingTimeStepMaxEnum
Definition: EnumDefinitions.h:434
pfclose
void pfclose(FILE *fid, char *filename)
Definition: pfclose.cpp:14
DragCoefficientAbsGradientx
void DragCoefficientAbsGradientx(IssmDouble *pJ, Elements *elements, Nodes *nodes, Vertices *vertices, Loads *loads, Materials *materials, Parameters *parameters)
Definition: DragCoefficientAbsGradientx.cpp:11
IntInput2Enum
@ IntInput2Enum
Definition: EnumDefinitions.h:996
ThicknessAbsGradientEnum
@ ThicknessAbsGradientEnum
Definition: EnumDefinitions.h:836
Parameters::FindParamObject
Param * FindParamObject(int enum_type)
Definition: Parameters.cpp:588
MassFluxSegmentsPresentEnum
@ MassFluxSegmentsPresentEnum
Definition: EnumDefinitions.h:242
Element::GetNumberOfVertices
virtual int GetNumberOfVertices(void)=0
DataSet
Declaration of DataSet class.
Definition: DataSet.h:14
SolidearthSettingsElasticEnum
@ SolidearthSettingsElasticEnum
Definition: EnumDefinitions.h:308
Channel::WriteChannelCrossSection
void WriteChannelCrossSection(IssmPDouble *values)
Definition: Channel.cpp:716
MassFluxSegmentsEnum
@ MassFluxSegmentsEnum
Definition: EnumDefinitions.h:241
FemModel::SetMesh
void SetMesh(int **elementslist, IssmDouble **x, IssmDouble **y, int *numberofvertices, int *numberofelements)
Definition: FemModel.cpp:3819
Element::GetInputListOnVertices
void GetInputListOnVertices(IssmDouble *pvalue, int enumtype)
Definition: Element.cpp:1131
IoModel::domaintype
int domaintype
Definition: IoModel.h:78
IceMassEnum
@ IceMassEnum
Definition: EnumDefinitions.h:1110
FemModel::DistanceToFieldValue
void DistanceToFieldValue(int fieldenum, IssmDouble fieldvalue, int distanceenum)
Definition: FemModel.cpp:1103
ESACORE
#define ESACORE
Definition: Profiler.h:27
Domain2DverticalEnum
@ Domain2DverticalEnum
Definition: EnumDefinitions.h:535
FemModel::SmoothedGradThickness
void SmoothedGradThickness(IssmDouble **pdHdx, IssmDouble **pdHdy)
Definition: FemModel.cpp:4180
FemModel::WriteMeshInResults
void WriteMeshInResults(void)
Definition: FemModel.cpp:3610
Nodes::NumberOfDofs
int NumberOfDofs(int setenum)
Definition: Nodes.cpp:314
Inputs2::Marshall
void Marshall(char **pmarshalled_data, int *pmarshalled_data_size, int marshall_direction)
Definition: Inputs2.cpp:81
FemModel::profiler
Profiler * profiler
Definition: FemModel.h:42
Vector< IssmDouble >
Vertices::Marshall
void Marshall(char **pmarshalled_data, int *pmarshalled_data_size, int marshall_direction)
Definition: Vertices.cpp:112
AmrBamg
Definition: AmrBamg.h:12
Input2::GetInputAverage
virtual void GetInputAverage(IssmDouble *pvalue)
Definition: Input2.h:33
InterpFromMeshToMesh2dx
int InterpFromMeshToMesh2dx(double **pdata_interp, int *index_data, double *x_data, double *y_data, int nods_data, int nels_data, double *data, int M_data, int N_data, double *x_interp, double *y_interp, int N_interp, Options *options)
Definition: InterpFromMeshToMesh2dx.cpp:16
Element::isonsurface
bool isonsurface
Definition: Element.h:52
Results
Declaration of Results class.
Definition: Results.h:14
HYDROLOGYCORE
#define HYDROLOGYCORE
Definition: Profiler.h:19
FemModel::ReMesh
void ReMesh(void)
Definition: FemModel.cpp:3101
FemModel::UpdateConstraintsExtrudeFromTopx
void UpdateConstraintsExtrudeFromTopx()
Definition: FemModel.cpp:3018
IcefrontMassFluxEnum
@ IcefrontMassFluxEnum
Definition: EnumDefinitions.h:1116
FlowequationIsSIAEnum
@ FlowequationIsSIAEnum
Definition: EnumDefinitions.h:141
Profiler::TotalTime
IssmPDouble TotalTime(int tag)
Definition: Profiler.cpp:96
TotalGroundedBmbScaledEnum
@ TotalGroundedBmbScaledEnum
Definition: EnumDefinitions.h:1310
FemModel::MaxDivergencex
void MaxDivergencex(IssmDouble *pdiv)
Definition: FemModel.cpp:1836
Loads::SetCurrentConfiguration
void SetCurrentConfiguration(Elements *elements, Loads *loads, Nodes *nodes, Vertices *vertices, Materials *materials, Parameters *parameters)
Definition: Loads.cpp:178
AmrDeviatoricErrorGroupThresholdEnum
@ AmrDeviatoricErrorGroupThresholdEnum
Definition: EnumDefinitions.h:13
RheologyBInitialguessMisfitEnum
@ RheologyBInitialguessMisfitEnum
Definition: EnumDefinitions.h:673
GroundedAreaEnum
@ GroundedAreaEnum
Definition: EnumDefinitions.h:1089
Gauss
Definition: Gauss.h:8
Element::material
Material * material
Definition: Element.h:50
OutputFilePointerEnum
@ OutputFilePointerEnum
Definition: EnumDefinitions.h:284
TriaEnum
@ TriaEnum
Definition: EnumDefinitions.h:1318
ElementsAndVerticesPartitioning
void ElementsAndVerticesPartitioning(IoModel *iomodel)
Definition: ElementsAndVerticesPartitioning.cpp:17
VxMeshEnum
@ VxMeshEnum
Definition: EnumDefinitions.h:847
Element::IcefrontMassFluxLevelset
virtual IssmDouble IcefrontMassFluxLevelset(bool scaled)
Definition: Element.h:272
FemModel::GetMesh
void GetMesh(Vertices *femmodel_vertices, Elements *femmodel_elements, IssmDouble **px, IssmDouble **py, int **pelementslist)
Definition: FemModel.cpp:3731
classes.h
RotationalEquatorialMoiEnum
@ RotationalEquatorialMoiEnum
Definition: EnumDefinitions.h:310
OutputBufferSizePointerEnum
@ OutputBufferSizePointerEnum
Definition: EnumDefinitions.h:282
Nodes::NumberOfNodesLocal
int NumberOfNodesLocal(void)
Definition: Nodes.cpp:359
DatasetInput2.h
: header file for datasetinput object
Element::GetVerticesLidList
void GetVerticesLidList(int *lidlist)
Definition: Element.cpp:1426
Analysis::UpdateConstraints
virtual void UpdateConstraints(FemModel *femmodel)=0
Analysis
Definition: Analysis.h:30
TransientInput2::AddTriaTimeInput
void AddTriaTimeInput(IssmDouble time, int numindices, int *indices, IssmDouble *values_in, int interp_in)
Definition: TransientInput2.cpp:138
TotalFloatingBmbEnum
@ TotalFloatingBmbEnum
Definition: EnumDefinitions.h:1307
FemModelEnum
@ FemModelEnum
Definition: EnumDefinitions.h:1064
Vector::SetValue
void SetValue(int dof, doubletype value, InsMode mode)
Definition: Vector.h:163
SealevelMasks::isoceanin
bool * isoceanin
Definition: SealevelMasks.h:17
FemModel::UpdateVertexPositionsx
int UpdateVertexPositionsx(void)
Definition: FemModel.cpp:3055
MeshXEnum
@ MeshXEnum
Definition: EnumDefinitions.h:1184
ThicknessAcrossGradientx
void ThicknessAcrossGradientx(IssmDouble *pJ, Elements *elements, Nodes *nodes, Vertices *vertices, Loads *loads, Materials *materials, Parameters *parameters)
Definition: ThicknessAcrossGradientx.cpp:11
ISSM_MPI_Gather
int ISSM_MPI_Gather(void *sendbuf, int sendcnt, ISSM_MPI_Datatype sendtype, void *recvbuf, int recvcnt, ISSM_MPI_Datatype recvtype, int root, ISSM_MPI_Comm comm)
Definition: issmmpi.cpp:242
SealevelMasks
Definition: SealevelMasks.h:10
Vertices::common_send_ids
int ** common_send_ids
Definition: Vertices.h:25
Vertex::Sid
int Sid(void)
Definition: Vertex.cpp:168
MaxVyEnum
@ MaxVyEnum
Definition: EnumDefinitions.h:1179
FlowequationIsHOEnum
@ FlowequationIsHOEnum
Definition: EnumDefinitions.h:139
Element::GetInputLocalMinMaxOnNodes
void GetInputLocalMinMaxOnNodes(IssmDouble *min, IssmDouble *max, IssmDouble *ug)
Definition: Element.cpp:1152
MinVelEnum
@ MinVelEnum
Definition: EnumDefinitions.h:1186
AmrFieldEnum
@ AmrFieldEnum
Definition: EnumDefinitions.h:18
FemModel::WriteErrorEstimatorsInResults
void WriteErrorEstimatorsInResults(void)
Definition: FemModel.cpp:3642
HydrologyDCInefficientAnalysis::HydrologyIDSGetMask
void HydrologyIDSGetMask(Vector< IssmDouble > *vec_mask, Element *element)
Definition: HydrologyDCInefficientAnalysis.cpp:774
RheologyBbarAbsGradientEnum
@ RheologyBbarAbsGradientEnum
Definition: EnumDefinitions.h:674
Profiler::copy
Object * copy()
Definition: Profiler.cpp:31
SurfaceAverageVelMisfitx
void SurfaceAverageVelMisfitx(IssmDouble *pJ, FemModel *femmodel)
Definition: SurfaceAverageVelMisfitx.cpp:12
GenericParam
Definition: GenericParam.h:26
Analysis::CreateNodes
virtual void CreateNodes(Nodes *nodes, IoModel *iomodel, bool isamr=false)=0
Node::Activate
void Activate(void)
Definition: Node.cpp:632
FemModel::FemModel
FemModel(int argc, char **argv, ISSM_MPI_Comm comm_init, bool trace=false)
Definition: FemModel.cpp:56
ProfilingCurrentMemEnum
@ ProfilingCurrentMemEnum
Definition: EnumDefinitions.h:1235
ThicknessAcrossGradientEnum
@ ThicknessAcrossGradientEnum
Definition: EnumDefinitions.h:838
FlowequationIsL1L2Enum
@ FlowequationIsL1L2Enum
Definition: EnumDefinitions.h:140
ElementHook::numanalyses
int numanalyses
Definition: ElementHook.h:14
Element::ComputeDeviatoricStressTensor
virtual void ComputeDeviatoricStressTensor(void)=0
FemModel::GroundedAreax
void GroundedAreax(IssmDouble *pV, bool scaled)
Definition: FemModel.cpp:1530
DataSet::Marshall
void Marshall(char **pmarshalled_data, int *pmarshalled_data_size, int marshall_direction)
Definition: DataSet.cpp:93