Changeset 20810
- Timestamp:
- 06/27/16 09:22:48 (9 years ago)
- Location:
- issm/trunk-jpl/src/c/classes
- Files:
-
- 56 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk-jpl/src/c/classes/Constraints/SpcDynamic.cpp
r19254 r20810 71 71 int SpcDynamic::Id(void){ return sid; }/*{{{*/ 72 72 /*}}}*/ 73 int SpcDynamic::ObjectEnum(void){/*{{{*/74 75 return SpcDynamicEnum;76 77 }78 /*}}}*/79 73 void SpcDynamic::Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){ /*{{{*/ 80 74 … … 88 82 MARSHALLING(isset); 89 83 MARSHALLING(penalty); 84 85 } 86 /*}}}*/ 87 int SpcDynamic::ObjectEnum(void){/*{{{*/ 88 89 return SpcDynamicEnum; 90 90 91 91 } -
issm/trunk-jpl/src/c/classes/Constraints/SpcDynamic.h
r19254 r20810 34 34 void Echo(); 35 35 int Id(); 36 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction); 36 37 int ObjectEnum(); 37 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction);38 38 39 39 /*Constraint virtual functions definitions*/ -
issm/trunk-jpl/src/c/classes/Constraints/SpcStatic.cpp
r19254 r20810 73 73 int SpcStatic::Id(void){ return sid; }/*{{{*/ 74 74 /*}}}*/ 75 int SpcStatic::ObjectEnum(void){/*{{{*/76 77 return SpcStaticEnum;78 79 }80 /*}}}*/81 75 void SpcStatic::Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){ /*{{{*/ 82 76 … … 89 83 MARSHALLING(analysis_type); 90 84 MARSHALLING(penalty); 85 86 } 87 /*}}}*/ 88 int SpcStatic::ObjectEnum(void){/*{{{*/ 89 90 return SpcStaticEnum; 91 91 92 92 } -
issm/trunk-jpl/src/c/classes/Constraints/SpcStatic.h
r19216 r20810 29 29 /*}}}*/ 30 30 /*Object virtual functions definitions:{{{ */ 31 Object* copy(); 32 void DeepEcho(); 31 33 void Echo(); 32 void DeepEcho();33 34 int Id(); 35 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction); 34 36 int ObjectEnum(); 35 Object* copy();36 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction);37 37 /*}}}*/ 38 38 /*Constraint virtual functions definitions: {{{*/ … … 43 43 /*}}}*/ 44 44 /*SpcStatic management:{{{ */ 45 int GetDof(); 45 46 int GetNodeId(); 46 int GetDof();47 47 IssmDouble GetValue(); 48 48 /*}}}*/ -
issm/trunk-jpl/src/c/classes/Constraints/SpcTransient.cpp
r19256 r20810 79 79 } 80 80 /*}}}*/ 81 int SpcTransient::ObjectEnum(void){/*{{{*/82 83 return SpcTransientEnum;84 85 }86 /*}}}*/87 81 void SpcTransient::Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){ /*{{{*/ 88 82 … … 106 100 } 107 101 /*}}}*/ 102 int SpcTransient::ObjectEnum(void){/*{{{*/ 103 104 return SpcTransientEnum; 105 106 } 107 /*}}}*/ 108 108 109 109 /*Constraint virtual functions definitions:*/ -
issm/trunk-jpl/src/c/classes/Constraints/SpcTransient.h
r19254 r20810 35 35 void Echo(); 36 36 int Id(); 37 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction); 37 38 int ObjectEnum(); 38 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction);39 39 /*}}}*/ 40 40 /*Constraint virtual functions definitions: {{{*/ -
issm/trunk-jpl/src/c/classes/Contour.h
r19198 r20810 52 52 53 53 /*Object virtual function resolutoin: */ 54 Object* copy() {/*{{{*/ 55 56 Contour* contour = new Contour(this->id,this->nods,this->x,this->y,this->closed); 57 58 return (Object*) contour; 59 } 60 /*}}}*/ 61 void DeepEcho(void){/*{{{*/ 62 this->Echo(); 63 } 64 /*}}}*/ 54 65 void Echo(void){/*{{{*/ 55 66 _printf_(" Contour: " << id << "\n"); … … 64 75 } 65 76 /*}}}*/ 66 void DeepEcho(void){/*{{{*/67 this->Echo();68 }69 /*}}}*/70 77 int Id(void){/*{{{*/ 71 78 return id; 72 }73 /*}}}*/74 int ObjectEnum(void){/*{{{*/75 return ContourEnum;76 }77 /*}}}*/78 Object* copy() {/*{{{*/79 80 Contour* contour = new Contour(this->id,this->nods,this->x,this->y,this->closed);81 82 return (Object*) contour;83 79 } 84 80 /*}}}*/ … … 87 83 } 88 84 /*}}}*/ 85 int ObjectEnum(void){/*{{{*/ 86 return ContourEnum; 87 } 88 /*}}}*/ 89 89 90 90 }; -
issm/trunk-jpl/src/c/classes/DependentObject.cpp
r18064 r20810 36 36 37 37 /*Object virtual functions definitions:*/ 38 Object* DependentObject::copy(void) { /*{{{*/ 39 return new DependentObject(name,type,index); 40 } /*}}}*/ 41 void DependentObject::DeepEcho(void){/*{{{*/ 42 this->Echo(); 43 } 44 /*}}}*/ 38 45 void DependentObject::Echo(void){/*{{{*/ 39 46 … … 49 56 } 50 57 /*}}}*/ 51 void DependentObject::DeepEcho(void){/*{{{*/52 this->Echo();53 }54 /*}}}*/55 58 int DependentObject::Id(void){ return -1; }/*{{{*/ 56 59 /*}}}*/ … … 61 64 } 62 65 /*}}}*/ 63 Object* DependentObject::copy(void) { /*{{{*/64 return new DependentObject(name,type,index);65 } /*}}}*/66 66 67 67 /*DependentObject methods: */ -
issm/trunk-jpl/src/c/classes/DependentObject.h
r19198 r20810 27 27 /*}}}*/ 28 28 /*Object virtual functions definitions:{{{ */ 29 Object* copy(void); 30 void DeepEcho(); 29 31 void Echo(); 30 void DeepEcho();31 32 int Id(); 32 33 int ObjectEnum(); 33 Object* copy(void);34 34 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){/*{{{*/ 35 35 _error_("not implemented yet!"); -
issm/trunk-jpl/src/c/classes/DofIndexing.cpp
r20462 r20810 214 214 215 215 /*Some of the Object functionality: */ 216 void DofIndexing::Echo(void){/*{{{*/ 216 void DofIndexing::Activate(void){/*{{{*/ 217 218 this->active = true; 219 220 /*Constrain to 0. at this point*/ 221 for(int i=0;i<this->gsize;i++){ 222 this->f_set[i] = true; 223 this->s_set[i] = false; 224 this->svalues[i] = 0.; 225 } 226 return; 227 } 228 /*}}}*/ 229 void DofIndexing::Deactivate(void){/*{{{*/ 230 this->active = false; 231 232 /*Constrain to 0. at this point*/ 233 for(int i=0;i<this->gsize;i++){ 234 this->f_set[i] = false; 235 this->s_set[i] = true; 236 this->svalues[i] = 0.; 237 } 238 return; 239 } 240 /*}}}*/ 241 void DofIndexing::DeepEcho(void){/*{{{*/ 242 243 int i; 217 244 218 245 _printf_("DofIndexing:\n"); … … 223 250 _printf_(" active: " << active << "\n"); 224 251 _printf_(" freeze: " << freeze << "\n"); 225 } 226 /*}}}*/ 227 void DofIndexing::DeepEcho(void){/*{{{*/ 228 229 int i; 252 253 _printf_(" set membership: f,s sets \n"); 254 for(i=0;i<gsize;i++){ 255 _printf_(" dof " << i << ": " <<(f_set[i]?"true":"false")<< " " <<(s_set[i]?"true":"false") << "\n"); 256 } 257 258 _printf_(" svalues (" << this->ssize << "): |"); 259 for(i=0;i<this->gsize;i++){ 260 if(this->s_set[i])_printf_(" " << svalues[i] << " |"); 261 } 262 _printf_("\n"); 263 264 if(doftype){ 265 _printf_(" doftype: |"); 266 for(i=0;i<gsize;i++){ 267 _printf_(" " << doftype[i] << " |"); 268 } 269 _printf_("\n"); 270 } 271 else _printf_(" doftype: NULL\n"); 272 273 _printf_(" g_doflist (" << this->gsize << "): |"); 274 for(i=0;i<this->gsize;i++){ 275 _printf_(" " << gdoflist[i] << " |"); 276 } 277 _printf_("\n"); 278 279 _printf_(" f_doflist (" << this->fsize << "): |"); 280 for(i=0;i<this->fsize;i++){ 281 _printf_(" " << fdoflist[i] << " |"); 282 } 283 _printf_("\n"); 284 285 _printf_(" s_doflist (" << this->ssize << "): |"); 286 for(i=0;i<this->ssize;i++){ 287 _printf_(" " << sdoflist[i] << " |"); 288 } 289 _printf_("\n"); 290 } 291 /*}}}*/ 292 void DofIndexing::Echo(void){/*{{{*/ 230 293 231 294 _printf_("DofIndexing:\n"); … … 236 299 _printf_(" active: " << active << "\n"); 237 300 _printf_(" freeze: " << freeze << "\n"); 238 239 _printf_(" set membership: f,s sets \n");240 for(i=0;i<gsize;i++){241 _printf_(" dof " << i << ": " <<(f_set[i]?"true":"false")<< " " <<(s_set[i]?"true":"false") << "\n");242 }243 244 _printf_(" svalues (" << this->ssize << "): |");245 for(i=0;i<this->gsize;i++){246 if(this->s_set[i])_printf_(" " << svalues[i] << " |");247 }248 _printf_("\n");249 250 if(doftype){251 _printf_(" doftype: |");252 for(i=0;i<gsize;i++){253 _printf_(" " << doftype[i] << " |");254 }255 _printf_("\n");256 }257 else _printf_(" doftype: NULL\n");258 259 _printf_(" g_doflist (" << this->gsize << "): |");260 for(i=0;i<this->gsize;i++){261 _printf_(" " << gdoflist[i] << " |");262 }263 _printf_("\n");264 265 _printf_(" f_doflist (" << this->fsize << "): |");266 for(i=0;i<this->fsize;i++){267 _printf_(" " << fdoflist[i] << " |");268 }269 _printf_("\n");270 271 _printf_(" s_doflist (" << this->ssize << "): |");272 for(i=0;i<this->ssize;i++){273 _printf_(" " << sdoflist[i] << " |");274 }275 _printf_("\n");276 }277 /*}}}*/278 void DofIndexing::Deactivate(void){/*{{{*/279 this->active = false;280 281 /*Constrain to 0. at this point*/282 for(int i=0;i<this->gsize;i++){283 this->f_set[i] = false;284 this->s_set[i] = true;285 this->svalues[i] = 0.;286 }287 return;288 }289 /*}}}*/290 void DofIndexing::Activate(void){/*{{{*/291 292 this->active = true;293 294 /*Constrain to 0. at this point*/295 for(int i=0;i<this->gsize;i++){296 this->f_set[i] = true;297 this->s_set[i] = false;298 this->svalues[i] = 0.;299 }300 return;301 301 } 302 302 /*}}}*/ -
issm/trunk-jpl/src/c/classes/DofIndexing.h
r20462 r20810 45 45 /*}}}*/ 46 46 /*Object like functionality: {{{*/ 47 void copy(const DofIndexing& in); 48 void DeepEcho(void); 47 49 void Echo(void); 48 void DeepEcho(void);49 void copy(const DofIndexing& in);50 50 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction); 51 51 /*}}}*/ 52 52 /*DofIndexing management: {{{*/ 53 DofIndexing* Spawn(int* indices, int numindices);54 53 void Activate(void); 55 54 void Deactivate(void); 55 DofIndexing* Spawn(int* indices, int numindices); 56 56 /*}}}*/ 57 57 -
issm/trunk-jpl/src/c/classes/Elements/Element.cpp
r20723 r20810 43 43 this->inputs->AddInput(input_in); 44 44 }/*}}}*/ 45 void Element::ComputeLambdaS(){/*{{{*/ 46 47 /*Intermediaries*/ 48 IssmDouble vx,vy,vz,vmag; 49 IssmDouble dvx[3],dvy[3],dvz[3],dvmag[3]; 50 IssmDouble epso,epsprime; 51 int dim; 52 IssmDouble *xyz_list = NULL; 53 54 /*Retrieve all inputs we will be needing: */ 55 this->GetVerticesCoordinates(&xyz_list); 56 parameters->FindParam(&dim,DomainDimensionEnum); 57 Input* vx_input=this->GetInput(VxEnum); _assert_(vx_input); 58 Input* vy_input=this->GetInput(VyEnum); _assert_(vy_input); 59 Input* vz_input=NULL; 60 if(dim==3){vz_input=this->GetInput(VzEnum); _assert_(vz_input);} 61 62 /*Allocate arrays*/ 63 int numvertices = this->GetNumberOfVertices(); 64 IssmDouble* lambdas = xNew<IssmDouble>(numvertices); 65 IssmDouble* vorticityx = xNew<IssmDouble>(numvertices); 66 IssmDouble* vorticityy = xNew<IssmDouble>(numvertices); 67 IssmDouble* vorticityz = xNew<IssmDouble>(numvertices); 68 IssmDouble* omega_corrx = xNew<IssmDouble>(numvertices); 69 IssmDouble* omega_corry = xNew<IssmDouble>(numvertices); 70 IssmDouble* omega_corrz = xNew<IssmDouble>(numvertices); 71 72 /* Start looping on the number of vertices: */ 73 Gauss* gauss=this->NewGauss(); 74 for (int iv=0;iv<numvertices;iv++){ 75 gauss->GaussVertex(iv); 76 77 /*Get velocity derivatives in all directions*/ 78 _assert_(dim>1); 79 _assert_(vx_input); 80 vx_input->GetInputValue(&vx,gauss); 81 vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss); 82 _assert_(vy_input); 83 vy_input->GetInputValue(&vy,gauss); 84 vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss); 85 if(dim==3){ 86 _assert_(vz_input); 87 vz_input->GetInputValue(&vz,gauss); 88 vz_input->GetInputDerivativeValue(&dvz[0],xyz_list,gauss); 89 } 90 else{ 91 vz = 0.; 92 dvz[0] = 0.; dvz[1] = 0.; dvz[2] = 0.; 93 } 94 /*Calculate velocity magnitude and its derivative*/ 95 vmag = sqrt(vx*vx+vy*vy+vz*vz); 96 if(vmag<1e-12){ 97 vmag=1e-12; 98 dvmag[0]=0; 99 dvmag[1]=0; 100 dvmag[2]=0; 101 } 102 else{ 103 dvmag[0]=1./(2*sqrt(vmag))*(2*vx*dvx[0]+2*vy*dvy[0]+2*vz*dvz[0]); 104 dvmag[1]=1./(2*sqrt(vmag))*(2*vx*dvx[1]+2*vy*dvy[1]+2*vz*dvz[1]); 105 dvmag[2]=1./(2*sqrt(vmag))*(2*vx*dvx[2]+2*vy*dvy[2]+2*vz*dvz[2]); 106 } 107 EstarStrainrateQuantities(&epso,&epsprime,vx,vy,vz,vmag,&dvx[0],&dvy[0],&dvz[0],&dvmag[0]); 108 lambdas[iv]=EstarLambdaS(epso,epsprime); 109 vorticityx[iv]=dvz[1]-dvy[2]; 110 vorticityy[iv]=dvx[2]-dvz[0]; 111 vorticityz[iv]=dvy[0]-dvx[1]; 112 omega_corrx[iv] = -vorticityx[iv] + 2*(dvmag[1]*vz - dvmag[2]*vy)/vmag; 113 omega_corry[iv] = -vorticityy[iv] + 2*(dvmag[2]*vx - dvmag[0]*vz)/vmag; 114 omega_corrz[iv] = -vorticityz[iv] + 2*(dvmag[0]*vy - dvmag[1]*vx)/vmag; 115 } 116 117 /*Add Stress tensor components into inputs*/ 118 this->AddInput(LambdaSEnum,lambdas,P1Enum); 119 this->AddInput(Outputdefinition21Enum,vorticityx,P1Enum); 120 this->AddInput(Outputdefinition22Enum,vorticityy,P1Enum); 121 this->AddInput(Outputdefinition23Enum,vorticityz,P1Enum); 122 this->AddInput(Outputdefinition31Enum,omega_corrx,P1Enum); 123 this->AddInput(Outputdefinition32Enum,omega_corry,P1Enum); 124 this->AddInput(Outputdefinition33Enum,omega_corrz,P1Enum); 125 126 /*Clean up and return*/ 127 delete gauss; 128 xDelete<IssmDouble>(xyz_list); 129 xDelete<IssmDouble>(lambdas); 130 131 } 132 /*}}}*/ 45 133 void Element::ComputeNewDamage(){/*{{{*/ 46 134 … … 218 306 xDelete<IssmDouble>(eps_yz); 219 307 xDelete<IssmDouble>(eps_ef); 220 221 }222 /*}}}*/223 void Element::ComputeLambdaS(){/*{{{*/224 225 /*Intermediaries*/226 IssmDouble vx,vy,vz,vmag;227 IssmDouble dvx[3],dvy[3],dvz[3],dvmag[3];228 IssmDouble epso,epsprime;229 int dim;230 IssmDouble *xyz_list = NULL;231 232 /*Retrieve all inputs we will be needing: */233 this->GetVerticesCoordinates(&xyz_list);234 parameters->FindParam(&dim,DomainDimensionEnum);235 Input* vx_input=this->GetInput(VxEnum); _assert_(vx_input);236 Input* vy_input=this->GetInput(VyEnum); _assert_(vy_input);237 Input* vz_input=NULL;238 if(dim==3){vz_input=this->GetInput(VzEnum); _assert_(vz_input);}239 240 /*Allocate arrays*/241 int numvertices = this->GetNumberOfVertices();242 IssmDouble* lambdas = xNew<IssmDouble>(numvertices);243 IssmDouble* vorticityx = xNew<IssmDouble>(numvertices);244 IssmDouble* vorticityy = xNew<IssmDouble>(numvertices);245 IssmDouble* vorticityz = xNew<IssmDouble>(numvertices);246 IssmDouble* omega_corrx = xNew<IssmDouble>(numvertices);247 IssmDouble* omega_corry = xNew<IssmDouble>(numvertices);248 IssmDouble* omega_corrz = xNew<IssmDouble>(numvertices);249 250 /* Start looping on the number of vertices: */251 Gauss* gauss=this->NewGauss();252 for (int iv=0;iv<numvertices;iv++){253 gauss->GaussVertex(iv);254 255 /*Get velocity derivatives in all directions*/256 _assert_(dim>1);257 _assert_(vx_input);258 vx_input->GetInputValue(&vx,gauss);259 vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);260 _assert_(vy_input);261 vy_input->GetInputValue(&vy,gauss);262 vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);263 if(dim==3){264 _assert_(vz_input);265 vz_input->GetInputValue(&vz,gauss);266 vz_input->GetInputDerivativeValue(&dvz[0],xyz_list,gauss);267 }268 else{269 vz = 0.;270 dvz[0] = 0.; dvz[1] = 0.; dvz[2] = 0.;271 }272 /*Calculate velocity magnitude and its derivative*/273 vmag = sqrt(vx*vx+vy*vy+vz*vz);274 if(vmag<1e-12){275 vmag=1e-12;276 dvmag[0]=0;277 dvmag[1]=0;278 dvmag[2]=0;279 }280 else{281 dvmag[0]=1./(2*sqrt(vmag))*(2*vx*dvx[0]+2*vy*dvy[0]+2*vz*dvz[0]);282 dvmag[1]=1./(2*sqrt(vmag))*(2*vx*dvx[1]+2*vy*dvy[1]+2*vz*dvz[1]);283 dvmag[2]=1./(2*sqrt(vmag))*(2*vx*dvx[2]+2*vy*dvy[2]+2*vz*dvz[2]);284 }285 EstarStrainrateQuantities(&epso,&epsprime,vx,vy,vz,vmag,&dvx[0],&dvy[0],&dvz[0],&dvmag[0]);286 lambdas[iv]=EstarLambdaS(epso,epsprime);287 vorticityx[iv]=dvz[1]-dvy[2];288 vorticityy[iv]=dvx[2]-dvz[0];289 vorticityz[iv]=dvy[0]-dvx[1];290 omega_corrx[iv] = -vorticityx[iv] + 2*(dvmag[1]*vz - dvmag[2]*vy)/vmag;291 omega_corry[iv] = -vorticityy[iv] + 2*(dvmag[2]*vx - dvmag[0]*vz)/vmag;292 omega_corrz[iv] = -vorticityz[iv] + 2*(dvmag[0]*vy - dvmag[1]*vx)/vmag;293 }294 295 /*Add Stress tensor components into inputs*/296 this->AddInput(LambdaSEnum,lambdas,P1Enum);297 this->AddInput(Outputdefinition21Enum,vorticityx,P1Enum);298 this->AddInput(Outputdefinition22Enum,vorticityy,P1Enum);299 this->AddInput(Outputdefinition23Enum,vorticityz,P1Enum);300 this->AddInput(Outputdefinition31Enum,omega_corrx,P1Enum);301 this->AddInput(Outputdefinition32Enum,omega_corry,P1Enum);302 this->AddInput(Outputdefinition33Enum,omega_corrz,P1Enum);303 304 /*Clean up and return*/305 delete gauss;306 xDelete<IssmDouble>(xyz_list);307 xDelete<IssmDouble>(lambdas);308 308 309 309 } … … 426 426 delete this->material; 427 427 }/*}}}*/ 428 IssmDouble Element::Divergence(void){/*{{{*/429 /*Compute element divergence*/430 431 /*Intermediaries*/432 int dim;433 IssmDouble Jdet;434 IssmDouble divergence=0.;435 IssmDouble dvx[3],dvy[3],dvz[3];436 IssmDouble *xyz_list = NULL;437 438 /*Get inputs and parameters*/439 this->FindParam(&dim,DomainDimensionEnum);440 Input* vx_input = this->GetInput(VxEnum); _assert_(vx_input);441 Input* vy_input = this->GetInput(VyEnum); _assert_(vy_input);442 Input* vz_input = NULL;443 if(dim==3){444 vz_input = this->GetInput(VzEnum); _assert_(vz_input);445 }446 this->GetVerticesCoordinates(&xyz_list);447 448 Gauss* gauss=this->NewGauss(5);449 for(int ig=gauss->begin();ig<gauss->end();ig++){450 gauss->GaussPoint(ig);451 this->JacobianDeterminant(&Jdet,xyz_list,gauss);452 453 /*Get strain rate assuming that epsilon has been allocated*/454 vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss);455 vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss);456 if(dim==2){457 divergence += (dvx[0]+dvy[1])*gauss->weight*Jdet;458 }459 else{460 vz_input->GetInputDerivativeValue(&dvz[0],xyz_list,gauss);461 divergence += (dvx[0]+dvy[1]+dvz[2])*gauss->weight*Jdet;462 }463 464 }465 466 /*Clean up and return*/467 xDelete<IssmDouble>(xyz_list);468 delete gauss;469 return divergence;470 }/*}}}*/471 void Element::dViscositydBFS(IssmDouble* pdmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input){/*{{{*/472 473 /*Intermediaries*/474 IssmDouble dmudB;475 IssmDouble epsilon3d[6];/* epsilon=[exx,eyy,exy,exy,exz,eyz]; */476 IssmDouble epsilon2d[3];/* epsilon=[exx,eyy,exy]; */477 IssmDouble eps_eff;478 IssmDouble eps0=1.e-27;479 480 if(dim==3){481 /* eps_eff^2 = exx^2 + eyy^2 + exy^2 + exz^2 + eyz^2 + exx*eyy */482 this->StrainRateFS(&epsilon3d[0],xyz_list,gauss,vx_input,vy_input,vz_input);483 eps_eff = sqrt(epsilon3d[0]*epsilon3d[0] + epsilon3d[1]*epsilon3d[1] + epsilon3d[3]*epsilon3d[3] + epsilon3d[4]*epsilon3d[4] + epsilon3d[5]*epsilon3d[5] + epsilon3d[0]*epsilon3d[1]+eps0*eps0);484 }485 else{486 /* eps_eff^2 = 1/2 ( exx^2 + eyy^2 + 2*exy^2 )*/487 this->StrainRateSSA(&epsilon2d[0],xyz_list,gauss,vx_input,vy_input);488 eps_eff = 1./sqrt(2.)*sqrt(epsilon2d[0]*epsilon2d[0] + epsilon2d[1]*epsilon2d[1] + 2.*epsilon2d[2]*epsilon2d[2]);489 }490 /*Get viscosity*/491 material->GetViscosity_B(&dmudB,eps_eff);492 493 /*Assign output pointer*/494 *pdmudB=dmudB;495 496 }497 /*}}}*/498 void Element::dViscositydBHO(IssmDouble* pdmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/499 500 /*Intermediaries*/501 IssmDouble dmudB;502 IssmDouble epsilon3d[5];/* epsilon=[exx,eyy,exy,exy,exz,eyz]; */503 IssmDouble epsilon2d[2];/* epsilon=[exx,eyy,exy]; */504 IssmDouble eps_eff;505 IssmDouble eps0=1.e-27;506 507 if(dim==3){508 /* eps_eff^2 = exx^2 + eyy^2 + exy^2 + exz^2 + eyz^2 + exx*eyy */509 this->StrainRateHO(&epsilon3d[0],xyz_list,gauss,vx_input,vy_input);510 eps_eff = sqrt(epsilon3d[0]*epsilon3d[0] + epsilon3d[1]*epsilon3d[1] + epsilon3d[2]*epsilon3d[2] + epsilon3d[3]*epsilon3d[3] + epsilon3d[4]*epsilon3d[4] + epsilon3d[0]*epsilon3d[1]+eps0*eps0);511 }512 else{513 /* eps_eff^2 = 1/2 ( exx^2 + eyy^2 + 2*exy^2 )*/514 this->StrainRateHO2dvertical(&epsilon2d[0],xyz_list,gauss,vx_input,vy_input);515 eps_eff = 1./sqrt(2.)*sqrt(epsilon2d[0]*epsilon2d[0] + 2.*epsilon2d[1]*epsilon2d[1] + eps0*eps0);516 }517 /*Get viscosity*/518 material->GetViscosity_B(&dmudB,eps_eff);519 520 /*Assign output pointer*/521 *pdmudB=dmudB;522 523 }524 /*}}}*/525 void Element::dViscositydBSSA(IssmDouble* pdmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/526 527 /*Intermediaries*/528 IssmDouble dmudB;529 IssmDouble epsilon2d[3];/* epsilon=[exx,eyy,exy]; */530 IssmDouble epsilon1d; /* epsilon=[exx]; */531 IssmDouble eps_eff;532 533 if(dim==2){534 /* eps_eff^2 = exx^2 + eyy^2 + exy^2 + exx*eyy*/535 this->StrainRateSSA(&epsilon2d[0],xyz_list,gauss,vx_input,vy_input);536 eps_eff = sqrt(epsilon2d[0]*epsilon2d[0] + epsilon2d[1]*epsilon2d[1] + epsilon2d[2]*epsilon2d[2] + epsilon2d[0]*epsilon2d[1]);537 }538 else{539 /* eps_eff^2 = 1/2 exx^2*/540 this->StrainRateSSA1d(&epsilon1d,xyz_list,gauss,vx_input);541 eps_eff = sqrt(epsilon1d*epsilon1d/2.);542 }543 544 /*Get viscosity*/545 material->GetViscosity_B(&dmudB,eps_eff);546 547 /*Assign output pointer*/548 *pdmudB=dmudB;549 550 }551 /*}}}*/552 void Element::dViscositydDSSA(IssmDouble* pdmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/553 554 /*Intermediaries*/555 IssmDouble dmudB;556 IssmDouble epsilon2d[3];/* epsilon=[exx,eyy,exy]; */557 IssmDouble epsilon1d; /* epsilon=[exx]; */558 IssmDouble eps_eff;559 560 if(dim==2){561 /* eps_eff^2 = exx^2 + eyy^2 + exy^2 + exx*eyy*/562 this->StrainRateSSA(&epsilon2d[0],xyz_list,gauss,vx_input,vy_input);563 eps_eff = sqrt(epsilon2d[0]*epsilon2d[0] + epsilon2d[1]*epsilon2d[1] + epsilon2d[2]*epsilon2d[2] + epsilon2d[0]*epsilon2d[1]);564 }565 else{566 /* eps_eff^2 = 1/2 exx^2*/567 this->StrainRateSSA1d(&epsilon1d,xyz_list,gauss,vx_input);568 eps_eff = sqrt(epsilon1d*epsilon1d/2.);569 }570 571 /*Get viscosity*/572 material->GetViscosity_D(&dmudB,eps_eff);573 574 /*Assign output pointer*/575 *pdmudB=dmudB;576 577 }578 /*}}}*/579 428 void Element::Delta18oParameterization(void){/*{{{*/ 580 429 … … 681 530 } 682 531 /*}}}*/ 683 void Element::MungsmtpParameterization(void){/*{{{*/684 /*Are we on the base? If not, return*/685 if(!IsOnBase()) return;686 687 int numvertices = this->GetNumberOfVertices();688 689 int i;690 IssmDouble* monthlytemperatures=xNew<IssmDouble>(12*numvertices);691 IssmDouble* monthlyprec=xNew<IssmDouble>(12*numvertices);692 IssmDouble* TemperaturesPresentday=xNew<IssmDouble>(12*numvertices);693 IssmDouble* TemperaturesLgm=xNew<IssmDouble>(12*numvertices);694 IssmDouble* PrecipitationsPresentday=xNew<IssmDouble>(12*numvertices);695 IssmDouble* PrecipitationsLgm=xNew<IssmDouble>(12*numvertices);696 IssmDouble* tmp=xNew<IssmDouble>(numvertices);697 IssmDouble TdiffTime,PfacTime;698 IssmDouble time,yts,time_yr;699 this->parameters->FindParam(&time,TimeEnum);700 this->parameters->FindParam(&yts,ConstantsYtsEnum);701 time_yr=floor(time/yts)*yts;702 703 /*Recover present day temperature and precipitation*/704 Input* input=this->inputs->GetInput(SmbTemperaturesPresentdayEnum); _assert_(input);705 Input* input2=this->inputs->GetInput(SmbTemperaturesLgmEnum); _assert_(input2);706 Input* input3=this->inputs->GetInput(SmbPrecipitationsPresentdayEnum); _assert_(input3);707 Input* input4=this->inputs->GetInput(SmbPrecipitationsLgmEnum); _assert_(input4);708 /*loop over vertices: */709 Gauss* gauss=this->NewGauss();710 for(int month=0;month<12;month++) {711 for(int iv=0;iv<numvertices;iv++) {712 gauss->GaussVertex(iv);713 input->GetInputValue(&TemperaturesPresentday[iv*12+month],gauss,month/12.*yts);714 input2->GetInputValue(&TemperaturesLgm[iv*12+month],gauss,month/12.*yts);715 input3->GetInputValue(&PrecipitationsPresentday[iv*12+month],gauss,month/12.*yts);716 input4->GetInputValue(&PrecipitationsLgm[iv*12+month],gauss,month/12.*yts);717 718 PrecipitationsPresentday[iv*12+month]=PrecipitationsPresentday[iv*12+month]*yts;719 PrecipitationsLgm[iv*12+month]=PrecipitationsLgm[iv*12+month]*yts;720 }721 }722 723 /*Recover interpolation parameters at time t*/724 this->parameters->FindParam(&TdiffTime,SmbTdiffEnum,time);725 this->parameters->FindParam(&PfacTime,SmbPfacEnum,time);726 727 /*Compute the temperature and precipitation*/728 for(int iv=0;iv<numvertices;iv++){729 ComputeMungsmTemperaturePrecipitation(TdiffTime,PfacTime,730 &PrecipitationsLgm[iv*12],&PrecipitationsPresentday[iv*12],731 &TemperaturesLgm[iv*12], &TemperaturesPresentday[iv*12],732 &monthlytemperatures[iv*12], &monthlyprec[iv*12]);733 }734 735 /*Update inputs*/736 TransientInput* NewTemperatureInput = new TransientInput(SmbMonthlytemperaturesEnum);737 TransientInput* NewPrecipitationInput = new TransientInput(SmbPrecipitationEnum);738 for (int imonth=0;imonth<12;imonth++) {739 for(i=0;i<numvertices;i++) tmp[i]=monthlytemperatures[i*12+imonth];740 switch(this->ObjectEnum()){741 case TriaEnum: NewTemperatureInput->AddTimeInput(new TriaInput(SmbMonthlytemperaturesEnum,&tmp[0],P1Enum),time_yr+imonth/12.*yts); break;742 case PentaEnum: NewTemperatureInput->AddTimeInput(new PentaInput(SmbMonthlytemperaturesEnum,&tmp[0],P1Enum),time_yr+imonth/12.*yts); break;743 case TetraEnum: NewTemperatureInput->AddTimeInput(new TetraInput(SmbMonthlytemperaturesEnum,&tmp[0],P1Enum),time_yr+imonth/12.*yts); break;744 default: _error_("Not implemented yet");745 }746 for(i=0;i<numvertices;i++) tmp[i]=monthlyprec[i*12+imonth]/yts;747 switch(this->ObjectEnum()){748 case TriaEnum: NewPrecipitationInput->AddTimeInput(new TriaInput(SmbPrecipitationEnum,&tmp[0],P1Enum),time_yr+imonth/12.*yts); break;749 case PentaEnum: NewPrecipitationInput->AddTimeInput(new PentaInput(SmbPrecipitationEnum,&tmp[0],P1Enum),time_yr+imonth/12.*yts); break;750 case TetraEnum: NewPrecipitationInput->AddTimeInput(new TetraInput(SmbPrecipitationEnum,&tmp[0],P1Enum),time_yr+imonth/12.*yts); break;751 default: _error_("Not implemented yet");752 }753 }754 NewTemperatureInput->Configure(this->parameters);755 NewPrecipitationInput->Configure(this->parameters);756 757 this->inputs->AddInput(NewTemperatureInput);758 this->inputs->AddInput(NewPrecipitationInput);759 760 switch(this->ObjectEnum()){761 case TriaEnum: break;762 case PentaEnum:763 case TetraEnum:764 this->InputExtrude(SmbMonthlytemperaturesEnum,-1);765 this->InputExtrude(SmbPrecipitationEnum,-1);766 break;767 default: _error_("Not implemented yet");768 }769 770 /*clean-up*/771 delete gauss;772 xDelete<IssmDouble>(monthlytemperatures);773 xDelete<IssmDouble>(monthlyprec);774 xDelete<IssmDouble>(TemperaturesPresentday);775 xDelete<IssmDouble>(TemperaturesLgm);776 xDelete<IssmDouble>(PrecipitationsPresentday);777 xDelete<IssmDouble>(PrecipitationsLgm);778 xDelete<IssmDouble>(tmp);779 780 }781 /*}}}*/782 532 void Element::Delta18opdParameterization(void){/*{{{*/ 783 533 /*Are we on the base? If not, return*/ … … 870 620 xDelete<IssmDouble>(tmp); 871 621 622 } 623 /*}}}*/ 624 IssmDouble Element::Divergence(void){/*{{{*/ 625 /*Compute element divergence*/ 626 627 /*Intermediaries*/ 628 int dim; 629 IssmDouble Jdet; 630 IssmDouble divergence=0.; 631 IssmDouble dvx[3],dvy[3],dvz[3]; 632 IssmDouble *xyz_list = NULL; 633 634 /*Get inputs and parameters*/ 635 this->FindParam(&dim,DomainDimensionEnum); 636 Input* vx_input = this->GetInput(VxEnum); _assert_(vx_input); 637 Input* vy_input = this->GetInput(VyEnum); _assert_(vy_input); 638 Input* vz_input = NULL; 639 if(dim==3){ 640 vz_input = this->GetInput(VzEnum); _assert_(vz_input); 641 } 642 this->GetVerticesCoordinates(&xyz_list); 643 644 Gauss* gauss=this->NewGauss(5); 645 for(int ig=gauss->begin();ig<gauss->end();ig++){ 646 gauss->GaussPoint(ig); 647 this->JacobianDeterminant(&Jdet,xyz_list,gauss); 648 649 /*Get strain rate assuming that epsilon has been allocated*/ 650 vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss); 651 vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss); 652 if(dim==2){ 653 divergence += (dvx[0]+dvy[1])*gauss->weight*Jdet; 654 } 655 else{ 656 vz_input->GetInputDerivativeValue(&dvz[0],xyz_list,gauss); 657 divergence += (dvx[0]+dvy[1]+dvz[2])*gauss->weight*Jdet; 658 } 659 660 } 661 662 /*Clean up and return*/ 663 xDelete<IssmDouble>(xyz_list); 664 delete gauss; 665 return divergence; 666 }/*}}}*/ 667 void Element::dViscositydBFS(IssmDouble* pdmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input){/*{{{*/ 668 669 /*Intermediaries*/ 670 IssmDouble dmudB; 671 IssmDouble epsilon3d[6];/* epsilon=[exx,eyy,exy,exy,exz,eyz]; */ 672 IssmDouble epsilon2d[3];/* epsilon=[exx,eyy,exy]; */ 673 IssmDouble eps_eff; 674 IssmDouble eps0=1.e-27; 675 676 if(dim==3){ 677 /* eps_eff^2 = exx^2 + eyy^2 + exy^2 + exz^2 + eyz^2 + exx*eyy */ 678 this->StrainRateFS(&epsilon3d[0],xyz_list,gauss,vx_input,vy_input,vz_input); 679 eps_eff = sqrt(epsilon3d[0]*epsilon3d[0] + epsilon3d[1]*epsilon3d[1] + epsilon3d[3]*epsilon3d[3] + epsilon3d[4]*epsilon3d[4] + epsilon3d[5]*epsilon3d[5] + epsilon3d[0]*epsilon3d[1]+eps0*eps0); 680 } 681 else{ 682 /* eps_eff^2 = 1/2 ( exx^2 + eyy^2 + 2*exy^2 )*/ 683 this->StrainRateSSA(&epsilon2d[0],xyz_list,gauss,vx_input,vy_input); 684 eps_eff = 1./sqrt(2.)*sqrt(epsilon2d[0]*epsilon2d[0] + epsilon2d[1]*epsilon2d[1] + 2.*epsilon2d[2]*epsilon2d[2]); 685 } 686 /*Get viscosity*/ 687 material->GetViscosity_B(&dmudB,eps_eff); 688 689 /*Assign output pointer*/ 690 *pdmudB=dmudB; 691 692 } 693 /*}}}*/ 694 void Element::dViscositydBHO(IssmDouble* pdmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/ 695 696 /*Intermediaries*/ 697 IssmDouble dmudB; 698 IssmDouble epsilon3d[5];/* epsilon=[exx,eyy,exy,exy,exz,eyz]; */ 699 IssmDouble epsilon2d[2];/* epsilon=[exx,eyy,exy]; */ 700 IssmDouble eps_eff; 701 IssmDouble eps0=1.e-27; 702 703 if(dim==3){ 704 /* eps_eff^2 = exx^2 + eyy^2 + exy^2 + exz^2 + eyz^2 + exx*eyy */ 705 this->StrainRateHO(&epsilon3d[0],xyz_list,gauss,vx_input,vy_input); 706 eps_eff = sqrt(epsilon3d[0]*epsilon3d[0] + epsilon3d[1]*epsilon3d[1] + epsilon3d[2]*epsilon3d[2] + epsilon3d[3]*epsilon3d[3] + epsilon3d[4]*epsilon3d[4] + epsilon3d[0]*epsilon3d[1]+eps0*eps0); 707 } 708 else{ 709 /* eps_eff^2 = 1/2 ( exx^2 + eyy^2 + 2*exy^2 )*/ 710 this->StrainRateHO2dvertical(&epsilon2d[0],xyz_list,gauss,vx_input,vy_input); 711 eps_eff = 1./sqrt(2.)*sqrt(epsilon2d[0]*epsilon2d[0] + 2.*epsilon2d[1]*epsilon2d[1] + eps0*eps0); 712 } 713 /*Get viscosity*/ 714 material->GetViscosity_B(&dmudB,eps_eff); 715 716 /*Assign output pointer*/ 717 *pdmudB=dmudB; 718 719 } 720 /*}}}*/ 721 void Element::dViscositydBSSA(IssmDouble* pdmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/ 722 723 /*Intermediaries*/ 724 IssmDouble dmudB; 725 IssmDouble epsilon2d[3];/* epsilon=[exx,eyy,exy]; */ 726 IssmDouble epsilon1d; /* epsilon=[exx]; */ 727 IssmDouble eps_eff; 728 729 if(dim==2){ 730 /* eps_eff^2 = exx^2 + eyy^2 + exy^2 + exx*eyy*/ 731 this->StrainRateSSA(&epsilon2d[0],xyz_list,gauss,vx_input,vy_input); 732 eps_eff = sqrt(epsilon2d[0]*epsilon2d[0] + epsilon2d[1]*epsilon2d[1] + epsilon2d[2]*epsilon2d[2] + epsilon2d[0]*epsilon2d[1]); 733 } 734 else{ 735 /* eps_eff^2 = 1/2 exx^2*/ 736 this->StrainRateSSA1d(&epsilon1d,xyz_list,gauss,vx_input); 737 eps_eff = sqrt(epsilon1d*epsilon1d/2.); 738 } 739 740 /*Get viscosity*/ 741 material->GetViscosity_B(&dmudB,eps_eff); 742 743 /*Assign output pointer*/ 744 *pdmudB=dmudB; 745 746 } 747 /*}}}*/ 748 void Element::dViscositydDSSA(IssmDouble* pdmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input){/*{{{*/ 749 750 /*Intermediaries*/ 751 IssmDouble dmudB; 752 IssmDouble epsilon2d[3];/* epsilon=[exx,eyy,exy]; */ 753 IssmDouble epsilon1d; /* epsilon=[exx]; */ 754 IssmDouble eps_eff; 755 756 if(dim==2){ 757 /* eps_eff^2 = exx^2 + eyy^2 + exy^2 + exx*eyy*/ 758 this->StrainRateSSA(&epsilon2d[0],xyz_list,gauss,vx_input,vy_input); 759 eps_eff = sqrt(epsilon2d[0]*epsilon2d[0] + epsilon2d[1]*epsilon2d[1] + epsilon2d[2]*epsilon2d[2] + epsilon2d[0]*epsilon2d[1]); 760 } 761 else{ 762 /* eps_eff^2 = 1/2 exx^2*/ 763 this->StrainRateSSA1d(&epsilon1d,xyz_list,gauss,vx_input); 764 eps_eff = sqrt(epsilon1d*epsilon1d/2.); 765 } 766 767 /*Get viscosity*/ 768 material->GetViscosity_D(&dmudB,eps_eff); 769 770 /*Assign output pointer*/ 771 *pdmudB=dmudB; 772 872 773 } 873 774 /*}}}*/ … … 1554 1455 bool Element::IsIceInElement(){/*{{{*/ 1555 1456 return (this->inputs->Min(MaskIceLevelsetEnum)<0.); 1556 }1557 /*}}}*/1558 bool Element::IsWaterInElement(){/*{{{*/1559 return (this->inputs->Max(MaskOceanLevelsetEnum)>0.);1560 }1561 /*}}}*/1562 bool Element::IsLandInElement(){/*{{{*/1563 return (this->inputs->Max(MaskLandLevelsetEnum)>0.);1564 1457 } 1565 1458 /*}}}*/ … … 1650 1543 } 1651 1544 /*}}}*/ 1545 bool Element::IsLandInElement(){/*{{{*/ 1546 return (this->inputs->Max(MaskLandLevelsetEnum)>0.); 1547 } 1548 /*}}}*/ 1549 bool Element::IsWaterInElement(){/*{{{*/ 1550 return (this->inputs->Max(MaskOceanLevelsetEnum)>0.); 1551 } 1552 /*}}}*/ 1652 1553 void Element::LinearFloatingiceMeltingRate(){/*{{{*/ 1653 1554 … … 1860 1761 1861 1762 }/*}}}*/ 1763 void Element::MungsmtpParameterization(void){/*{{{*/ 1764 /*Are we on the base? If not, return*/ 1765 if(!IsOnBase()) return; 1766 1767 int numvertices = this->GetNumberOfVertices(); 1768 1769 int i; 1770 IssmDouble* monthlytemperatures=xNew<IssmDouble>(12*numvertices); 1771 IssmDouble* monthlyprec=xNew<IssmDouble>(12*numvertices); 1772 IssmDouble* TemperaturesPresentday=xNew<IssmDouble>(12*numvertices); 1773 IssmDouble* TemperaturesLgm=xNew<IssmDouble>(12*numvertices); 1774 IssmDouble* PrecipitationsPresentday=xNew<IssmDouble>(12*numvertices); 1775 IssmDouble* PrecipitationsLgm=xNew<IssmDouble>(12*numvertices); 1776 IssmDouble* tmp=xNew<IssmDouble>(numvertices); 1777 IssmDouble TdiffTime,PfacTime; 1778 IssmDouble time,yts,time_yr; 1779 this->parameters->FindParam(&time,TimeEnum); 1780 this->parameters->FindParam(&yts,ConstantsYtsEnum); 1781 time_yr=floor(time/yts)*yts; 1782 1783 /*Recover present day temperature and precipitation*/ 1784 Input* input=this->inputs->GetInput(SmbTemperaturesPresentdayEnum); _assert_(input); 1785 Input* input2=this->inputs->GetInput(SmbTemperaturesLgmEnum); _assert_(input2); 1786 Input* input3=this->inputs->GetInput(SmbPrecipitationsPresentdayEnum); _assert_(input3); 1787 Input* input4=this->inputs->GetInput(SmbPrecipitationsLgmEnum); _assert_(input4); 1788 /*loop over vertices: */ 1789 Gauss* gauss=this->NewGauss(); 1790 for(int month=0;month<12;month++) { 1791 for(int iv=0;iv<numvertices;iv++) { 1792 gauss->GaussVertex(iv); 1793 input->GetInputValue(&TemperaturesPresentday[iv*12+month],gauss,month/12.*yts); 1794 input2->GetInputValue(&TemperaturesLgm[iv*12+month],gauss,month/12.*yts); 1795 input3->GetInputValue(&PrecipitationsPresentday[iv*12+month],gauss,month/12.*yts); 1796 input4->GetInputValue(&PrecipitationsLgm[iv*12+month],gauss,month/12.*yts); 1797 1798 PrecipitationsPresentday[iv*12+month]=PrecipitationsPresentday[iv*12+month]*yts; 1799 PrecipitationsLgm[iv*12+month]=PrecipitationsLgm[iv*12+month]*yts; 1800 } 1801 } 1802 1803 /*Recover interpolation parameters at time t*/ 1804 this->parameters->FindParam(&TdiffTime,SmbTdiffEnum,time); 1805 this->parameters->FindParam(&PfacTime,SmbPfacEnum,time); 1806 1807 /*Compute the temperature and precipitation*/ 1808 for(int iv=0;iv<numvertices;iv++){ 1809 ComputeMungsmTemperaturePrecipitation(TdiffTime,PfacTime, 1810 &PrecipitationsLgm[iv*12],&PrecipitationsPresentday[iv*12], 1811 &TemperaturesLgm[iv*12], &TemperaturesPresentday[iv*12], 1812 &monthlytemperatures[iv*12], &monthlyprec[iv*12]); 1813 } 1814 1815 /*Update inputs*/ 1816 TransientInput* NewTemperatureInput = new TransientInput(SmbMonthlytemperaturesEnum); 1817 TransientInput* NewPrecipitationInput = new TransientInput(SmbPrecipitationEnum); 1818 for (int imonth=0;imonth<12;imonth++) { 1819 for(i=0;i<numvertices;i++) tmp[i]=monthlytemperatures[i*12+imonth]; 1820 switch(this->ObjectEnum()){ 1821 case TriaEnum: NewTemperatureInput->AddTimeInput(new TriaInput(SmbMonthlytemperaturesEnum,&tmp[0],P1Enum),time_yr+imonth/12.*yts); break; 1822 case PentaEnum: NewTemperatureInput->AddTimeInput(new PentaInput(SmbMonthlytemperaturesEnum,&tmp[0],P1Enum),time_yr+imonth/12.*yts); break; 1823 case TetraEnum: NewTemperatureInput->AddTimeInput(new TetraInput(SmbMonthlytemperaturesEnum,&tmp[0],P1Enum),time_yr+imonth/12.*yts); break; 1824 default: _error_("Not implemented yet"); 1825 } 1826 for(i=0;i<numvertices;i++) tmp[i]=monthlyprec[i*12+imonth]/yts; 1827 switch(this->ObjectEnum()){ 1828 case TriaEnum: NewPrecipitationInput->AddTimeInput(new TriaInput(SmbPrecipitationEnum,&tmp[0],P1Enum),time_yr+imonth/12.*yts); break; 1829 case PentaEnum: NewPrecipitationInput->AddTimeInput(new PentaInput(SmbPrecipitationEnum,&tmp[0],P1Enum),time_yr+imonth/12.*yts); break; 1830 case TetraEnum: NewPrecipitationInput->AddTimeInput(new TetraInput(SmbPrecipitationEnum,&tmp[0],P1Enum),time_yr+imonth/12.*yts); break; 1831 default: _error_("Not implemented yet"); 1832 } 1833 } 1834 NewTemperatureInput->Configure(this->parameters); 1835 NewPrecipitationInput->Configure(this->parameters); 1836 1837 this->inputs->AddInput(NewTemperatureInput); 1838 this->inputs->AddInput(NewPrecipitationInput); 1839 1840 switch(this->ObjectEnum()){ 1841 case TriaEnum: break; 1842 case PentaEnum: 1843 case TetraEnum: 1844 this->InputExtrude(SmbMonthlytemperaturesEnum,-1); 1845 this->InputExtrude(SmbPrecipitationEnum,-1); 1846 break; 1847 default: _error_("Not implemented yet"); 1848 } 1849 1850 /*clean-up*/ 1851 delete gauss; 1852 xDelete<IssmDouble>(monthlytemperatures); 1853 xDelete<IssmDouble>(monthlyprec); 1854 xDelete<IssmDouble>(TemperaturesPresentday); 1855 xDelete<IssmDouble>(TemperaturesLgm); 1856 xDelete<IssmDouble>(PrecipitationsPresentday); 1857 xDelete<IssmDouble>(PrecipitationsLgm); 1858 xDelete<IssmDouble>(tmp); 1859 1860 } 1861 /*}}}*/ 1862 1862 ElementMatrix* Element::NewElementMatrix(int approximation_enum){/*{{{*/ 1863 1863 return new ElementMatrix(nodes,this->GetNumberOfNodes(),this->parameters,approximation_enum); … … 2069 2069 switch(calvinglaw){ 2070 2070 case DefaultCalvingEnum: 2071 case CalvingMinthicknessEnum:2072 2071 //do nothing 2073 2072 break; -
issm/trunk-jpl/src/c/classes/Elements/Element.h
r20723 r20810 63 63 void ComputeStrainRate(); 64 64 void CoordinateSystemTransform(IssmDouble** ptransform,Node** nodes,int numnodes,int* cs_array); 65 void Echo();66 65 void DeepEcho(); 67 66 void DeleteInput(int input_enum); 68 67 void DeleteMaterials(void); 69 68 void Delta18oParameterization(void); 70 void MungsmtpParameterization(void);71 69 void Delta18opdParameterization(void); 72 70 IssmDouble Divergence(void); … … 75 73 void dViscositydBSSA(IssmDouble* pdmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input); 76 74 void dViscositydDSSA(IssmDouble* pdmudB,int dim,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input); 75 void Echo(); 77 76 IssmDouble EnthalpyDiffusionParameter(IssmDouble enthalpy,IssmDouble pressure); 78 77 IssmDouble EnthalpyDiffusionParameterVolume(int numvertices,IssmDouble* enthalpy,IssmDouble* pressure); … … 120 119 bool IsFloating(); 121 120 bool IsIceInElement(); 121 bool IsInput(int name); 122 bool IsLandInElement(); 122 123 bool IsWaterInElement(); 123 bool IsLandInElement();124 bool IsInput(int name);125 124 void LinearFloatingiceMeltingRate(); 126 125 void MantlePlumeGeothermalFlux(); … … 128 127 void MigrateGroundingLine(IssmDouble* sheet_ungrounding); 129 128 void MismipFloatingiceMeltingRate(); 129 void MungsmtpParameterization(void); 130 130 ElementMatrix* NewElementMatrix(int approximation_enum=NoneApproximationEnum); 131 131 ElementMatrix* NewElementMatrixCoupling(int number_nodes,int approximation_enum=NoneApproximationEnum); … … 174 174 virtual void AddInput(int input_enum, IssmDouble* values, int interpolation_enum)=0; 175 175 virtual void AverageOntoPartition(Vector<IssmDouble>* partition_contributions,Vector<IssmDouble>* partition_areas,IssmDouble* vertex_response,IssmDouble* qmu_part)=0; 176 virtual void CalvingRateDev(void){_error_("not implemented yet");}; 176 177 virtual void CalvingRateLevermann(void)=0; 177 virtual void CalvingRateDev(void){_error_("not implemented yet");};178 virtual void WriteLevelsetSegment(DataSet* segments){_error_("not implemented yet");};179 virtual void ResetLevelsetFromSegmentlist(IssmDouble* segments,int numsegments){_error_("not implemented yet");};180 178 virtual IssmDouble CharacteristicLength(void)=0; 181 179 virtual void ComputeBasalStress(Vector<IssmDouble>* sigma_b)=0; … … 266 264 virtual void ResetFSBasalBoundaryCondition()=0; 267 265 virtual void ResetHooks()=0; 266 virtual void ResetLevelsetFromSegmentlist(IssmDouble* segments,int numsegments){_error_("not implemented yet");}; 268 267 virtual void SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index)=0; 269 268 virtual void SetCurrentConfiguration(Elements* elements,Loads* loads,Nodes* nodes,Materials* materials,Parameters* parameters)=0; … … 291 290 virtual void VerticalSegmentIndices(int** pindices,int* pnumseg)=0; 292 291 virtual void ViscousHeating(IssmDouble* pphi,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input)=0; 292 virtual void WriteLevelsetSegment(DataSet* segments){_error_("not implemented yet");}; 293 293 virtual void ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum)=0; 294 294 … … 297 297 #endif 298 298 #ifdef _HAVE_SEALEVELRISE_ 299 virtual IssmDouble GetArea3D(void)=0; 300 virtual IssmDouble OceanAverage(IssmDouble* Sg)=0; 301 virtual IssmDouble OceanArea(void)=0; 299 302 virtual void SealevelriseEustatic(Vector<IssmDouble>* pSgi,IssmDouble* peustatic,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble oceanarea,IssmDouble eartharea)=0; 300 303 virtual void SealevelriseNonEustatic(Vector<IssmDouble>* pSgo,IssmDouble* Sg_old,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble oceanarea,IssmDouble eartharea)=0; 301 virtual IssmDouble OceanAverage(IssmDouble* Sg)=0;302 virtual IssmDouble OceanArea(void)=0;303 virtual IssmDouble GetArea3D(void)=0;304 304 #endif 305 305 -
issm/trunk-jpl/src/c/classes/Elements/Elements.cpp
r18521 r20810 48 48 } 49 49 /*}}}*/ 50 void Elements:: SetCurrentConfiguration(Elements* elements,Loads* loads, Nodes* nodes, Vertices* vertices, Materials* materials,Parameters* parameters){/*{{{*/50 void Elements::InputDuplicate(int input_enum,int output_enum){/*{{{*/ 51 51 52 vector<Object*>::iterator object; 53 Element* element=NULL; 54 55 for ( object=objects.begin() ; object < objects.end(); object++ ){ 56 57 element=xDynamicCast<Element*>((*object)); 58 element->SetCurrentConfiguration(elements,loads,nodes,materials,parameters); 59 52 for(int i=0;i<this->Size();i++){ 53 Element* element=xDynamicCast<Element*>(this->GetObjectByOffset(i)); 54 element->InputDuplicate(input_enum,output_enum); 60 55 } 61 62 }63 /*}}}*/64 void Elements::ResetHooks(){/*{{{*/65 66 vector<Object*>::iterator object;67 Element* element=NULL;68 69 for ( object=objects.begin() ; object < objects.end(); object++ ){70 71 element=xDynamicCast<Element*>((*object));72 element->ResetHooks();73 74 }75 76 56 } 77 57 /*}}}*/ … … 108 88 } 109 89 /*}}}*/ 110 void Elements:: InputDuplicate(int input_enum,int output_enum){/*{{{*/90 void Elements::ResetHooks(){/*{{{*/ 111 91 112 for(int i=0;i<this->Size();i++){ 113 Element* element=xDynamicCast<Element*>(this->GetObjectByOffset(i)); 114 element->InputDuplicate(input_enum,output_enum); 92 vector<Object*>::iterator object; 93 Element* element=NULL; 94 95 for ( object=objects.begin() ; object < objects.end(); object++ ){ 96 97 element=xDynamicCast<Element*>((*object)); 98 element->ResetHooks(); 99 115 100 } 101 116 102 } 117 103 /*}}}*/ 104 void Elements::SetCurrentConfiguration(Elements* elements,Loads* loads, Nodes* nodes, Vertices* vertices, Materials* materials,Parameters* parameters){/*{{{*/ 105 106 vector<Object*>::iterator object; 107 Element* element=NULL; 108 109 for ( object=objects.begin() ; object < objects.end(); object++ ){ 110 111 element=xDynamicCast<Element*>((*object)); 112 element->SetCurrentConfiguration(elements,loads,nodes,materials,parameters); 113 114 } 115 116 } 117 /*}}}*/ -
issm/trunk-jpl/src/c/classes/Elements/Elements.h
r18237 r20810 25 25 /*numerics*/ 26 26 void Configure(Elements* elements,Loads* loads, Nodes* nodes, Vertices* vertices, Materials* materials,Parameters* parameters); 27 void InputDuplicate(int input_enum,int output_enum); 27 28 int MaxNumNodes(void); 29 int NumberOfElements(void); 28 30 void SetCurrentConfiguration(Elements* elements,Loads* loads, Nodes* nodes, Vertices* vertices, Materials* materials,Parameters* parameters); 29 31 void ResetHooks(); 30 int NumberOfElements(void);31 void InputDuplicate(int input_enum,int output_enum);32 32 33 33 }; -
issm/trunk-jpl/src/c/classes/Elements/Penta.cpp
r20690 r20810 3386 3386 3387 3387 #ifdef _HAVE_DAKOTA_ 3388 void Penta::InputUpdateFromMatrixDakota(IssmDouble* matrix, int nrows, int ncols, int name, int type){/*{{{*/ 3389 3390 int i,t,row; 3391 IssmDouble time; 3392 TransientInput *transientinput = NULL; 3393 IssmDouble values[6]; 3394 3395 /*Check that name is an element input*/ 3396 if (!IsInput(name)) return; 3397 3398 switch(type){ 3399 3400 case VertexEnum: 3401 /*Create transient input: */ 3402 for(t=0;t<ncols;t++){ //ncols is the number of times 3403 3404 /*create input values: */ 3405 for(i=0;i<6;i++){ 3406 row=this->vertices[i]->Sid(); 3407 values[i]=matrix[ncols*row+t]; 3408 } 3409 3410 /*time:*/ 3411 time=matrix[(nrows-1)*ncols+t]; 3412 3413 if(t==0) transientinput=new TransientInput(name); 3414 transientinput->AddTimeInput(new PentaInput(name,values,P1Enum),time); 3415 transientinput->Configure(parameters); 3416 } 3417 this->inputs->AddInput(transientinput); 3418 break; 3419 3420 default: 3421 _error_("type " << type << " (" << EnumToStringx(type) << ") not implemented yet"); 3422 } 3423 3424 } 3425 /*}}}*/ 3388 3426 void Penta::InputUpdateFromVectorDakota(IssmDouble* vector, int name, int type){/*{{{*/ 3389 3427 … … 3486 3524 } 3487 3525 /*}}}*/ 3488 void Penta::InputUpdateFromMatrixDakota(IssmDouble* matrix, int nrows, int ncols, int name, int type){/*{{{*/3489 3490 int i,t,row;3491 IssmDouble time;3492 TransientInput *transientinput = NULL;3493 IssmDouble values[6];3494 3495 /*Check that name is an element input*/3496 if (!IsInput(name)) return;3497 3498 switch(type){3499 3500 case VertexEnum:3501 /*Create transient input: */3502 for(t=0;t<ncols;t++){ //ncols is the number of times3503 3504 /*create input values: */3505 for(i=0;i<6;i++){3506 row=this->vertices[i]->Sid();3507 values[i]=matrix[ncols*row+t];3508 }3509 3510 /*time:*/3511 time=matrix[(nrows-1)*ncols+t];3512 3513 if(t==0) transientinput=new TransientInput(name);3514 transientinput->AddTimeInput(new PentaInput(name,values,P1Enum),time);3515 transientinput->Configure(parameters);3516 }3517 this->inputs->AddInput(transientinput);3518 break;3519 3520 default:3521 _error_("type " << type << " (" << EnumToStringx(type) << ") not implemented yet");3522 }3523 3524 }3525 /*}}}*/3526 3526 #endif -
issm/trunk-jpl/src/c/classes/Elements/Penta.h
r20461 r20810 41 41 /*Object virtual functions definitions: {{{*/ 42 42 Object *copy(); 43 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction); 43 44 int ObjectEnum(); 44 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction);45 45 /*}}}*/ 46 46 /*Penta routines:{{{*/ … … 48 48 void AddInput(int input_enum, IssmDouble* values, int interpolation_enum); 49 49 void AverageOntoPartition(Vector<IssmDouble>* partition_contributions,Vector<IssmDouble>* partition_areas,IssmDouble* vertex_response,IssmDouble* qmu_part); 50 void CalvingRateLevermann(); 50 51 IssmDouble CharacteristicLength(void){_error_("not implemented yet");}; 51 void CalvingRateLevermann();52 52 void ComputeBasalStress(Vector<IssmDouble>* sigma_b); 53 53 void ComputeDeviatoricStressTensor(); … … 63 63 IssmDouble FloatingArea(void); 64 64 void FSContactMigration(Vector<IssmDouble>* vertexgrounded,Vector<IssmDouble>* vertexfloating); 65 IssmDouble GetArea3D(void){_error_("not implemented yet!");}; 65 66 void GetAreaCoordinates(IssmDouble *area_coordinates,IssmDouble* xyz_zero,IssmDouble* xyz_list,int numpoints); 66 67 Element* GetBasalElement(void); … … 172 173 void ViscousHeating(IssmDouble* pphi,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input); 173 174 void ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum); 174 IssmDouble GetArea3D(void){_error_("not implemented yet!");};175 175 176 176 #ifdef _HAVE_DAKOTA_ 177 void InputUpdateFromMatrixDakota(IssmDouble* matrix, int nows, int ncols, int name, int type); 177 178 void InputUpdateFromVectorDakota(IssmDouble* vector, int name, int type); 178 void InputUpdateFromMatrixDakota(IssmDouble* matrix, int nows, int ncols, int name, int type);179 179 #endif 180 180 … … 183 183 #endif 184 184 #ifdef _HAVE_SEALEVELRISE_ 185 IssmDouble OceanArea(void){_error_("not implemented yet!");}; 186 IssmDouble OceanAverage(IssmDouble* Sg){_error_("not implemented yet!");}; 185 187 void SealevelriseEustatic(Vector<IssmDouble>* pSgi,IssmDouble* peustatic,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble oceanarea,IssmDouble eartharea){_error_("not implemented yet!");}; 186 188 void SealevelriseNonEustatic(Vector<IssmDouble>* pSgo,IssmDouble* Sg_old,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble oceanarea,IssmDouble eartharea){_error_("not implemented yet!");}; 187 IssmDouble OceanArea(void){_error_("not implemented yet!");};188 IssmDouble OceanAverage(IssmDouble* Sg){_error_("not implemented yet!");};189 189 #endif 190 190 -
issm/trunk-jpl/src/c/classes/Elements/PentaRef.cpp
r20515 r20810 190 190 IssmDouble y1,y2,y3,y4,y5,y6; 191 191 IssmDouble z1,z2,z3,z4,z5,z6; 192 IssmDouble j_const_reciprocal; // SQRT3/12.0 192 193 193 194 /*Cast gauss to GaussPenta*/ … … 224 225 z6=xyz_list[3*5+2]; 225 226 227 /* DEBUG 228 * REMOVE BEFORE SUBMITTING 229 * ---------- 230 * CHANGE SQRT3/12 TO MULTIPLY BY RECIPROCAL 231 */ 232 j_const_reciprocal=SQRT3/12; 233 226 234 J[NDOF3*0+0] = 0.25*(x1-x2-x4+x5)*zi+0.25*(-x1+x2-x4+x5); 227 J[NDOF3*1+0] = SQRT3/12.0*(x1+x2-2*x3-x4-x5+2*x6)*zi+SQRT3/12.0*(-x1-x2+2*x3-x4-x5+2*x6);228 J[NDOF3*2+0] = SQRT3/12.0*(x1+x2-2*x3-x4-x5+2*x6)*eta+1/4*(x1-x2-x4+x5)*xi +0.25*(-x1+x5-x2+x4);235 J[NDOF3*1+0] = j_const_reciprocal*(x1+x2-2*x3-x4-x5+2*x6)*zi+j_const_reciprocal*(-x1-x2+2*x3-x4-x5+2*x6); 236 J[NDOF3*2+0] = j_const_reciprocal*(x1+x2-2*x3-x4-x5+2*x6)*eta+0.25*(x1-x2-x4+x5)*xi +0.25*(-x1+x5-x2+x4); 229 237 230 238 J[NDOF3*0+1] = 0.25*(y1-y2-y4+y5)*zi+0.25*(-y1+y2-y4+y5); 231 J[NDOF3*1+1] = SQRT3/12.0*(y1+y2-2*y3-y4-y5+2*y6)*zi+SQRT3/12.0*(-y1-y2+2*y3-y4-y5+2*y6);232 J[NDOF3*2+1] = SQRT3/12.0*(y1+y2-2*y3-y4-y5+2*y6)*eta+0.25*(y1-y2-y4+y5)*xi+0.25*(y4-y1+y5-y2);239 J[NDOF3*1+1] = j_const_reciprocal*(y1+y2-2*y3-y4-y5+2*y6)*zi+j_const_reciprocal*(-y1-y2+2*y3-y4-y5+2*y6); 240 J[NDOF3*2+1] = j_const_reciprocal*(y1+y2-2*y3-y4-y5+2*y6)*eta+0.25*(y1-y2-y4+y5)*xi+0.25*(y4-y1+y5-y2); 233 241 234 242 J[NDOF3*0+2] = 0.25*(z1-z2-z4+z5)*zi+0.25*(-z1+z2-z4+z5); 235 J[NDOF3*1+2] = SQRT3/12.0*(z1+z2-2*z3-z4-z5+2*z6)*zi+SQRT3/12.0*(-z1-z2+2*z3-z4-z5+2*z6);236 J[NDOF3*2+2] = SQRT3/12.0*(z1+z2-2*z3-z4-z5+2*z6)*eta+0.25*(z1-z2-z4+z5)*xi+0.25*(-z1+z5-z2+z4);243 J[NDOF3*1+2] = j_const_reciprocal*(z1+z2-2*z3-z4-z5+2*z6)*zi+j_const_reciprocal*(-z1-z2+2*z3-z4-z5+2*z6); 244 J[NDOF3*2+2] = j_const_reciprocal*(z1+z2-2*z3-z4-z5+2*z6)*eta+0.25*(z1-z2-z4+z5)*xi+0.25*(-z1+z5-z2+z4); 237 245 } 238 246 /*}}}*/ -
issm/trunk-jpl/src/c/classes/Elements/PentaRef.h
r19254 r20810 28 28 void GetSegmentJacobianDeterminant(IssmDouble* Jdet, IssmDouble* xyz_list,Gauss* gauss); 29 29 void GetTriaJacobianDeterminant(IssmDouble* Jdet, IssmDouble* xyz_list,Gauss* gauss); 30 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){ /*do nothing */}; 30 31 int NumberofNodes(int finiteelement); 31 32 int PressureInterpolation(int fe_stokes); … … 33 34 int TensorInterpolation(int fe_stokes); 34 35 int VelocityInterpolation(int fe_stokes); 35 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){ /*do nothing */};36 36 }; 37 37 #endif -
issm/trunk-jpl/src/c/classes/Elements/Seg.h
r20461 r20810 36 36 /*}}}*/ 37 37 /*Object virtual functions definitions:{{{ */ 38 int ObjectEnum();39 38 Object *copy(); 40 39 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction); 40 int ObjectEnum(); 41 41 /*}}}*/ 42 42 /*Element virtual functions definitions: {{{*/ -
issm/trunk-jpl/src/c/classes/Elements/SegRef.h
r19254 r20810 24 24 void GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, GaussSeg* gauss,int finiteelement); 25 25 void GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,GaussSeg* gauss,int finiteelement); 26 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){ /*do nothing */}; 26 27 int NumberofNodes(int finiteelement); 27 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){ /*do nothing */};28 28 }; 29 29 #endif -
issm/trunk-jpl/src/c/classes/Elements/Tetra.h
r20461 r20810 36 36 /*}}}*/ 37 37 /*Object virtual functions definitions:{{{ */ 38 int ObjectEnum();39 38 Object *copy(); 40 39 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction); 40 int ObjectEnum(); 41 41 /*}}}*/ 42 42 /*Element virtual functions definitions: {{{*/ … … 62 62 IssmDouble FloatingArea(void){_error_("not implemented yet");}; 63 63 void FSContactMigration(Vector<IssmDouble>* vertexgrounded,Vector<IssmDouble>* vertexfloating){_error_("not implemented yet");}; 64 IssmDouble GetArea3D(void){_error_("not implemented yet!");}; 64 65 Element* GetBasalElement(void){_error_("not implemented yet");}; 65 66 int GetElementType(void); … … 169 170 void ViscousHeating(IssmDouble* pphi,IssmDouble* xyz_list,Gauss* gauss,Input* vx_input,Input* vy_input,Input* vz_input); 170 171 void ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum); 171 IssmDouble GetArea3D(void){_error_("not implemented yet!");};172 172 173 173 #ifdef _HAVE_GIA_ -
issm/trunk-jpl/src/c/classes/Elements/TetraRef.h
r19254 r20810 25 25 void GetNodalFunctionsDerivatives(IssmDouble* dbasis,IssmDouble* xyz_list, GaussTetra* gauss,int finiteelement); 26 26 void GetNodalFunctionsDerivativesReference(IssmDouble* dbasis,GaussTetra* gauss,int finiteelement); 27 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){ /*do nothing */}; 27 28 int NumberofNodes(int finiteelement); 28 29 int PressureInterpolation(int fe_stokes); 29 30 int TensorInterpolation(int fe_stokes); 30 31 int VelocityInterpolation(int fe_stokes); 31 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){ /*do nothing */};32 32 }; 33 33 #endif -
issm/trunk-jpl/src/c/classes/Elements/Tria.cpp
r20758 r20810 208 208 } 209 209 /*}}}*/ 210 void Tria::CalvingRateLevermann(){/*{{{*/211 212 IssmDouble xyz_list[NUMVERTICES][3];213 GaussTria* gauss=NULL;214 IssmDouble vx,vy,vel;215 IssmDouble strainparallel;216 IssmDouble propcoeff;217 IssmDouble strainperpendicular;218 IssmDouble calvingratex[NUMVERTICES];219 IssmDouble calvingratey[NUMVERTICES];220 IssmDouble calvingrate[NUMVERTICES];221 222 223 /* Get node coordinates and dof list: */224 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);225 226 /*Retrieve all inputs and parameters we will need*/227 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);228 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);229 Input* strainparallel_input=inputs->GetInput(StrainRateparallelEnum); _assert_(strainparallel_input);230 Input* strainperpendicular_input=inputs->GetInput(StrainRateperpendicularEnum); _assert_(strainperpendicular_input);231 Input* levermanncoeff_input=inputs->GetInput(CalvinglevermannCoeffEnum); _assert_(levermanncoeff_input);232 233 /* Start looping on the number of vertices: */234 gauss=new GaussTria();235 for (int iv=0;iv<NUMVERTICES;iv++){236 gauss->GaussVertex(iv);237 238 /* Get the value we need*/239 vx_input->GetInputValue(&vx,gauss);240 vy_input->GetInputValue(&vy,gauss);241 vel=vx*vx+vy*vy;242 strainparallel_input->GetInputValue(&strainparallel,gauss);243 strainperpendicular_input->GetInputValue(&strainperpendicular,gauss);244 levermanncoeff_input->GetInputValue(&propcoeff,gauss);245 246 /*Calving rate proportionnal to the positive product of the strain rate along the ice flow direction and the strain rate perpendicular to the ice flow */247 calvingrate[iv]=propcoeff*strainparallel*strainperpendicular;248 if(calvingrate[iv]<0){249 calvingrate[iv]=0;250 }251 calvingratex[iv]=calvingrate[iv]*vx/(sqrt(vel)+1.e-14);252 calvingratey[iv]=calvingrate[iv]*vy/(sqrt(vel)+1.e-14);253 }254 255 /*Add input*/256 this->inputs->AddInput(new TriaInput(CalvingratexEnum,&calvingratex[0],P1Enum));257 this->inputs->AddInput(new TriaInput(CalvingrateyEnum,&calvingratey[0],P1Enum));258 this->inputs->AddInput(new TriaInput(CalvingCalvingrateEnum,&calvingrate[0],P1Enum));259 260 /*Clean up and return*/261 delete gauss;262 263 }264 /*}}}*/265 210 void Tria::CalvingRateDev(){/*{{{*/ 266 211 … … 338 283 } 339 284 /*}}}*/ 340 void Tria::WriteLevelsetSegment(DataSet* segments){/*{{{*/ 341 342 if(!this->IsZeroLevelset(MaskIceLevelsetEnum)) return; 343 344 IssmDouble* xyz_list_zero = NULL; 285 void Tria::CalvingRateLevermann(){/*{{{*/ 286 345 287 IssmDouble xyz_list[NUMVERTICES][3]; 346 ::GetVerticesCoordinates(&xyz_list[0][0],this->vertices,NUMVERTICES); 347 this->ZeroLevelsetCoordinates(&xyz_list_zero,&xyz_list[0][0], MaskIceLevelsetEnum); 348 if(xyz_list_zero){ 349 IssmDouble x[2]; 350 IssmDouble y[2]; 351 x[0] = xyz_list_zero[0*3 + 0]; x[1] = xyz_list_zero[1*3 + 0]; 352 y[0] = xyz_list_zero[0*3 + 1]; y[1] = xyz_list_zero[1*3 + 1]; 353 segments->AddObject(new Contour<IssmDouble>(segments->Size()+1,2,&x[0],&y[0],false)); 354 } 355 xDelete<IssmDouble>(xyz_list_zero); 356 357 // IssmDouble ls[NUMVERTICES]; 358 // IssmDouble xyz_list[NUMVERTICES][3]; 359 // 360 // if(IsIceInElement()){ 361 // 362 // /*Retrieve all inputs and parameters*/ 363 // GetInputListOnVertices(&ls[0],levelset_enum); 364 // 365 // /*If the level set is awlays <0, there is no ice front here*/ 366 // bool iszerols= false; 367 // if(IsIceInElement()){ 368 // if(ls[0]*ls[1]<0. || ls[0]*ls[2]<0. || (ls[0]*ls[1]*ls[2]==0. && ls[0]*ls[1]+ls[0]*ls[2]+ls[1]*ls[2]<=0.)){ 369 // iszerols = true; 370 // } 371 // } 372 // 373 // if(iszerols){ 374 // /*OK we have one segment!*/ 375 // ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES); 376 // int count = 0; 377 // IssmDouble x[2]; 378 // IssmDouble y[2]; 379 // 380 // for(int i=0;i<NUMVERTICES,i++){ 381 // int index1 = i; 382 // int index1 = (i+1)%3; 383 // if(ls[index1]<=0 && ls[index2]>=0){ 384 // 385 // } 386 // 387 // } 388 // Contour* segment = new Contour<IssmDouble>(segment->Size()+1,2,x,y,false); 389 // } 390 // 391 // } 392 // 393 // _error_("STOP"); 394 } 395 /*}}}*/ 396 void Tria::ResetLevelsetFromSegmentlist(IssmDouble* segments,int numsegments){/*{{{*/ 397 398 /*Intermediaries*/ 399 IssmDouble d,xn,yn; 400 401 /*Get current levelset and vertex coordinates*/ 402 IssmDouble ls[NUMVERTICES]; 403 IssmDouble xyz_list[NUMVERTICES][3]; 288 GaussTria* gauss=NULL; 289 IssmDouble vx,vy,vel; 290 IssmDouble strainparallel; 291 IssmDouble propcoeff; 292 IssmDouble strainperpendicular; 293 IssmDouble calvingratex[NUMVERTICES]; 294 IssmDouble calvingratey[NUMVERTICES]; 295 IssmDouble calvingrate[NUMVERTICES]; 296 297 298 /* Get node coordinates and dof list: */ 404 299 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES); 405 GetInputListOnVertices(&ls[0],MaskIceLevelsetEnum); 406 InputDuplicate(MaskIceLevelsetEnum,PressureEnum); 407 408 /*Get distance from list of segments and reset ls*/ 409 for(int j=0;j<NUMVERTICES;j++){ 410 IssmDouble dmin = 1.e+50; 411 for(int i=0;i<numsegments;i++){ 412 IssmDouble x = xyz_list[j][0]; 413 IssmDouble y = xyz_list[j][1]; 414 IssmDouble l2 = (segments[4*i+2]-segments[4*i+0])*(segments[4*i+2]-segments[4*i+0]) + (segments[4*i+3]-segments[4*i+1])*(segments[4*i+3]-segments[4*i+1]); 415 416 /*Segment has a length of 0*/ 417 if(l2==0.){ 418 d = (x-segments[4*i+0])*(x-segments[4*i+0])+(y-segments[4*i+1])*(y-segments[4*i+1]); 419 if(d<dmin) dmin = d; 420 continue; 421 } 422 423 /*Consider the line extending the segment, parameterized as v + t (w - v). 424 *We find projection of point p onto the line. 425 *It falls where t = [(p-v) . (w-v)] / |w-v|^2*/ 426 IssmDouble t = ((x-segments[4*i+0])*(segments[4*i+2]-segments[4*i+0]) + (y-segments[4*i+1])*(segments[4*i+3]-segments[4*i+1]))/l2; 427 if(t < 0.0){ 428 // Beyond the 'v' end of the segment 429 d = (x-segments[4*i+0])*(x-segments[4*i+0])+(y-segments[4*i+1])*(y-segments[4*i+1]); 430 } 431 else if (t > 1.0){ 432 // Beyond the 'w' end of the segment 433 d = (x-segments[4*i+2])*(x-segments[4*i+2])+(y-segments[4*i+3])*(y-segments[4*i+3]); 434 } 435 else{ 436 // Projection falls on the segment 437 xn = segments[4*i+0] + t * (segments[4*i+2] - segments[4*i+0]); 438 yn = segments[4*i+1] + t * (segments[4*i+3] - segments[4*i+1]); 439 d = (x-xn)*(x-xn)+(y-yn)*(y-yn); 440 } 441 442 if(d<dmin) dmin = d; 443 } 444 445 /*Update signed distance*/ 446 dmin = sqrt(dmin); 447 if(dmin>10000) dmin=10000; 448 if(ls[j]>0){ 449 ls[j] = dmin; 450 } 451 else{ 452 ls[j] = - dmin; 453 } 454 } 455 456 /*Update Levelset*/ 457 this->inputs->AddInput(new TriaInput(MaskIceLevelsetEnum,&ls[0],P1Enum)); 300 301 /*Retrieve all inputs and parameters we will need*/ 302 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input); 303 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input); 304 Input* strainparallel_input=inputs->GetInput(StrainRateparallelEnum); _assert_(strainparallel_input); 305 Input* strainperpendicular_input=inputs->GetInput(StrainRateperpendicularEnum); _assert_(strainperpendicular_input); 306 Input* levermanncoeff_input=inputs->GetInput(CalvinglevermannCoeffEnum); _assert_(levermanncoeff_input); 307 308 /* Start looping on the number of vertices: */ 309 gauss=new GaussTria(); 310 for (int iv=0;iv<NUMVERTICES;iv++){ 311 gauss->GaussVertex(iv); 312 313 /* Get the value we need*/ 314 vx_input->GetInputValue(&vx,gauss); 315 vy_input->GetInputValue(&vy,gauss); 316 vel=vx*vx+vy*vy; 317 strainparallel_input->GetInputValue(&strainparallel,gauss); 318 strainperpendicular_input->GetInputValue(&strainperpendicular,gauss); 319 levermanncoeff_input->GetInputValue(&propcoeff,gauss); 320 321 /*Calving rate proportionnal to the positive product of the strain rate along the ice flow direction and the strain rate perpendicular to the ice flow */ 322 calvingrate[iv]=propcoeff*strainparallel*strainperpendicular; 323 if(calvingrate[iv]<0){ 324 calvingrate[iv]=0; 325 } 326 calvingratex[iv]=calvingrate[iv]*vx/(sqrt(vel)+1.e-14); 327 calvingratey[iv]=calvingrate[iv]*vy/(sqrt(vel)+1.e-14); 328 } 329 330 /*Add input*/ 331 this->inputs->AddInput(new TriaInput(CalvingratexEnum,&calvingratex[0],P1Enum)); 332 this->inputs->AddInput(new TriaInput(CalvingrateyEnum,&calvingratey[0],P1Enum)); 333 this->inputs->AddInput(new TriaInput(CalvingCalvingrateEnum,&calvingrate[0],P1Enum)); 334 335 /*Clean up and return*/ 336 delete gauss; 337 458 338 } 459 339 /*}}}*/ … … 2744 2624 } 2745 2625 /*}}}*/ 2626 void Tria::ResetLevelsetFromSegmentlist(IssmDouble* segments,int numsegments){/*{{{*/ 2627 2628 /*Intermediaries*/ 2629 IssmDouble d,xn,yn; 2630 2631 /*Get current levelset and vertex coordinates*/ 2632 IssmDouble ls[NUMVERTICES]; 2633 IssmDouble xyz_list[NUMVERTICES][3]; 2634 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES); 2635 GetInputListOnVertices(&ls[0],MaskIceLevelsetEnum); 2636 InputDuplicate(MaskIceLevelsetEnum,PressureEnum); 2637 2638 /*Get distance from list of segments and reset ls*/ 2639 for(int j=0;j<NUMVERTICES;j++){ 2640 IssmDouble dmin = 1.e+50; 2641 for(int i=0;i<numsegments;i++){ 2642 IssmDouble x = xyz_list[j][0]; 2643 IssmDouble y = xyz_list[j][1]; 2644 IssmDouble l2 = (segments[4*i+2]-segments[4*i+0])*(segments[4*i+2]-segments[4*i+0]) + (segments[4*i+3]-segments[4*i+1])*(segments[4*i+3]-segments[4*i+1]); 2645 2646 /*Segment has a length of 0*/ 2647 if(l2==0.){ 2648 d = (x-segments[4*i+0])*(x-segments[4*i+0])+(y-segments[4*i+1])*(y-segments[4*i+1]); 2649 if(d<dmin) dmin = d; 2650 continue; 2651 } 2652 2653 /*Consider the line extending the segment, parameterized as v + t (w - v). 2654 *We find projection of point p onto the line. 2655 *It falls where t = [(p-v) . (w-v)] / |w-v|^2*/ 2656 IssmDouble t = ((x-segments[4*i+0])*(segments[4*i+2]-segments[4*i+0]) + (y-segments[4*i+1])*(segments[4*i+3]-segments[4*i+1]))/l2; 2657 if(t < 0.0){ 2658 // Beyond the 'v' end of the segment 2659 d = (x-segments[4*i+0])*(x-segments[4*i+0])+(y-segments[4*i+1])*(y-segments[4*i+1]); 2660 } 2661 else if (t > 1.0){ 2662 // Beyond the 'w' end of the segment 2663 d = (x-segments[4*i+2])*(x-segments[4*i+2])+(y-segments[4*i+3])*(y-segments[4*i+3]); 2664 } 2665 else{ 2666 // Projection falls on the segment 2667 xn = segments[4*i+0] + t * (segments[4*i+2] - segments[4*i+0]); 2668 yn = segments[4*i+1] + t * (segments[4*i+3] - segments[4*i+1]); 2669 d = (x-xn)*(x-xn)+(y-yn)*(y-yn); 2670 } 2671 2672 if(d<dmin) dmin = d; 2673 } 2674 2675 /*Update signed distance*/ 2676 dmin = sqrt(dmin); 2677 if(dmin>10000) dmin=10000; 2678 if(ls[j]>0){ 2679 ls[j] = dmin; 2680 } 2681 else{ 2682 ls[j] = - dmin; 2683 } 2684 } 2685 2686 /*Update Levelset*/ 2687 this->inputs->AddInput(new TriaInput(MaskIceLevelsetEnum,&ls[0],P1Enum)); 2688 } 2689 /*}}}*/ 2746 2690 void Tria::SetClone(int* minranks){/*{{{*/ 2747 2691 … … 3361 3305 } 3362 3306 /*}}}*/ 3307 void Tria::WriteLevelsetSegment(DataSet* segments){/*{{{*/ 3308 3309 if(!this->IsZeroLevelset(MaskIceLevelsetEnum)) return; 3310 3311 IssmDouble* xyz_list_zero = NULL; 3312 IssmDouble xyz_list[NUMVERTICES][3]; 3313 ::GetVerticesCoordinates(&xyz_list[0][0],this->vertices,NUMVERTICES); 3314 this->ZeroLevelsetCoordinates(&xyz_list_zero,&xyz_list[0][0], MaskIceLevelsetEnum); 3315 if(xyz_list_zero){ 3316 IssmDouble x[2]; 3317 IssmDouble y[2]; 3318 x[0] = xyz_list_zero[0*3 + 0]; x[1] = xyz_list_zero[1*3 + 0]; 3319 y[0] = xyz_list_zero[0*3 + 1]; y[1] = xyz_list_zero[1*3 + 1]; 3320 segments->AddObject(new Contour<IssmDouble>(segments->Size()+1,2,&x[0],&y[0],false)); 3321 } 3322 xDelete<IssmDouble>(xyz_list_zero); 3323 3324 // IssmDouble ls[NUMVERTICES]; 3325 // IssmDouble xyz_list[NUMVERTICES][3]; 3326 // 3327 // if(IsIceInElement()){ 3328 // 3329 // /*Retrieve all inputs and parameters*/ 3330 // GetInputListOnVertices(&ls[0],levelset_enum); 3331 // 3332 // /*If the level set is awlays <0, there is no ice front here*/ 3333 // bool iszerols= false; 3334 // if(IsIceInElement()){ 3335 // if(ls[0]*ls[1]<0. || ls[0]*ls[2]<0. || (ls[0]*ls[1]*ls[2]==0. && ls[0]*ls[1]+ls[0]*ls[2]+ls[1]*ls[2]<=0.)){ 3336 // iszerols = true; 3337 // } 3338 // } 3339 // 3340 // if(iszerols){ 3341 // /*OK we have one segment!*/ 3342 // ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES); 3343 // int count = 0; 3344 // IssmDouble x[2]; 3345 // IssmDouble y[2]; 3346 // 3347 // for(int i=0;i<NUMVERTICES,i++){ 3348 // int index1 = i; 3349 // int index1 = (i+1)%3; 3350 // if(ls[index1]<=0 && ls[index2]>=0){ 3351 // 3352 // } 3353 // 3354 // } 3355 // Contour* segment = new Contour<IssmDouble>(segment->Size()+1,2,x,y,false); 3356 // } 3357 // 3358 // } 3359 // 3360 // _error_("STOP"); 3361 } 3362 /*}}}*/ 3363 3363 void Tria::ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum){/*{{{*/ 3364 3364 /* Return coordinates where levelset intersects element edges. … … 3541 3541 3542 3542 #ifdef _HAVE_SEALEVELRISE_ 3543 IssmDouble Tria::OceanArea(void){ /*{{{*/ 3544 3545 if(IsWaterInElement()) return GetArea3D(); 3546 else return 0; 3547 3548 } 3549 /*}}}*/ 3550 IssmDouble Tria::OceanAverage(IssmDouble* Sg){ /*{{{*/ 3551 3552 if(IsWaterInElement()){ 3553 3554 IssmDouble area; 3555 3556 /*Compute area of element:*/ 3557 area=GetArea3D(); 3558 3559 /*Average Sg over vertices:*/ 3560 IssmDouble Sg_avg=0; for(int i=0;i<NUMVERTICES;i++) Sg_avg+=Sg[this->vertices[i]->Sid()]/NUMVERTICES; 3561 3562 /*return: */ 3563 return area*Sg_avg; 3564 } 3565 else return 0; 3566 3567 } 3568 /*}}}*/ 3543 3569 void Tria::SealevelriseEustatic(Vector<IssmDouble>* pSgi,IssmDouble* peustatic,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble oceanarea,IssmDouble eartharea){ /*{{{*/ 3544 3570 … … 3827 3853 3828 3854 return; 3829 }3830 /*}}}*/3831 IssmDouble Tria::OceanAverage(IssmDouble* Sg){ /*{{{*/3832 3833 if(IsWaterInElement()){3834 3835 IssmDouble area;3836 3837 /*Compute area of element:*/3838 area=GetArea3D();3839 3840 /*Average Sg over vertices:*/3841 IssmDouble Sg_avg=0; for(int i=0;i<NUMVERTICES;i++) Sg_avg+=Sg[this->vertices[i]->Sid()]/NUMVERTICES;3842 3843 /*return: */3844 return area*Sg_avg;3845 }3846 else return 0;3847 3848 }3849 /*}}}*/3850 IssmDouble Tria::OceanArea(void){ /*{{{*/3851 3852 if(IsWaterInElement()) return GetArea3D();3853 else return 0;3854 3855 3855 } 3856 3856 /*}}}*/ -
issm/trunk-jpl/src/c/classes/Elements/Tria.h
r20723 r20810 38 38 /*}}}*/ 39 39 /*Object virtual functions definitions:{{{ */ 40 int ObjectEnum();41 40 Object *copy(); 42 41 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction); 42 int ObjectEnum(); 43 43 /*}}}*/ 44 44 /*Update virtual functions resolution: {{{*/ … … 52 52 /*Element virtual functions definitions: {{{*/ 53 53 void AverageOntoPartition(Vector<IssmDouble>* partition_contributions,Vector<IssmDouble>* partition_areas,IssmDouble* vertex_response,IssmDouble* qmu_part); 54 void CalvingRateDev(); 54 55 void CalvingRateLevermann(); 55 void CalvingRateDev();56 void WriteLevelsetSegment(DataSet* segments);57 void ResetLevelsetFromSegmentlist(IssmDouble* segments,int numsegments);58 56 IssmDouble CharacteristicLength(void); 59 57 void ComputeBasalStress(Vector<IssmDouble>* sigma_b); … … 119 117 void ResetFSBasalBoundaryCondition(void); 120 118 void ResetHooks(); 119 void ResetLevelsetFromSegmentlist(IssmDouble* segments,int numsegments); 121 120 void SetControlInputsFromVector(IssmDouble* vector,int control_enum,int control_index); 122 121 void SetCurrentConfiguration(Elements* elements,Loads* loads,Nodes* nodes,Materials* materials,Parameters* parameters); … … 139 138 int VertexConnectivity(int vertexindex); 140 139 void VerticalSegmentIndices(int** pindices,int* pnumseg){_error_("not implemented yet");}; 140 void WriteLevelsetSegment(DataSet* segments); 141 141 void ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum); 142 142 … … 145 145 #endif 146 146 #ifdef _HAVE_SEALEVELRISE_ 147 IssmDouble OceanArea(void); 148 IssmDouble OceanAverage(IssmDouble* Sg); 147 149 void SealevelriseEustatic(Vector<IssmDouble>* pSgi,IssmDouble* peustatic,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble oceanarea,IssmDouble eartharea); 148 150 void SealevelriseNonEustatic(Vector<IssmDouble>* pSgo,IssmDouble* Sg_old,IssmDouble* latitude,IssmDouble* longitude,IssmDouble* radius,IssmDouble oceanarea,IssmDouble eartharea); 149 IssmDouble OceanAverage(IssmDouble* Sg);150 IssmDouble OceanArea(void);151 151 #endif 152 152 /*}}}*/ … … 158 158 IssmDouble GetAreaIce(void); 159 159 void GetAreaCoordinates(IssmDouble *area_coordinates,IssmDouble* xyz_zero,IssmDouble* xyz_list,int numpoints); 160 void GetLevelsetIntersection(int** pindices, int* pnumiceverts, IssmDouble* fraction, int levelset_enum, IssmDouble level);161 160 int GetElementType(void); 162 161 void GetInputValue(IssmDouble* pvalue,Node* node,int enumtype); 162 void GetLevelsetIntersection(int** pindices, int* pnumiceverts, IssmDouble* fraction, int levelset_enum, IssmDouble level); 163 163 void GetMaterialInputValue(IssmDouble* pvalue,Node* node,int enumtype); 164 164 Node* GetNode(int node_number); -
issm/trunk-jpl/src/c/classes/Elements/TriaRef.cpp
r20515 r20810 212 212 } 213 213 214 } 215 /*}}}*/ 216 void TriaRef::GetSegmentBFlux(IssmDouble* B,Gauss* gauss, int index1,int index2,int finiteelement){/*{{{*/ 217 /*Compute B matrix. B=[phi1 phi2 -phi3 -phi4] 218 * 219 * and phi1=phi3 phi2=phi4 220 * 221 * We assume B has been allocated already, of size: 1x4 222 */ 223 224 /*Fetch number of nodes for this finite element*/ 225 int numnodes = this->NumberofNodes(finiteelement); 226 227 /*Get nodal functions*/ 228 IssmDouble* basis=xNew<IssmDouble>(numnodes); 229 GetNodalFunctions(basis,gauss,finiteelement); 230 231 /*Build B for this segment*/ 232 B[0] = +basis[index1]; 233 B[1] = +basis[index2]; 234 B[2] = -basis[index1]; 235 B[3] = -basis[index2]; 236 237 /*Clean-up*/ 238 xDelete<IssmDouble>(basis); 239 } 240 /*}}}*/ 241 void TriaRef::GetSegmentBprimeFlux(IssmDouble* Bprime,Gauss* gauss, int index1,int index2,int finiteelement){/*{{{*/ 242 /*Compute Bprime matrix. Bprime=[phi1 phi2 phi3 phi4] 243 * 244 * and phi1=phi3 phi2=phi4 245 * 246 * We assume Bprime has been allocated already, of size: 1x4 247 */ 248 249 /*Fetch number of nodes for this finite element*/ 250 int numnodes = this->NumberofNodes(finiteelement); 251 252 /*Get nodal functions*/ 253 IssmDouble* basis=xNew<IssmDouble>(numnodes); 254 GetNodalFunctions(basis,gauss,finiteelement); 255 256 /*Build B'*/ 257 Bprime[0] = basis[index1]; 258 Bprime[1] = basis[index2]; 259 Bprime[2] = basis[index1]; 260 Bprime[3] = basis[index2]; 261 262 /*Clean-up*/ 263 xDelete<IssmDouble>(basis); 264 } 265 /*}}}*/ 266 void TriaRef::GetSegmentJacobianDeterminant(IssmDouble* Jdet, IssmDouble* xyz_list,Gauss* gauss){/*{{{*/ 267 /*The Jacobian determinant is constant over the element, discard the gaussian points. 268 * J is assumed to have been allocated*/ 269 270 IssmDouble x1 = xyz_list[3*0+0]; 271 IssmDouble y1 = xyz_list[3*0+1]; 272 IssmDouble x2 = xyz_list[3*1+0]; 273 IssmDouble y2 = xyz_list[3*1+1]; 274 275 *Jdet = .5*sqrt(pow(x2-x1,2) + pow(y2-y1,2)); 276 if(*Jdet<0) _error_("negative jacobian determinant!"); 277 278 } 279 /*}}}*/ 280 void TriaRef::GetSegmentNodalFunctions(IssmDouble* basis,Gauss* gauss,int index1,int index2,int finiteelement){/*{{{*/ 281 /*This routine returns the values of the nodal functions at the gaussian point.*/ 282 283 _assert_(index1>=0 && index1<3); 284 _assert_(index2>=0 && index2<3); 285 286 /*Fetch number of nodes for this finite element*/ 287 int numnodes = this->NumberofNodes(finiteelement); 288 289 /*Get nodal functions*/ 290 IssmDouble* triabasis=xNew<IssmDouble>(numnodes); 291 GetNodalFunctions(triabasis,gauss,finiteelement); 292 293 switch(finiteelement){ 294 case P1Enum: case P1DGEnum: 295 basis[0]=triabasis[index1]; 296 basis[1]=triabasis[index2]; 297 xDelete<IssmDouble>(triabasis); 298 return; 299 case P1bubbleEnum: case P1bubblecondensedEnum: 300 basis[0]=triabasis[index1]; 301 basis[1]=triabasis[index2]; 302 xDelete<IssmDouble>(triabasis); 303 return; 304 case P2Enum: 305 _assert_(index2<index1); 306 basis[0]=triabasis[index1]; 307 basis[1]=triabasis[index2]; 308 basis[2]=triabasis[3+index2-1]; 309 xDelete<IssmDouble>(triabasis); 310 return; 311 default: 312 _error_("Element type "<<EnumToStringx(finiteelement)<<" not supported yet"); 313 } 314 315 /*Clean up*/ 316 xDelete<IssmDouble>(triabasis); 214 317 } 215 318 /*}}}*/ … … 302 405 } 303 406 304 }305 /*}}}*/306 void TriaRef::GetSegmentBFlux(IssmDouble* B,Gauss* gauss, int index1,int index2,int finiteelement){/*{{{*/307 /*Compute B matrix. B=[phi1 phi2 -phi3 -phi4]308 *309 * and phi1=phi3 phi2=phi4310 *311 * We assume B has been allocated already, of size: 1x4312 */313 314 /*Fetch number of nodes for this finite element*/315 int numnodes = this->NumberofNodes(finiteelement);316 317 /*Get nodal functions*/318 IssmDouble* basis=xNew<IssmDouble>(numnodes);319 GetNodalFunctions(basis,gauss,finiteelement);320 321 /*Build B for this segment*/322 B[0] = +basis[index1];323 B[1] = +basis[index2];324 B[2] = -basis[index1];325 B[3] = -basis[index2];326 327 /*Clean-up*/328 xDelete<IssmDouble>(basis);329 }330 /*}}}*/331 void TriaRef::GetSegmentBprimeFlux(IssmDouble* Bprime,Gauss* gauss, int index1,int index2,int finiteelement){/*{{{*/332 /*Compute Bprime matrix. Bprime=[phi1 phi2 phi3 phi4]333 *334 * and phi1=phi3 phi2=phi4335 *336 * We assume Bprime has been allocated already, of size: 1x4337 */338 339 /*Fetch number of nodes for this finite element*/340 int numnodes = this->NumberofNodes(finiteelement);341 342 /*Get nodal functions*/343 IssmDouble* basis=xNew<IssmDouble>(numnodes);344 GetNodalFunctions(basis,gauss,finiteelement);345 346 /*Build B'*/347 Bprime[0] = basis[index1];348 Bprime[1] = basis[index2];349 Bprime[2] = basis[index1];350 Bprime[3] = basis[index2];351 352 /*Clean-up*/353 xDelete<IssmDouble>(basis);354 }355 /*}}}*/356 void TriaRef::GetSegmentJacobianDeterminant(IssmDouble* Jdet, IssmDouble* xyz_list,Gauss* gauss){/*{{{*/357 /*The Jacobian determinant is constant over the element, discard the gaussian points.358 * J is assumed to have been allocated*/359 360 IssmDouble x1 = xyz_list[3*0+0];361 IssmDouble y1 = xyz_list[3*0+1];362 IssmDouble x2 = xyz_list[3*1+0];363 IssmDouble y2 = xyz_list[3*1+1];364 365 *Jdet = .5*sqrt(pow(x2-x1,2) + pow(y2-y1,2));366 if(*Jdet<0) _error_("negative jacobian determinant!");367 368 }369 /*}}}*/370 void TriaRef::GetSegmentNodalFunctions(IssmDouble* basis,Gauss* gauss,int index1,int index2,int finiteelement){/*{{{*/371 /*This routine returns the values of the nodal functions at the gaussian point.*/372 373 _assert_(index1>=0 && index1<3);374 _assert_(index2>=0 && index2<3);375 376 /*Fetch number of nodes for this finite element*/377 int numnodes = this->NumberofNodes(finiteelement);378 379 /*Get nodal functions*/380 IssmDouble* triabasis=xNew<IssmDouble>(numnodes);381 GetNodalFunctions(triabasis,gauss,finiteelement);382 383 switch(finiteelement){384 case P1Enum: case P1DGEnum:385 basis[0]=triabasis[index1];386 basis[1]=triabasis[index2];387 xDelete<IssmDouble>(triabasis);388 return;389 case P1bubbleEnum: case P1bubblecondensedEnum:390 basis[0]=triabasis[index1];391 basis[1]=triabasis[index2];392 xDelete<IssmDouble>(triabasis);393 return;394 case P2Enum:395 _assert_(index2<index1);396 basis[0]=triabasis[index1];397 basis[1]=triabasis[index2];398 basis[2]=triabasis[3+index2-1];399 xDelete<IssmDouble>(triabasis);400 return;401 default:402 _error_("Element type "<<EnumToStringx(finiteelement)<<" not supported yet");403 }404 405 /*Clean up*/406 xDelete<IssmDouble>(triabasis);407 407 } 408 408 /*}}}*/ -
issm/trunk-jpl/src/c/classes/Elements/TriaRef.h
r19216 r20810 28 28 void GetSegmentJacobianDeterminant(IssmDouble* Jdet, IssmDouble* xyz_list,Gauss* gauss); 29 29 void GetSegmentNodalFunctions(IssmDouble* basis,Gauss* gauss, int index1,int index2,int finiteelement); 30 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){ /*do nothing */}; 30 31 void NodeOnEdgeIndices(int* pnumindices,int** pindices,int index,int finiteelement); 31 32 int NumberofNodes(int finiteelement); … … 33 34 int TensorInterpolation(int fe_stokes); 34 35 int VelocityInterpolation(int fe_stokes); 35 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){ /*do nothing */};36 36 37 37 }; -
issm/trunk-jpl/src/c/classes/ExternalResults/ExternalResult.h
r18886 r20810 24 24 25 25 virtual ~ExternalResult(){}; 26 virtual void WriteData(FILE* fid,bool io_gather)=0;26 virtual int GetResultEnum(void)=0; 27 27 virtual char* GetResultName(void)=0; 28 28 virtual int GetStep(void)=0; 29 29 virtual double GetValue(void)=0; 30 virtual int GetResultEnum(void)=0;30 virtual void WriteData(FILE* fid,bool io_gather)=0; 31 31 }; 32 32 #endif -
issm/trunk-jpl/src/c/classes/ExternalResults/GenericExternalResult.h
r19813 r20810 132 132 133 133 /*Object virtual functions definitions:*/ 134 Object* copy(void) { /*{{{*/ 135 return new GenericExternalResult<ResultType>(this->id,this->result_name,this->value,this->step,this->time); 136 } /*}}}*/ 134 137 void Echo(void){ /*{{{*/ 135 138 this->DeepEcho(); … … 146 149 _error_("template ObjectEnum not implemented for this ResultType\n"); 147 150 } /*}}}*/ 148 Object* copy(void) { /*{{{*/149 return new GenericExternalResult<ResultType>(this->id,this->result_name,this->value,this->step,this->time);150 } /*}}}*/151 151 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){/*{{{*/ 152 152 _error_("not implemented yet!"); -
issm/trunk-jpl/src/c/classes/ExternalResults/Results.cpp
r18886 r20810 31 31 32 32 /*Object management*/ 33 void Results::Write(Parameters* parameters){/*{{{*/34 35 FILE *fid = NULL;36 bool io_gather;37 38 /*Recover file descriptor: */39 parameters->FindParam(&fid,OutputFilePointerEnum);40 parameters->FindParam(&io_gather,SettingsIoGatherEnum);41 42 for(int i=0;i<this->Size();i++){43 ExternalResult* result=xDynamicCast<ExternalResult*>(this->GetObjectByOffset(i));44 result->WriteData(fid,io_gather);45 }46 47 }48 /*}}}*/49 33 int Results::AddResult(ExternalResult* in_result){/*{{{*/ 50 34 … … 106 90 } 107 91 /*}}}*/ 92 void Results::Write(Parameters* parameters){/*{{{*/ 93 94 FILE *fid = NULL; 95 bool io_gather; 96 97 /*Recover file descriptor: */ 98 parameters->FindParam(&fid,OutputFilePointerEnum); 99 parameters->FindParam(&io_gather,SettingsIoGatherEnum); 100 101 for(int i=0;i<this->Size();i++){ 102 ExternalResult* result=xDynamicCast<ExternalResult*>(this->GetObjectByOffset(i)); 103 result->WriteData(fid,io_gather); 104 } 105 106 } 107 /*}}}*/ -
issm/trunk-jpl/src/c/classes/ExternalResults/Results.h
r18886 r20810 22 22 /*Mehthos*/ 23 23 int AddResult(ExternalResult* result); 24 int DeleteResult(int result_enum,int result_step); 24 25 ExternalResult* FindResult(int result_enum); 25 int DeleteResult(int result_enum,int result_step);26 26 void Write(Parameters* parameters); 27 27 }; -
issm/trunk-jpl/src/c/classes/FemModel.cpp
r20723 r20810 143 143 144 144 /*Object management*/ 145 void FemModel::Echo(void){/*{{{*/ 146 147 _printf_("FemModel echo: \n"); 148 _printf_(" number of fem models: " << nummodels << "\n"); 149 _printf_(" analysis_type_list: \n"); 150 for(int i=0;i<nummodels;i++)_printf_(" " << i << ": " << EnumToStringx(analysis_type_list[i]) << "\n"); 151 _printf_(" current analysis_type: \n"); 152 _printf_(" " << analysis_counter << ": " << EnumToStringx(analysis_type_list[analysis_counter]) << "\n"); 153 154 } 155 /*}}}*/ 156 void FemModel::InitFromFiles(char* rootpath, char* inputfilename, char* outputfilename, char* toolkitsfilename, char* lockfilename, char* restartfilename, const int in_solution_type,bool trace,IssmPDouble* X){/*{{{*/ 157 158 /*intermediary*/ 159 int i; 160 int analysis_type; 161 FILE *IOMODEL = NULL; 162 FILE *toolkitsoptionsfid = NULL; 163 FILE *output_fid = NULL; 164 int my_rank; 165 166 /*recover my_rank:*/ 167 my_rank=IssmComm::GetRank(); 168 169 /*Initialize internal data: */ 170 this->solution_type = in_solution_type; 171 this->analysis_counter = nummodels-1; //point to last analysis_type carried out. 172 this->results = new Results(); //not initialized by CreateDataSets 173 /*Open input file on cpu 0 and create IoModel */ 174 if(my_rank==0) IOMODEL = pfopen0(inputfilename ,"rb"); 175 IoModel* iomodel = new IoModel(IOMODEL,in_solution_type,trace,X); 176 177 /*Figure out what analyses are activated for this solution*/ 178 SolutionAnalysesList(&this->analysis_type_list,&this->nummodels,iomodel,this->solution_type); 179 180 /*Open toolkits file: */ 181 toolkitsoptionsfid=pfopen(toolkitsfilename,"r"); 182 183 /*create datasets for all analyses*/ 184 ModelProcessorx(&this->elements,&this->nodes,&this->vertices,&this->materials,&this->constraints,&this->loads,&this->parameters,iomodel,toolkitsoptionsfid,rootpath,this->solution_type,this->nummodels,this->analysis_type_list); 185 186 187 /*do the post-processing of the datasets to get an FemModel that can actually run analyses: */ 188 for(i=0;i<nummodels;i++){ 189 190 if(VerboseMProcessor()) _printf0_(" Processing finite element model of analysis " << EnumToStringx(analysis_type_list[i]) << ":\n"); 191 analysis_type=analysis_type_list[i]; 192 this->SetCurrentConfiguration(analysis_type); 193 194 if(VerboseMProcessor()) _printf0_(" configuring element and loads\n"); 195 ConfigureObjectsx(elements, loads, nodes, vertices, materials,parameters); 196 197 if(i==0){ 198 if(VerboseMProcessor()) _printf0_(" creating vertex PIDs\n"); 199 VerticesDofx(vertices,parameters); 200 201 if(VerboseMProcessor()) _printf0_(" detecting active vertices\n"); 202 GetMaskOfIceVerticesLSMx(this); 203 } 204 205 if(VerboseMProcessor()) _printf0_(" resolving node constraints\n"); 206 SpcNodesx(nodes,constraints,parameters,analysis_type); 207 208 if(VerboseMProcessor()) _printf0_(" creating nodal degrees of freedom\n"); 209 NodesDofx(nodes,parameters,analysis_type); 210 } 211 212 /*Close input file and toolkits file descriptors: */ 213 if(my_rank==0) pfclose(IOMODEL,inputfilename); 214 pfclose(toolkitsoptionsfid,toolkitsfilename); 215 216 /*Open output file once for all and add output file descriptor to parameters*/ 217 output_fid=pfopen(outputfilename,"wb"); 218 this->parameters->SetParam(output_fid,OutputFilePointerEnum); 145 void FemModel::CheckPoint(void){/*{{{*/ 146 147 FILE* restartfid=NULL; 148 char* restartfilename = NULL; 149 int femmodel_size; 150 char* femmodel_buffer=NULL; 151 char* femmodel_buffer_ini=NULL; 152 153 /*First, recover the name of the restart file: */ 154 parameters->FindParam(&restartfilename,RestartFileNameEnum); 219 155 220 /*Now save all of these file names into parameters, you never know when you might need them: */ 221 this->parameters->AddObject(new StringParam(ToolkitsFileNameEnum,toolkitsfilename)); 222 this->parameters->AddObject(new StringParam(RootPathEnum,rootpath)); 223 this->parameters->AddObject(new StringParam(InputFileNameEnum,inputfilename)); 224 this->parameters->AddObject(new StringParam(OutputFileNameEnum,outputfilename)); 225 this->parameters->AddObject(new StringParam(LockFileNameEnum,lockfilename)); 226 this->parameters->AddObject(new StringParam(RestartFileNameEnum,restartfilename)); 227 228 /*Clean up*/ 229 delete iomodel; 230 }/*}}}*/ 156 /*Open file for writing: */ 157 restartfid=pfopen(restartfilename,"wb"); 158 159 /*Initialize: */ 160 femmodel_size=0; 161 162 /*Create buffer to hold marshalled femmodel: */ 163 this->Marshall(NULL,&femmodel_size,MARSHALLING_SIZE); 164 femmodel_buffer=xNew<char>(femmodel_size); 165 /*Keep track of initial position of femmodel_buffer: */ 166 femmodel_buffer_ini=femmodel_buffer; 167 168 /*Marshall:*/ 169 this->Marshall(&femmodel_buffer,NULL,MARSHALLING_FORWARD); 170 171 /*Reset position of buffer: */ 172 femmodel_buffer=femmodel_buffer_ini; 173 174 /*write buffer: */ 175 fwrite(femmodel_buffer,femmodel_size,sizeof(char),restartfid); 176 177 /*Done, close file :*/ 178 pfclose(restartfid,restartfilename); 179 180 /*Free ressources: */ 181 xDelete<char>(femmodel_buffer); 182 xDelete<char>(restartfilename); 183 184 } 185 /*}}}*/ 231 186 void FemModel::CleanUp(void){/*{{{*/ 232 187 … … 275 230 } 276 231 /*}}}*/ 232 FemModel* FemModel::copy(void){/*{{{*/ 233 234 FemModel* output=NULL; 235 int i; 236 int analysis_type; 237 238 output=new FemModel(*this); //Use default copy constructor. 239 240 output->nummodels = this->nummodels; 241 output->solution_type = this->solution_type; 242 output->analysis_counter = this->analysis_counter; 243 244 /*Now, deep copy arrays: */ 245 output->analysis_type_list=xNew<int>(nummodels); 246 xMemCpy<int>(output->analysis_type_list,this->analysis_type_list,this->nummodels); 247 248 output->profiler=static_cast<Profiler*>(this->profiler->copy()); 249 250 output->loads=static_cast<Loads*>(this->loads->Copy()); 251 output->materials=static_cast<Materials*>(this->materials->Copy()); 252 output->parameters=static_cast<Parameters*>(this->parameters->Copy()); 253 output->constraints=static_cast<Constraints*>(this->constraints->Copy()); 254 output->results=static_cast<Results*>(this->results->Copy()); 255 256 output->nodes=static_cast<Nodes*>(this->nodes->Copy()); 257 output->vertices=static_cast<Vertices*>(this->vertices->Copy()); 258 output->elements=static_cast<Elements*>(this->elements->Copy()); 259 260 /*reset hooks for elements, loads and nodes: */ 261 output->elements->ResetHooks(); 262 output->loads->ResetHooks(); 263 output->materials->ResetHooks(); 264 265 /*do the post-processing of the datasets to get an FemModel that can actually run analyses: */ 266 for(i=0;i<nummodels;i++){ 267 analysis_type=output->analysis_type_list[i]; 268 output->SetCurrentConfiguration(analysis_type); 269 if(i==0) VerticesDofx(output->vertices,output->parameters); //only call once, we only have one set of vertices 270 SpcNodesx(output->nodes,output->constraints,output->parameters,analysis_type); 271 NodesDofx(output->nodes,output->parameters,analysis_type); 272 ConfigureObjectsx(output->elements,output->loads,output->nodes,output->vertices,output->materials,output->parameters); 273 } 274 275 /*Reset current configuration: */ 276 analysis_type=output->analysis_type_list[analysis_counter]; 277 output->SetCurrentConfiguration(analysis_type); 278 279 return output; 280 } 281 /*}}}*/ 282 void FemModel::Echo(void){/*{{{*/ 283 284 _printf_("FemModel echo: \n"); 285 _printf_(" number of fem models: " << nummodels << "\n"); 286 _printf_(" analysis_type_list: \n"); 287 for(int i=0;i<nummodels;i++)_printf_(" " << i << ": " << EnumToStringx(analysis_type_list[i]) << "\n"); 288 _printf_(" current analysis_type: \n"); 289 _printf_(" " << analysis_counter << ": " << EnumToStringx(analysis_type_list[analysis_counter]) << "\n"); 290 291 } 292 /*}}}*/ 293 void FemModel::InitFromFiles(char* rootpath, char* inputfilename, char* outputfilename, char* toolkitsfilename, char* lockfilename, char* restartfilename, const int in_solution_type,bool trace,IssmPDouble* X){/*{{{*/ 294 295 /*intermediary*/ 296 int i; 297 int analysis_type; 298 FILE *IOMODEL = NULL; 299 FILE *toolkitsoptionsfid = NULL; 300 FILE *output_fid = NULL; 301 int my_rank; 302 303 /*recover my_rank:*/ 304 my_rank=IssmComm::GetRank(); 305 306 /*Initialize internal data: */ 307 this->solution_type = in_solution_type; 308 this->analysis_counter = nummodels-1; //point to last analysis_type carried out. 309 this->results = new Results(); //not initialized by CreateDataSets 310 /*Open input file on cpu 0 and create IoModel */ 311 if(my_rank==0) IOMODEL = pfopen0(inputfilename ,"rb"); 312 IoModel* iomodel = new IoModel(IOMODEL,in_solution_type,trace,X); 313 314 /*Figure out what analyses are activated for this solution*/ 315 SolutionAnalysesList(&this->analysis_type_list,&this->nummodels,iomodel,this->solution_type); 316 317 /*Open toolkits file: */ 318 toolkitsoptionsfid=pfopen(toolkitsfilename,"r"); 319 320 /*create datasets for all analyses*/ 321 ModelProcessorx(&this->elements,&this->nodes,&this->vertices,&this->materials,&this->constraints,&this->loads,&this->parameters,iomodel,toolkitsoptionsfid,rootpath,this->solution_type,this->nummodels,this->analysis_type_list); 322 323 324 /*do the post-processing of the datasets to get an FemModel that can actually run analyses: */ 325 for(i=0;i<nummodels;i++){ 326 327 if(VerboseMProcessor()) _printf0_(" Processing finite element model of analysis " << EnumToStringx(analysis_type_list[i]) << ":\n"); 328 analysis_type=analysis_type_list[i]; 329 this->SetCurrentConfiguration(analysis_type); 330 331 if(VerboseMProcessor()) _printf0_(" configuring element and loads\n"); 332 ConfigureObjectsx(elements, loads, nodes, vertices, materials,parameters); 333 334 if(i==0){ 335 if(VerboseMProcessor()) _printf0_(" creating vertex PIDs\n"); 336 VerticesDofx(vertices,parameters); 337 338 if(VerboseMProcessor()) _printf0_(" detecting active vertices\n"); 339 GetMaskOfIceVerticesLSMx(this); 340 } 341 342 if(VerboseMProcessor()) _printf0_(" resolving node constraints\n"); 343 SpcNodesx(nodes,constraints,parameters,analysis_type); 344 345 if(VerboseMProcessor()) _printf0_(" creating nodal degrees of freedom\n"); 346 NodesDofx(nodes,parameters,analysis_type); 347 } 348 349 /*Close input file and toolkits file descriptors: */ 350 if(my_rank==0) pfclose(IOMODEL,inputfilename); 351 pfclose(toolkitsoptionsfid,toolkitsfilename); 352 353 /*Open output file once for all and add output file descriptor to parameters*/ 354 output_fid=pfopen(outputfilename,"wb"); 355 this->parameters->SetParam(output_fid,OutputFilePointerEnum); 356 357 /*Now save all of these file names into parameters, you never know when you might need them: */ 358 this->parameters->AddObject(new StringParam(ToolkitsFileNameEnum,toolkitsfilename)); 359 this->parameters->AddObject(new StringParam(RootPathEnum,rootpath)); 360 this->parameters->AddObject(new StringParam(InputFileNameEnum,inputfilename)); 361 this->parameters->AddObject(new StringParam(OutputFileNameEnum,outputfilename)); 362 this->parameters->AddObject(new StringParam(LockFileNameEnum,lockfilename)); 363 this->parameters->AddObject(new StringParam(RestartFileNameEnum,restartfilename)); 364 365 /*Clean up*/ 366 delete iomodel; 367 }/*}}}*/ 368 void FemModel::Marshall(char** pmarshalled_data, int* pmarshalled_data_size, int marshall_direction){ /*{{{*/ 369 370 int i; 371 int analysis_type; 372 373 if(marshall_direction==MARSHALLING_BACKWARD){ 374 delete this->profiler; 375 delete this->loads; 376 delete this->materials; 377 delete this->parameters; 378 delete this->constraints; 379 delete this->results; 380 delete this->nodes; 381 delete this->vertices; 382 delete this->elements; 383 xDelete<int>(this->analysis_type_list); 384 385 this->profiler = new Profiler(); 386 this->loads = new Loads(); 387 this->materials = new Materials(); 388 this->parameters = new Parameters(); 389 this->constraints = new Constraints(); 390 this->results = new Results(); 391 this->nodes = new Nodes(); 392 this->vertices = new Vertices(); 393 this->elements = new Elements(); 394 } 395 396 MARSHALLING_ENUM(FemModelEnum); 397 398 MARSHALLING(solution_type); 399 MARSHALLING(analysis_counter); 400 MARSHALLING(nummodels); 401 MARSHALLING_DYNAMIC(analysis_type_list,int,nummodels); 402 403 this->profiler->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction); 404 this->loads->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction); 405 this->materials->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction); 406 this->parameters->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction); 407 this->constraints->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction); 408 this->results->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction); 409 this->nodes->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction); 410 this->vertices->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction); 411 this->elements->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction); 412 413 if(marshall_direction==MARSHALLING_BACKWARD){ 414 //reset hooks for elements, loads and nodes: 415 this->elements->ResetHooks(); 416 this->loads->ResetHooks(); 417 this->materials->ResetHooks(); 418 419 //do the post-processing of the datasets to get an FemModel that can actually run analyses: 420 for(i=0;i<nummodels;i++){ 421 analysis_type=this->analysis_type_list[i]; 422 SetCurrentConfiguration(analysis_type); 423 if(i==0) VerticesDofx(this->vertices,this->parameters); //only call once, we only have one set of vertices 424 SpcNodesx(this->nodes,this->constraints,this->parameters,analysis_type); 425 NodesDofx(this->nodes,this->parameters,analysis_type); 426 ConfigureObjectsx(this->elements,this->loads,this->nodes,this->vertices,this->materials,this->parameters); 427 } 428 429 //Reset current configuration: 430 analysis_type=this->analysis_type_list[analysis_counter]; 431 SetCurrentConfiguration(analysis_type); 432 } 433 434 } 435 /*}}}*/ 436 void FemModel::Restart(){ /*{{{*/ 437 438 FILE* restartfid=NULL; 439 FILE* output_fid=NULL; 440 char* restartfilename = NULL; 441 int femmodel_size=0; 442 int fread_return=0; 443 char* femmodel_buffer=NULL; 444 char* femmodel_buffer_ini=NULL; 445 446 /*First, recover the name of the restart file: */ 447 parameters->FindParam(&restartfilename,RestartFileNameEnum); 448 449 /*Now, figure out whether this file actually exists!: */ 450 restartfid=pfopen(restartfilename,"r",false); 451 452 if(restartfid==NULL){ 453 xDelete<char>(restartfilename); 454 return; //could not find the file, so no restart possible. 455 } 456 457 /*Figure out size of buffer to be read: */ 458 fseek(restartfid, 0L, SEEK_END); 459 femmodel_size = ftell(restartfid); 460 fseek(restartfid, 0L, SEEK_SET); 461 462 /*Allocate buffer: */ 463 femmodel_buffer=xNew<char>(femmodel_size); 464 465 /*Read buffer from file: */ 466 fread_return=fread(femmodel_buffer,femmodel_size,sizeof(char),restartfid); if(fread_return!=1)_error_("error reading the buffer from marshalled file!"); 467 femmodel_buffer_ini=femmodel_buffer; //keep track of the initial position, so as to free later. 468 469 this->parameters->FindParam(&output_fid,OutputFilePointerEnum); 470 471 /*Create new FemModel by demarshalling the buffer: */ 472 this->Marshall(&femmodel_buffer,NULL,MARSHALLING_BACKWARD); 473 474 this->parameters->SetParam(output_fid,OutputFilePointerEnum); 475 476 /*Reset position of buffer: */ 477 femmodel_buffer=femmodel_buffer_ini; 478 479 /*Done, close file :*/ 480 pfclose(restartfid,restartfilename); 481 482 /*Free ressources: */ 483 xDelete<char>(restartfilename); 484 xDelete<char>(femmodel_buffer); 485 486 } 487 /*}}}*/ 277 488 void FemModel::SetCurrentConfiguration(int configuration_type,int analysis_type){/*{{{*/ 278 489 … … 311 522 void FemModel::SetCurrentConfiguration(int configuration_type){/*{{{*/ 312 523 this->SetCurrentConfiguration(configuration_type,configuration_type); 313 }314 /*}}}*/315 void FemModel::Solve(void){/*{{{*/316 317 /*profiling: */318 bool profiling = false;319 IssmDouble solution_time;320 IssmDouble solution_flops;321 IssmDouble solution_memory;322 323 /*solution: */324 int solution_type;325 void (*solutioncore)(FemModel*)=NULL; //core solution function pointer326 327 _printf0_("call computational core:\n");328 329 /*Retrieve solution_type from parameters: */330 parameters->FindParam(&solution_type,SolutionTypeEnum);331 332 /*Figure out which solution core we are going to run with the current solution type: */333 WrapperCorePointerFromSolutionEnum(&solutioncore,this->parameters,solution_type);334 335 /*run solution core: */336 profiler->Tag(STARTCORE);337 solutioncore(this);338 profiler->Tag(FINISHCORE);339 340 /*run AD core if needed: */341 profiler->Tag(STARTADCORE);342 ad_core(this);343 profiler->Tag(FINISHADCORE);344 345 /*some profiling results for the core: */346 parameters->FindParam(&profiling,DebugProfilingEnum);347 if(profiling){348 349 solution_time=profiler->DeltaTime(STARTCORE,FINISHCORE);350 solution_flops=profiler->DeltaFlops(STARTCORE,FINISHCORE);351 solution_memory=profiler->Memory(FINISHCORE);352 353 _printf0_("Core solution elapsed time : " << solution_time << " Seconds\n");354 _printf0_("Core solution number of flops : " << solution_flops << " Flops\n");355 _printf0_("Core solution memory used : " << solution_memory << " Bytes\n");356 357 /*Add to results: */358 results->AddObject(new GenericExternalResult<IssmDouble>(results->Size()+1, ProfilingSolutionTimeEnum, solution_time, 0, 0));359 results->AddObject(new GenericExternalResult<IssmDouble>(results->Size()+1, ProfilingCurrentMemEnum, solution_memory, 0, 0));360 results->AddObject(new GenericExternalResult<IssmDouble>(results->Size()+1, ProfilingCurrentFlopsEnum, solution_flops, 0, 0));361 362 #ifdef _HAVE_ADOLC_363 solution_time=profiler->DeltaTime(STARTADCORE,FINISHADCORE);364 solution_flops=profiler->DeltaFlops(STARTADCORE,FINISHADCORE);365 solution_memory=profiler->Memory(FINISHADCORE);366 367 _printf0_("AD Solution elapsed time : " << solution_time << " Seconds\n");368 _printf0_("AD Solution number of flops : " << solution_flops << " Flops\n");369 _printf0_("AD Solution memory used : " << solution_memory << " Bytes\n");370 371 #endif372 373 }374 }375 /*}}}*/376 FemModel* FemModel::copy(void){/*{{{*/377 378 FemModel* output=NULL;379 int i;380 int analysis_type;381 382 output=new FemModel(*this); //Use default copy constructor.383 384 output->nummodels = this->nummodels;385 output->solution_type = this->solution_type;386 output->analysis_counter = this->analysis_counter;387 388 /*Now, deep copy arrays: */389 output->analysis_type_list=xNew<int>(nummodels);390 xMemCpy<int>(output->analysis_type_list,this->analysis_type_list,this->nummodels);391 392 output->profiler=static_cast<Profiler*>(this->profiler->copy());393 394 output->loads=static_cast<Loads*>(this->loads->Copy());395 output->materials=static_cast<Materials*>(this->materials->Copy());396 output->parameters=static_cast<Parameters*>(this->parameters->Copy());397 output->constraints=static_cast<Constraints*>(this->constraints->Copy());398 output->results=static_cast<Results*>(this->results->Copy());399 400 output->nodes=static_cast<Nodes*>(this->nodes->Copy());401 output->vertices=static_cast<Vertices*>(this->vertices->Copy());402 output->elements=static_cast<Elements*>(this->elements->Copy());403 404 /*reset hooks for elements, loads and nodes: */405 output->elements->ResetHooks();406 output->loads->ResetHooks();407 output->materials->ResetHooks();408 409 /*do the post-processing of the datasets to get an FemModel that can actually run analyses: */410 for(i=0;i<nummodels;i++){411 analysis_type=output->analysis_type_list[i];412 output->SetCurrentConfiguration(analysis_type);413 if(i==0) VerticesDofx(output->vertices,output->parameters); //only call once, we only have one set of vertices414 SpcNodesx(output->nodes,output->constraints,output->parameters,analysis_type);415 NodesDofx(output->nodes,output->parameters,analysis_type);416 ConfigureObjectsx(output->elements,output->loads,output->nodes,output->vertices,output->materials,output->parameters);417 }418 419 /*Reset current configuration: */420 analysis_type=output->analysis_type_list[analysis_counter];421 output->SetCurrentConfiguration(analysis_type);422 423 return output;424 524 } 425 525 /*}}}*/ … … 634 734 else xDelete<int>(analyses); 635 735 }/*}}}*/ 636 void FemModel::CheckPoint(void){/*{{{*/ 637 638 FILE* restartfid=NULL; 639 char* restartfilename = NULL; 640 int femmodel_size; 641 char* femmodel_buffer=NULL; 642 char* femmodel_buffer_ini=NULL; 643 644 /*First, recover the name of the restart file: */ 645 parameters->FindParam(&restartfilename,RestartFileNameEnum); 646 647 /*Open file for writing: */ 648 restartfid=pfopen(restartfilename,"wb"); 649 650 /*Initialize: */ 651 femmodel_size=0; 652 653 /*Create buffer to hold marshalled femmodel: */ 654 this->Marshall(NULL,&femmodel_size,MARSHALLING_SIZE); 655 femmodel_buffer=xNew<char>(femmodel_size); 656 /*Keep track of initial position of femmodel_buffer: */ 657 femmodel_buffer_ini=femmodel_buffer; 658 659 /*Marshall:*/ 660 this->Marshall(&femmodel_buffer,NULL,MARSHALLING_FORWARD); 661 662 /*Reset position of buffer: */ 663 femmodel_buffer=femmodel_buffer_ini; 664 665 /*write buffer: */ 666 fwrite(femmodel_buffer,femmodel_size,sizeof(char),restartfid); 667 668 /*Done, close file :*/ 669 pfclose(restartfid,restartfilename); 670 671 /*Free ressources: */ 672 xDelete<char>(femmodel_buffer); 673 xDelete<char>(restartfilename); 674 675 } 676 /*}}}*/ 677 void FemModel::Restart(){ /*{{{*/ 678 679 FILE* restartfid=NULL; 680 FILE* output_fid=NULL; 681 char* restartfilename = NULL; 682 int femmodel_size=0; 683 int fread_return=0; 684 char* femmodel_buffer=NULL; 685 char* femmodel_buffer_ini=NULL; 686 687 /*First, recover the name of the restart file: */ 688 parameters->FindParam(&restartfilename,RestartFileNameEnum); 689 690 /*Now, figure out whether this file actually exists!: */ 691 restartfid=pfopen(restartfilename,"r",false); 692 693 if(restartfid==NULL){ 694 xDelete<char>(restartfilename); 695 return; //could not find the file, so no restart possible. 696 } 697 698 /*Figure out size of buffer to be read: */ 699 fseek(restartfid, 0L, SEEK_END); 700 femmodel_size = ftell(restartfid); 701 fseek(restartfid, 0L, SEEK_SET); 702 703 /*Allocate buffer: */ 704 femmodel_buffer=xNew<char>(femmodel_size); 705 706 /*Read buffer from file: */ 707 fread_return=fread(femmodel_buffer,femmodel_size,sizeof(char),restartfid); if(fread_return!=1)_error_("error reading the buffer from marshalled file!"); 708 femmodel_buffer_ini=femmodel_buffer; //keep track of the initial position, so as to free later. 709 710 this->parameters->FindParam(&output_fid,OutputFilePointerEnum); 711 712 /*Create new FemModel by demarshalling the buffer: */ 713 this->Marshall(&femmodel_buffer,NULL,MARSHALLING_BACKWARD); 714 715 this->parameters->SetParam(output_fid,OutputFilePointerEnum); 716 717 /*Reset position of buffer: */ 718 femmodel_buffer=femmodel_buffer_ini; 719 720 /*Done, close file :*/ 721 pfclose(restartfid,restartfilename); 722 723 /*Free ressources: */ 724 xDelete<char>(restartfilename); 725 xDelete<char>(femmodel_buffer); 726 727 } 728 /*}}}*/ 729 void FemModel::Marshall(char** pmarshalled_data, int* pmarshalled_data_size, int marshall_direction){ /*{{{*/ 730 731 int i; 732 int analysis_type; 733 734 if(marshall_direction==MARSHALLING_BACKWARD){ 735 delete this->profiler; 736 delete this->loads; 737 delete this->materials; 738 delete this->parameters; 739 delete this->constraints; 740 delete this->results; 741 delete this->nodes; 742 delete this->vertices; 743 delete this->elements; 744 xDelete<int>(this->analysis_type_list); 745 746 this->profiler = new Profiler(); 747 this->loads = new Loads(); 748 this->materials = new Materials(); 749 this->parameters = new Parameters(); 750 this->constraints = new Constraints(); 751 this->results = new Results(); 752 this->nodes = new Nodes(); 753 this->vertices = new Vertices(); 754 this->elements = new Elements(); 755 } 756 757 MARSHALLING_ENUM(FemModelEnum); 758 759 MARSHALLING(solution_type); 760 MARSHALLING(analysis_counter); 761 MARSHALLING(nummodels); 762 MARSHALLING_DYNAMIC(analysis_type_list,int,nummodels); 763 764 this->profiler->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction); 765 this->loads->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction); 766 this->materials->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction); 767 this->parameters->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction); 768 this->constraints->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction); 769 this->results->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction); 770 this->nodes->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction); 771 this->vertices->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction); 772 this->elements->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction); 773 774 if(marshall_direction==MARSHALLING_BACKWARD){ 775 //reset hooks for elements, loads and nodes: 776 this->elements->ResetHooks(); 777 this->loads->ResetHooks(); 778 this->materials->ResetHooks(); 779 780 //do the post-processing of the datasets to get an FemModel that can actually run analyses: 781 for(i=0;i<nummodels;i++){ 782 analysis_type=this->analysis_type_list[i]; 783 SetCurrentConfiguration(analysis_type); 784 if(i==0) VerticesDofx(this->vertices,this->parameters); //only call once, we only have one set of vertices 785 SpcNodesx(this->nodes,this->constraints,this->parameters,analysis_type); 786 NodesDofx(this->nodes,this->parameters,analysis_type); 787 ConfigureObjectsx(this->elements,this->loads,this->nodes,this->vertices,this->materials,this->parameters); 736 void FemModel::Solve(void){/*{{{*/ 737 738 /*profiling: */ 739 bool profiling = false; 740 IssmDouble solution_time; 741 IssmDouble solution_flops; 742 IssmDouble solution_memory; 743 744 /*solution: */ 745 int solution_type; 746 void (*solutioncore)(FemModel*)=NULL; //core solution function pointer 747 748 _printf0_("call computational core:\n"); 749 750 /*Retrieve solution_type from parameters: */ 751 parameters->FindParam(&solution_type,SolutionTypeEnum); 752 753 /*Figure out which solution core we are going to run with the current solution type: */ 754 WrapperCorePointerFromSolutionEnum(&solutioncore,this->parameters,solution_type); 755 756 /*run solution core: */ 757 profiler->Tag(STARTCORE); 758 solutioncore(this); 759 profiler->Tag(FINISHCORE); 760 761 /*run AD core if needed: */ 762 profiler->Tag(STARTADCORE); 763 ad_core(this); 764 profiler->Tag(FINISHADCORE); 765 766 /*some profiling results for the core: */ 767 parameters->FindParam(&profiling,DebugProfilingEnum); 768 if(profiling){ 769 770 solution_time=profiler->DeltaTime(STARTCORE,FINISHCORE); 771 solution_flops=profiler->DeltaFlops(STARTCORE,FINISHCORE); 772 solution_memory=profiler->Memory(FINISHCORE); 773 774 _printf0_("Core solution elapsed time : " << solution_time << " Seconds\n"); 775 _printf0_("Core solution number of flops : " << solution_flops << " Flops\n"); 776 _printf0_("Core solution memory used : " << solution_memory << " Bytes\n"); 777 778 /*Add to results: */ 779 results->AddObject(new GenericExternalResult<IssmDouble>(results->Size()+1, ProfilingSolutionTimeEnum, solution_time, 0, 0)); 780 results->AddObject(new GenericExternalResult<IssmDouble>(results->Size()+1, ProfilingCurrentMemEnum, solution_memory, 0, 0)); 781 results->AddObject(new GenericExternalResult<IssmDouble>(results->Size()+1, ProfilingCurrentFlopsEnum, solution_flops, 0, 0)); 782 783 #ifdef _HAVE_ADOLC_ 784 solution_time=profiler->DeltaTime(STARTADCORE,FINISHADCORE); 785 solution_flops=profiler->DeltaFlops(STARTADCORE,FINISHADCORE); 786 solution_memory=profiler->Memory(FINISHADCORE); 787 788 _printf0_("AD Solution elapsed time : " << solution_time << " Seconds\n"); 789 _printf0_("AD Solution number of flops : " << solution_flops << " Flops\n"); 790 _printf0_("AD Solution memory used : " << solution_memory << " Bytes\n"); 791 792 #endif 793 794 } 795 } 796 /*}}}*/ 797 798 /*Modules:*/ 799 void FemModel::BalancethicknessMisfitx(IssmDouble* presponse){/*{{{*/ 800 801 /*output: */ 802 IssmDouble J=0.; 803 IssmDouble J_sum; 804 805 IssmDouble weight,vx,vy,H,dvx[2],dvy[2],dH[2]; 806 IssmDouble temp,Jdet,dhdt,groundedice_melting,surface_mass_balance; 807 IssmDouble* xyz_list = NULL; 808 IssmDouble dp[3]; 809 810 /*Compute Misfit: */ 811 for(int i=0;i<elements->Size();i++){ 812 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 813 814 /*If on water, return 0: */ 815 if(!element->IsIceInElement()) continue; 816 817 /* Get node coordinates*/ 818 element->GetVerticesCoordinates(&xyz_list); 819 Input* weights_input = element->GetInput(InversionCostFunctionsCoefficientsEnum); _assert_(weights_input); 820 Input* thickness_input = element->GetInput(ThicknessEnum); _assert_(thickness_input); 821 Input* vx_input = element->GetInput(VxEnum); _assert_(vx_input); 822 Input* vy_input = element->GetInput(VyEnum); _assert_(vy_input); 823 Input* surface_mass_balance_input = element->GetInput(SmbMassBalanceEnum); _assert_(surface_mass_balance_input); 824 Input* groundedice_melting_input = element->GetInput(BasalforcingsGroundediceMeltingRateEnum); _assert_(groundedice_melting_input); 825 Input* dhdt_input = element->GetInput(BalancethicknessThickeningRateEnum); _assert_(dhdt_input); 826 827 /* Start looping on the number of gaussian points: */ 828 Gauss* gauss=element->NewGauss(2); 829 for(int ig=gauss->begin();ig<gauss->end();ig++){ 830 831 gauss->GaussPoint(ig); 832 833 /* Get Jacobian determinant: */ 834 element->JacobianDeterminant(&Jdet,xyz_list,gauss); 835 836 /*Get all parameters at gaussian point*/ 837 weights_input->GetInputValue(&weight,gauss,BalancethicknessMisfitEnum); 838 thickness_input->GetInputValue(&H, gauss); 839 thickness_input->GetInputDerivativeValue(&dH[0],xyz_list,gauss); 840 surface_mass_balance_input->GetInputValue(&surface_mass_balance,gauss); 841 groundedice_melting_input->GetInputValue(&groundedice_melting,gauss); 842 dhdt_input->GetInputValue(&dhdt,gauss); 843 vx_input->GetInputValue(&vx,gauss); 844 vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss); 845 vy_input->GetInputValue(&vy,gauss); 846 vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss); 847 848 /*Balance thickness soft constraint J = 1/2 (div(Hv)-a)^2*/ 849 temp = vx*dH[0]+vy*dH[1]+H*(dvx[0]+dvy[1]) - (surface_mass_balance-groundedice_melting-dhdt); 850 J +=weight*1/2*temp*temp*Jdet*gauss->weight; 788 851 } 789 852 790 //Reset current configuration: 791 analysis_type=this->analysis_type_list[analysis_counter]; 792 SetCurrentConfiguration(analysis_type); 793 } 794 795 } 796 /*}}}*/ 797 798 /*Modules:*/ 799 int FemModel::UpdateVertexPositionsx(void){ /*{{{*/ 800 801 IssmDouble *surface = NULL; 802 IssmDouble *bed = NULL; 803 804 if(VerboseSolution()) _printf0_(" updating vertices positions\n"); 805 806 /*get vertex vectors for bed and thickness: */ 807 GetVectorFromInputsx(&surface ,this, SurfaceEnum,VertexPIdEnum); 808 GetVectorFromInputsx(&bed ,this, BaseEnum, VertexPIdEnum); 809 810 /*Allocate vector*/ 811 Vector<IssmDouble> *vx=new Vector<IssmDouble>(vertices->NumberOfVertices()); 812 Vector<IssmDouble> *vy=new Vector<IssmDouble>(vertices->NumberOfVertices()); 813 Vector<IssmDouble> *vz=new Vector<IssmDouble>(vertices->NumberOfVertices()); 814 815 /*Update verices new geometry: */ 816 for(int i=0;i<vertices->Size();i++){ 817 Vertex* vertex=(Vertex*)vertices->GetObjectByOffset(i); 818 vertex->UpdatePosition(vx,vy,vz,parameters,surface,bed); 819 } 820 821 /*Assemble mesh velocity*/ 822 vx->Assemble(); 823 vy->Assemble(); 824 vz->Assemble(); 825 826 /*Update element inputs*/ 827 InputUpdateFromVectorx(this,vx,VxMeshEnum,VertexPIdEnum); 828 InputUpdateFromVectorx(this,vy,VyMeshEnum,VertexPIdEnum); 829 InputUpdateFromVectorx(this,vz,VzMeshEnum,VertexPIdEnum); 830 831 /*Free ressources:*/ 832 delete vx; 833 delete vy; 834 delete vz; 835 xDelete<IssmDouble>(bed); 836 xDelete<IssmDouble>(surface); 837 return 1; 838 } 839 /*}}}*/ 840 void FemModel::UpdateConstraintsx(void){ /*{{{*/ 841 842 IssmDouble time; 843 int analysis_type; 844 845 /*retrieve parameters: */ 846 parameters->FindParam(&analysis_type,AnalysisTypeEnum); 847 parameters->FindParam(&time,TimeEnum); 848 849 /*start module: */ 850 if(VerboseModule()) _printf0_(" Updating constraints and active domain of analysis " << EnumToStringx(analysis_type) << " for time: " << time << "\n"); 851 852 Analysis* analysis= EnumToAnalysis(analysis_type); 853 analysis->UpdateConstraints(this); 854 delete analysis; 855 856 /*Second, constraints might be time dependent: */ 857 SpcNodesx(nodes,constraints,parameters,analysis_type); 858 859 /*Now, update degrees of freedoms: */ 860 NodesDofx(nodes,parameters,analysis_type); 861 862 } 863 /*}}}*/ 853 /*clean up and Return: */ 854 xDelete<IssmDouble>(xyz_list); 855 delete gauss; 856 } 857 858 /*Sum all J from all cpus of the cluster:*/ 859 ISSM_MPI_Reduce (&J,&J_sum,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 860 ISSM_MPI_Bcast(&J_sum,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 861 J=J_sum; 862 863 /*Assign output pointers: */ 864 *presponse=J; 865 866 }/*}}}*/ 867 void FemModel::CalvingRateDevx(){/*{{{*/ 868 869 for(int i=0;i<elements->Size();i++){ 870 Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i)); 871 element->CalvingRateDev(); 872 } 873 } 874 /*}}}*/ 875 void FemModel::CalvingRateLevermannx(){/*{{{*/ 876 877 for(int i=0;i<elements->Size();i++){ 878 Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i)); 879 element->CalvingRateLevermann(); 880 } 881 } 882 /*}}}*/ 883 void FemModel::CostFunctionx(IssmDouble* pJ,IssmDouble** pJlist,int* pn){/*{{{*/ 884 885 /*Intermediary*/ 886 int num_responses; 887 int *responses = NULL; 888 Results *cost_functions = NULL; 889 890 /*Recover parameters*/ 891 parameters->FindParam(&num_responses,InversionNumCostFunctionsEnum); 892 parameters->FindParam(&responses,NULL,InversionCostFunctionsEnum); 893 894 /*Get the value of all cost functions*/ 895 this->RequestedOutputsx(&cost_functions,responses,num_responses); 896 897 /*Get and add all contributions one by one*/ 898 IssmDouble J=0; 899 IssmDouble* Jlist = xNew<IssmDouble>(num_responses); 900 for(int i=0;i<num_responses;i++){ 901 ExternalResult* result=(ExternalResult*)cost_functions->GetObjectByOffset(i); 902 Jlist[i] = reCast<IssmDouble>(result->GetValue()); 903 J += Jlist[i]; 904 } 905 _assert_(cost_functions->Size()==num_responses); 906 907 /*Assign output pointers: */ 908 delete cost_functions; 909 xDelete<int>(responses); 910 if(pJ) *pJ = J; 911 if(pJlist) *pJlist = Jlist; 912 else xDelete<IssmDouble>(Jlist); 913 if(pn) *pn = num_responses; 914 } 915 /*}}}*/ 916 void FemModel::DeviatoricStressx(){/*{{{*/ 917 918 for(int i=0;i<elements->Size();i++){ 919 Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i)); 920 element->ComputeDeviatoricStressTensor(); 921 } 922 } 923 /*}}}*/ 924 void FemModel::Divergencex(IssmDouble* pdiv){/*{{{*/ 925 926 IssmDouble local_divergence=0; 927 IssmDouble total_divergence; 928 929 for(int i=0;i<this->elements->Size();i++){ 930 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 931 local_divergence+=element->Divergence(); 932 } 933 ISSM_MPI_Reduce(&local_divergence,&total_divergence,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 934 ISSM_MPI_Bcast(&total_divergence,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 935 936 /*Assign output pointers: */ 937 *pdiv=total_divergence; 938 939 }/*}}}*/ 864 940 void FemModel::ElementOperationx(void (Element::*function)(void)){ /*{{{*/ 865 941 … … 869 945 } 870 946 947 } 948 /*}}}*/ 949 void FemModel::ElementResponsex(IssmDouble* presponse,int response_enum){/*{{{*/ 950 951 int found=0; 952 int sumfound=0; 953 int cpu_found=-1; 954 int index; 955 IssmDouble response; 956 Element* element=NULL; 957 958 /*retrieve element we are interested in: */ 959 this->parameters->FindParam(&index,IndexEnum); 960 int my_rank=IssmComm::GetRank(); 961 962 /*now, go through our elements, and retrieve the one with this id: index: */ 963 for(int i=0;i<this->elements->Size();i++){ 964 element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 965 if (element->Id()==index){ 966 found=1; 967 cpu_found=my_rank; 968 break; 969 } 970 } 971 972 /*Broadcast whether we found the element: */ 973 ISSM_MPI_Allreduce ( &found,&sumfound,1,ISSM_MPI_INT,ISSM_MPI_SUM,IssmComm::GetComm()); 974 if(!sumfound)_error_("could not find material with id" << index << " to compute ElementResponse"); 975 976 /*Ok, we found the element, compute responseocity: */ 977 if(my_rank==cpu_found){ 978 element->ElementResponse(&response,response_enum); 979 } 980 981 /*Broadcast and plug into response: */ 982 ISSM_MPI_Allreduce ( &cpu_found,&cpu_found,1,ISSM_MPI_INT,ISSM_MPI_MAX,IssmComm::GetComm()); 983 ISSM_MPI_Bcast(&response,1,ISSM_MPI_DOUBLE,cpu_found,IssmComm::GetComm()); 984 985 /*Assign output pointers: */ 986 *presponse=response; 987 988 }/*}}}*/ 989 void FemModel::FloatingAreax(IssmDouble* pV){/*{{{*/ 990 991 IssmDouble local_floating_area= 0; 992 IssmDouble total_floating_area; 993 994 for(int i=0;i<this->elements->Size();i++){ 995 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 996 local_floating_area+=element->FloatingArea(); 997 } 998 ISSM_MPI_Reduce(&local_floating_area,&total_floating_area,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 999 ISSM_MPI_Bcast(&total_floating_area,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1000 1001 /*Assign output pointers: */ 1002 *pV=total_floating_area; 1003 1004 }/*}}}*/ 1005 void FemModel::GetInputLocalMinMaxOnNodesx(IssmDouble** pmin,IssmDouble** pmax,IssmDouble* ug){/*{{{*/ 1006 1007 /*Get vector sizes for current configuration*/ 1008 int configuration_type; 1009 this->parameters->FindParam(&configuration_type,ConfigurationTypeEnum); 1010 int numnodes = this->nodes->NumberOfNodes(configuration_type); 1011 1012 /*Initialize output vectors*/ 1013 IssmDouble* uLmin_local = xNew<IssmDouble>(numnodes); 1014 IssmDouble* uLmax_local = xNew<IssmDouble>(numnodes); 1015 IssmDouble* uLmin = xNew<IssmDouble>(numnodes); 1016 IssmDouble* uLmax = xNew<IssmDouble>(numnodes); 1017 for(int i=0;i<numnodes;i++){ 1018 uLmin_local[i] = +1.e+50; 1019 uLmax_local[i] = -1.e+50; 1020 } 1021 1022 for(int i=0;i<this->elements->Size();i++){ 1023 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1024 element->GetInputLocalMinMaxOnNodes(uLmin_local,uLmax_local,ug); 1025 } 1026 1027 /*Synchronize all CPUs*/ 1028 ISSM_MPI_Allreduce((void*)uLmin_local,(void*)uLmin,numnodes,ISSM_MPI_DOUBLE,ISSM_MPI_MIN,IssmComm::GetComm()); 1029 ISSM_MPI_Allreduce((void*)uLmax_local,(void*)uLmax,numnodes,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,IssmComm::GetComm()); 1030 xDelete<IssmDouble>(uLmin_local); 1031 xDelete<IssmDouble>(uLmax_local); 1032 1033 /*Assign output pointers: */ 1034 *pmin=uLmin; 1035 *pmax=uLmax; 1036 1037 }/*}}}*/ 1038 void FemModel::GroundedAreax(IssmDouble* pV){/*{{{*/ 1039 1040 IssmDouble local_grounded_area= 0; 1041 IssmDouble total_grounded_area; 1042 1043 for(int i=0;i<this->elements->Size();i++){ 1044 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1045 local_grounded_area+=element->GroundedArea(); 1046 } 1047 ISSM_MPI_Reduce(&local_grounded_area,&total_grounded_area,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 1048 ISSM_MPI_Bcast(&total_grounded_area,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1049 1050 /*Assign output pointers: */ 1051 *pV=total_grounded_area; 1052 1053 }/*}}}*/ 1054 void FemModel::IceMassx(IssmDouble* pM){/*{{{*/ 1055 1056 IssmDouble local_ice_mass = 0; 1057 IssmDouble total_ice_mass; 1058 1059 for(int i=0;i<this->elements->Size();i++){ 1060 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1061 local_ice_mass+=element->IceMass(); 1062 } 1063 ISSM_MPI_Reduce(&local_ice_mass,&total_ice_mass,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 1064 ISSM_MPI_Bcast(&total_ice_mass,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1065 1066 /*Assign output pointers: */ 1067 *pM=total_ice_mass; 1068 1069 }/*}}}*/ 1070 void FemModel::IceVolumeAboveFloatationx(IssmDouble* pV){/*{{{*/ 1071 1072 IssmDouble local_ice_volume_af = 0; 1073 IssmDouble total_ice_volume_af; 1074 1075 for(int i=0;i<this->elements->Size();i++){ 1076 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1077 local_ice_volume_af+=element->IceVolumeAboveFloatation(); 1078 } 1079 ISSM_MPI_Reduce(&local_ice_volume_af,&total_ice_volume_af,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 1080 ISSM_MPI_Bcast(&total_ice_volume_af,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1081 1082 /*Assign output pointers: */ 1083 *pV=total_ice_volume_af; 1084 1085 }/*}}}*/ 1086 void FemModel::IceVolumex(IssmDouble* pV){/*{{{*/ 1087 1088 IssmDouble local_ice_volume = 0; 1089 IssmDouble total_ice_volume; 1090 1091 for(int i=0;i<this->elements->Size();i++){ 1092 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1093 local_ice_volume+=element->IceVolume(); 1094 } 1095 ISSM_MPI_Reduce(&local_ice_volume,&total_ice_volume,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 1096 ISSM_MPI_Bcast(&total_ice_volume,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1097 1098 /*Assign output pointers: */ 1099 *pV=total_ice_volume; 1100 1101 }/*}}}*/ 1102 void FemModel::MassFluxx(IssmDouble* pmass_flux){/*{{{*/ 1103 1104 int i,j; 1105 Element *element = NULL; 1106 int element_id; 1107 bool ispresent = false; 1108 IssmDouble mass_flux = 0; 1109 IssmDouble all_mass_flux = 0; 1110 int counter; 1111 IssmDouble **array = NULL; 1112 int M; 1113 int *mdims_array = NULL; 1114 int *ndims_array = NULL; 1115 IssmDouble *segments = NULL; 1116 int num_segments; 1117 1118 /*First, figure out which segment to compute our mass flux on. Start with retrieving qmu_mass_flux_segments: */ 1119 this->parameters->FindParam(&ispresent,MassFluxSegmentsPresentEnum); 1120 if(!ispresent)_error_("no mass flux segments available!"); 1121 this->parameters->FindParam(&array,&M,&mdims_array,&ndims_array,MassFluxSegmentsEnum); 1122 1123 /*Retrieve index of segments being used for MassFlux computation: */ 1124 parameters->FindParam(&counter,IndexEnum); 1125 1126 /*retrieve segments from array: */ 1127 segments = array[counter-1]; //matlab to "C" indexing 1128 num_segments = mdims_array[counter-1]; 1129 1130 /*Go through segments, and then elements, and figure out which elements belong to a segment. 1131 * When we find one, use the element to compute the mass flux on the segment: */ 1132 for(i=0;i<num_segments;i++){ 1133 element_id=reCast<int,IssmDouble>(*(segments+5*i+4)); 1134 for(j=0;j<elements->Size();j++){ 1135 element=(Element*)this->elements->GetObjectByOffset(j); 1136 if (element->Id()==element_id){ 1137 /*We found the element which owns this segment, use it to compute the mass flux: */ 1138 mass_flux+=element->MassFlux(segments+5*i+0); 1139 break; 1140 } 1141 } 1142 } 1143 1144 ISSM_MPI_Allreduce ( (void*)&mass_flux,(void*)&all_mass_flux,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,IssmComm::GetComm()); 1145 mass_flux=all_mass_flux; 1146 1147 /*Free ressources:*/ 1148 for(i=0;i<M;i++){ 1149 IssmDouble* matrix=array[i]; 1150 xDelete<IssmDouble>(matrix); 1151 } 1152 xDelete<int>(mdims_array); 1153 xDelete<int>(ndims_array); 1154 xDelete<IssmDouble*>(array); 1155 1156 /*Assign output pointers: */ 1157 *pmass_flux=mass_flux; 1158 1159 }/*}}}*/ 1160 void FemModel::MaxAbsVxx(IssmDouble* pmaxabsvx){/*{{{*/ 1161 1162 int i; 1163 IssmDouble maxabsvx; 1164 IssmDouble node_maxabsvx; 1165 IssmDouble element_maxabsvx; 1166 1167 /*Go through elements, and request velocity: */ 1168 maxabsvx=-INFINITY; 1169 for(i=0;i<this->elements->Size();i++){ 1170 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1171 element_maxabsvx=element->inputs->MaxAbs(VxEnum); 1172 if(element_maxabsvx>maxabsvx) maxabsvx=element_maxabsvx; 1173 } 1174 1175 /*Figure out maximum across the cluster: */ 1176 ISSM_MPI_Reduce(&maxabsvx,&node_maxabsvx,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1177 ISSM_MPI_Bcast(&node_maxabsvx,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1178 maxabsvx=node_maxabsvx; 1179 1180 /*Assign output pointers:*/ 1181 *pmaxabsvx=maxabsvx; 1182 1183 }/*}}}*/ 1184 void FemModel::MaxAbsVyx(IssmDouble* pmaxabsvy){/*{{{*/ 1185 1186 int i; 1187 IssmDouble maxabsvy; 1188 IssmDouble node_maxabsvy; 1189 IssmDouble element_maxabsvy; 1190 1191 /*Go through elements, and request velocity: */ 1192 maxabsvy=-INFINITY; 1193 for(i=0;i<this->elements->Size();i++){ 1194 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1195 element_maxabsvy=element->inputs->MaxAbs(VyEnum); 1196 if(element_maxabsvy>maxabsvy) maxabsvy=element_maxabsvy; 1197 } 1198 1199 /*Figure out maximum across the cluster: */ 1200 ISSM_MPI_Reduce(&maxabsvy,&node_maxabsvy,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1201 ISSM_MPI_Bcast(&node_maxabsvy,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1202 maxabsvy=node_maxabsvy; 1203 1204 /*Assign output pointers:*/ 1205 *pmaxabsvy=maxabsvy; 1206 1207 }/*}}}*/ 1208 void FemModel::MaxAbsVzx(IssmDouble* pmaxabsvz){/*{{{*/ 1209 1210 int i; 1211 IssmDouble maxabsvz; 1212 IssmDouble node_maxabsvz; 1213 IssmDouble element_maxabsvz; 1214 1215 /*Go through elements, and request velocity: */ 1216 maxabsvz=-INFINITY; 1217 for(i=0;i<this->elements->Size();i++){ 1218 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1219 element_maxabsvz=element->inputs->MaxAbs(VzEnum); 1220 if(element_maxabsvz>maxabsvz) maxabsvz=element_maxabsvz; 1221 } 1222 1223 /*Figure out maximum across the cluster: */ 1224 ISSM_MPI_Reduce(&maxabsvz,&node_maxabsvz,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1225 ISSM_MPI_Bcast(&node_maxabsvz,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1226 maxabsvz=node_maxabsvz; 1227 1228 /*Assign output pointers:*/ 1229 *pmaxabsvz=maxabsvz; 1230 1231 }/*}}}*/ 1232 void FemModel::MaxDivergencex(IssmDouble* pdiv){/*{{{*/ 1233 1234 IssmDouble local_divergence; 1235 IssmDouble node_max_divergence; 1236 IssmDouble max_divergence = -INFINITY; 1237 1238 for(int i=0;i<this->elements->Size();i++){ 1239 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1240 local_divergence=element->Divergence(); 1241 if(fabs(local_divergence)>max_divergence) max_divergence=fabs(local_divergence); 1242 } 1243 ISSM_MPI_Reduce(&max_divergence,&node_max_divergence,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1244 ISSM_MPI_Bcast(&node_max_divergence,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1245 max_divergence=node_max_divergence; 1246 1247 /*Assign output pointers: */ 1248 *pdiv=max_divergence; 1249 1250 }/*}}}*/ 1251 void FemModel::MaxVelx(IssmDouble* pmaxvel){/*{{{*/ 1252 1253 int i; 1254 IssmDouble maxvel; 1255 IssmDouble node_maxvel; 1256 IssmDouble element_maxvel; 1257 1258 /*Go through elements, and request velocity: */ 1259 maxvel=-INFINITY; 1260 for(i=0;i<this->elements->Size();i++){ 1261 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1262 element_maxvel = element->inputs->Max(VelEnum); 1263 if(element_maxvel>maxvel) maxvel=element_maxvel; 1264 } 1265 1266 /*Figure out maximum across the cluster: */ 1267 ISSM_MPI_Reduce(&maxvel,&node_maxvel,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1268 ISSM_MPI_Bcast(&node_maxvel,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1269 maxvel=node_maxvel; 1270 1271 /*Assign output pointers:*/ 1272 *pmaxvel=maxvel; 1273 1274 }/*}}}*/ 1275 void FemModel::MaxVxx(IssmDouble* pmaxvx){/*{{{*/ 1276 1277 int i; 1278 IssmDouble maxvx; 1279 IssmDouble node_maxvx; 1280 IssmDouble element_maxvx; 1281 1282 /*Go through elements, and request velocity: */ 1283 maxvx=-INFINITY; 1284 for(i=0;i<this->elements->Size();i++){ 1285 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1286 element_maxvx = element->inputs->Max(VxEnum); 1287 if(element_maxvx>maxvx) maxvx=element_maxvx; 1288 } 1289 1290 /*Figure out maximum across the cluster: */ 1291 ISSM_MPI_Reduce(&maxvx,&node_maxvx,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1292 ISSM_MPI_Bcast(&node_maxvx,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1293 maxvx=node_maxvx; 1294 1295 /*Assign output pointers:*/ 1296 *pmaxvx=maxvx; 1297 1298 }/*}}}*/ 1299 void FemModel::MaxVyx(IssmDouble* pmaxvy){/*{{{*/ 1300 1301 int i; 1302 IssmDouble maxvy; 1303 IssmDouble node_maxvy; 1304 IssmDouble element_maxvy; 1305 1306 /*Go through elements, and request velocity: */ 1307 maxvy=-INFINITY; 1308 for(i=0;i<this->elements->Size();i++){ 1309 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1310 element_maxvy = element->inputs->Max(VyEnum); 1311 if(element_maxvy>maxvy) maxvy=element_maxvy; 1312 } 1313 1314 /*Figure out maximum across the cluster: */ 1315 ISSM_MPI_Reduce(&maxvy,&node_maxvy,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1316 ISSM_MPI_Bcast(&node_maxvy,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1317 maxvy=node_maxvy; 1318 1319 /*Assign output pointers:*/ 1320 *pmaxvy=maxvy; 1321 1322 }/*}}}*/ 1323 void FemModel::MaxVzx(IssmDouble* pmaxvz){/*{{{*/ 1324 1325 int i; 1326 IssmDouble maxvz; 1327 IssmDouble node_maxvz; 1328 IssmDouble element_maxvz; 1329 1330 /*Go through elements, and request velocity: */ 1331 maxvz=-INFINITY; 1332 for(i=0;i<this->elements->Size();i++){ 1333 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1334 element_maxvz = element->inputs->Max(VzEnum); 1335 if(element_maxvz>maxvz) maxvz=element_maxvz; 1336 } 1337 1338 /*Figure out maximum across the cluster: */ 1339 ISSM_MPI_Reduce(&maxvz,&node_maxvz,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1340 ISSM_MPI_Bcast(&node_maxvz,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1341 maxvz=node_maxvz; 1342 1343 /*Assign output pointers:*/ 1344 *pmaxvz=maxvz; 1345 1346 }/*}}}*/ 1347 void FemModel::MinVelx(IssmDouble* pminvel){/*{{{*/ 1348 1349 int i; 1350 IssmDouble minvel; 1351 IssmDouble node_minvel; 1352 IssmDouble element_minvel; 1353 1354 /*Go through elements, and request velocity: */ 1355 minvel=INFINITY; 1356 for(i=0;i<this->elements->Size();i++){ 1357 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1358 element_minvel = element->inputs->Min(VelEnum); 1359 if(element_minvel<minvel) minvel=element_minvel; 1360 } 1361 1362 /*Figure out minimum across the cluster: */ 1363 ISSM_MPI_Reduce(&minvel,&node_minvel,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1364 ISSM_MPI_Bcast(&node_minvel,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1365 minvel=node_minvel; 1366 1367 /*Assign output pointers:*/ 1368 *pminvel=minvel; 1369 1370 }/*}}}*/ 1371 void FemModel::MinVxx(IssmDouble* pminvx){/*{{{*/ 1372 1373 int i; 1374 IssmDouble minvx; 1375 IssmDouble node_minvx; 1376 IssmDouble element_minvx; 1377 1378 /*Go through elements, and request velocity: */ 1379 minvx=INFINITY; 1380 for(i=0;i<this->elements->Size();i++){ 1381 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1382 element_minvx = element->inputs->Min(VxEnum); 1383 if(element_minvx<minvx) minvx=element_minvx; 1384 } 1385 1386 /*Figure out minimum across the cluster: */ 1387 ISSM_MPI_Reduce(&minvx,&node_minvx,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1388 ISSM_MPI_Bcast(&node_minvx,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1389 minvx=node_minvx; 1390 1391 /*Assign output pointers:*/ 1392 *pminvx=minvx; 1393 1394 }/*}}}*/ 1395 void FemModel::MinVyx(IssmDouble* pminvy){/*{{{*/ 1396 1397 int i; 1398 IssmDouble minvy; 1399 IssmDouble node_minvy; 1400 IssmDouble element_minvy; 1401 1402 /*Go through elements, and request velocity: */ 1403 minvy=INFINITY; 1404 for(i=0;i<this->elements->Size();i++){ 1405 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1406 element_minvy = element->inputs->Min(VyEnum); 1407 if(element_minvy<minvy) minvy=element_minvy; 1408 } 1409 1410 /*Figure out minimum across the cluster: */ 1411 ISSM_MPI_Reduce(&minvy,&node_minvy,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1412 ISSM_MPI_Bcast(&node_minvy,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1413 minvy=node_minvy; 1414 1415 /*Assign output pointers:*/ 1416 *pminvy=minvy; 1417 1418 }/*}}}*/ 1419 void FemModel::MinVzx(IssmDouble* pminvz){/*{{{*/ 1420 1421 int i; 1422 IssmDouble minvz; 1423 IssmDouble node_minvz; 1424 IssmDouble element_minvz; 1425 1426 /*Go through elements, and request velocity: */ 1427 minvz=INFINITY; 1428 for(i=0;i<this->elements->Size();i++){ 1429 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1430 element_minvz = element->inputs->Min(VzEnum); 1431 if(element_minvz<minvz) minvz=element_minvz; 1432 } 1433 1434 /*Figure out minimum across the cluster: */ 1435 ISSM_MPI_Reduce(&minvz,&node_minvz,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1436 ISSM_MPI_Bcast(&node_minvz,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1437 minvz=node_minvz; 1438 1439 /*Assign output pointers:*/ 1440 *pminvz=minvz; 1441 1442 }/*}}}*/ 1443 void FemModel::OutputControlsx(Results **presults){/*{{{*/ 1444 1445 /*parameters: */ 1446 int num_controls,step; 1447 IssmDouble time; 1448 int *control_type = NULL; 1449 1450 /*recover results*/ 1451 Results* results = *presults; 1452 if(!results) results = new Results(); 1453 1454 /*Get list of Controls*/ 1455 this->parameters->FindParam(&num_controls,InversionNumControlParametersEnum); 1456 this->parameters->FindParam(&control_type,NULL,InversionControlParametersEnum); 1457 this->parameters->FindParam(&step,StepEnum); 1458 this->parameters->FindParam(&time,TimeEnum); 1459 1460 for(int i=0;i<num_controls;i++){ 1461 1462 int control_enum = control_type[i]; 1463 int gradient_enum; 1464 1465 switch(i){ 1466 case 0: gradient_enum = Gradient1Enum; break; 1467 case 1: gradient_enum = Gradient2Enum; break; 1468 case 2: gradient_enum = Gradient3Enum; break; 1469 default: _error_("more than 3 controls not implemented yet"); 1470 } 1471 1472 /*Allocate vector*/ 1473 Vector<IssmPDouble> *vector_control = new Vector<IssmPDouble>(this->vertices->NumberOfVertices()); 1474 Vector<IssmPDouble> *vector_gradient = new Vector<IssmPDouble>(this->vertices->NumberOfVertices()); 1475 1476 /*Fill in vector*/ 1477 for(int j=0;j<elements->Size();j++){ 1478 Element* element=(Element*)elements->GetObjectByOffset(j); 1479 element->ControlToVectors(vector_control,vector_gradient,control_enum); 1480 } 1481 vector_control->Assemble(); 1482 vector_gradient->Assemble(); 1483 1484 results->AddResult(new GenericExternalResult<Vector<IssmPDouble>*>(results->Size()+1,control_enum,vector_control ,step,time)); 1485 results->AddResult(new GenericExternalResult<Vector<IssmPDouble>*>(results->Size()+1,gradient_enum,vector_gradient,step,time)); 1486 } 1487 1488 /*Clean up and return*/ 1489 xDelete<int>(control_type); 1490 } 1491 /*}}}*/ 1492 void FemModel::RequestedDependentsx(void){/*{{{*/ 1493 1494 bool isautodiff = false; 1495 IssmDouble output_value; 1496 1497 int num_dependents; 1498 IssmPDouble *dependents; 1499 DataSet* dependent_objects=NULL; 1500 int my_rank=IssmComm::GetRank(); 1501 1502 /*AD mode on?: */ 1503 parameters->FindParam(&isautodiff,AutodiffIsautodiffEnum); 1504 1505 if(isautodiff){ 1506 #ifdef _HAVE_ADOLC_ 1507 parameters->FindParam(&num_dependents,AutodiffNumDependentsEnum); 1508 parameters->FindParam(&dependent_objects,AutodiffDependentObjectsEnum); 1509 if(num_dependents){ 1510 dependents=xNew<IssmPDouble>(num_dependents); 1511 1512 /*Go through our dependent variables, and compute the response:*/ 1513 for(int i=0;i<dependent_objects->Size();i++){ 1514 DependentObject* dep=(DependentObject*)dependent_objects->GetObjectByOffset(i); 1515 dep->Responsex(&output_value,this); 1516 if (my_rank==0) { 1517 output_value>>=dependents[i]; 1518 } 1519 } 1520 } 1521 delete dependent_objects; 1522 if(num_dependents)xDelete<IssmPDouble>(dependents); 1523 #else 1524 _error_("Should not be requesting dependents when an AD library is not available!"); 1525 #endif 1526 } 1527 } 1528 /*}}}*/ 1529 void FemModel::RequestedOutputsx(Results **presults,char** requested_outputs, int numoutputs, bool save_results){/*{{{*/ 1530 1531 /*Intermediaries*/ 1532 bool isvec,results_on_nodes; 1533 int step,output_enum; 1534 IssmDouble time; 1535 IssmDouble double_result; 1536 const char *output_string = NULL; 1537 1538 /*recover results*/ 1539 Results* results = *presults; 1540 if(!results) results = new Results(); 1541 1542 /*Get time and step*/ 1543 parameters->FindParam(&step,StepEnum); 1544 parameters->FindParam(&time,TimeEnum); 1545 parameters->FindParam(&results_on_nodes,SettingsResultsOnNodesEnum); 1546 1547 /*Go through all requested output*/ 1548 for(int i=0;i<numoutputs;i++){ 1549 1550 output_string = requested_outputs[i]; 1551 output_enum = StringToEnumx(output_string,false); 1552 isvec = false; 1553 1554 /*If string is not an enum, it is defined in output definitions*/ 1555 if(output_enum<0){ 1556 double_result = OutputDefinitionsResponsex(this,output_string); 1557 if(save_results){ 1558 results->AddResult(new GenericExternalResult<IssmPDouble>(results->Size()+1,output_string,reCast<IssmPDouble>(double_result),step,time)); 1559 continue; 1560 } 1561 } 1562 else{ 1563 /*last chance for the output definition, if the enum is one of Outputdefinition[1-10]Enum:*/ 1564 if(output_enum>=Outputdefinition1Enum && output_enum <=Outputdefinition10Enum){ 1565 double_result = OutputDefinitionsResponsex(this,output_enum); 1566 if(save_results){ 1567 results->AddResult(new GenericExternalResult<IssmPDouble>(results->Size()+1,output_string,reCast<IssmPDouble>(double_result),step,time)); 1568 continue; 1569 } 1570 } 1571 else{ 1572 switch(output_enum){ 1573 1574 /*Scalar output*/ 1575 case DivergenceEnum: this->Divergencex(&double_result); break; 1576 case MaxDivergenceEnum: this->MaxDivergencex(&double_result); break; 1577 case IceMassEnum: this->IceMassx(&double_result); break; 1578 case IceVolumeEnum: this->IceVolumex(&double_result); break; 1579 case IceVolumeAboveFloatationEnum: this->IceVolumeAboveFloatationx(&double_result); break; 1580 case GroundedAreaEnum: this->GroundedAreax(&double_result); break; 1581 case FloatingAreaEnum: this->FloatingAreax(&double_result); break; 1582 case MinVelEnum: this->MinVelx(&double_result); break; 1583 case MaxVelEnum: this->MaxVelx(&double_result); break; 1584 case MinVxEnum: this->MinVxx(&double_result); break; 1585 case MaxVxEnum: this->MaxVxx(&double_result); break; 1586 case MaxAbsVxEnum: this->MaxAbsVxx(&double_result); break; 1587 case MinVyEnum: this->MinVyx(&double_result); break; 1588 case MaxVyEnum: this->MaxVyx(&double_result); break; 1589 case MaxAbsVyEnum: this->MaxAbsVyx(&double_result); break; 1590 case MinVzEnum: this->MinVzx(&double_result); break; 1591 case MaxVzEnum: this->MaxVzx(&double_result); break; 1592 case MaxAbsVzEnum: this->MaxAbsVzx(&double_result); break; 1593 case MassFluxEnum: this->MassFluxx(&double_result); break; 1594 case TotalFloatingBmbEnum: this->TotalFloatingBmbx(&double_result); break; 1595 case TotalGroundedBmbEnum: this->TotalGroundedBmbx(&double_result); break; 1596 case TotalSmbEnum: this->TotalSmbx(&double_result); break; 1597 1598 /*Scalar control output*/ 1599 case SurfaceAbsVelMisfitEnum: SurfaceAbsVelMisfitx(&double_result,elements,nodes,vertices,loads,materials,parameters); break; 1600 case SurfaceRelVelMisfitEnum: SurfaceRelVelMisfitx(&double_result,elements,nodes,vertices,loads,materials,parameters); break; 1601 case SurfaceLogVelMisfitEnum: SurfaceLogVelMisfitx(&double_result,elements,nodes,vertices,loads,materials,parameters); break; 1602 case SurfaceLogVxVyMisfitEnum: SurfaceLogVxVyMisfitx(&double_result,elements,nodes,vertices,loads,materials,parameters); break; 1603 case SurfaceAverageVelMisfitEnum: SurfaceAverageVelMisfitx(&double_result,this); break; 1604 case ThicknessAbsMisfitEnum: ThicknessAbsMisfitx(&double_result,elements,nodes,vertices,loads,materials,parameters); break; 1605 case ThicknessAbsGradientEnum: this->ThicknessAbsGradientx(&double_result); break; 1606 case ThicknessAlongGradientEnum: ThicknessAlongGradientx(&double_result,elements,nodes,vertices,loads,materials,parameters); break; 1607 case ThicknessAcrossGradientEnum: ThicknessAcrossGradientx(&double_result,elements,nodes,vertices,loads,materials,parameters); break; 1608 case ThicknessPositiveEnum: this->ThicknessPositivex(&double_result); break; 1609 case RheologyBbarAbsGradientEnum: RheologyBbarAbsGradientx(&double_result,elements,nodes,vertices,loads,materials,parameters); break; 1610 case RheologyBAbsGradientEnum: RheologyBAbsGradientx(&double_result,elements,nodes,vertices,loads,materials,parameters); break; 1611 case DragCoefficientAbsGradientEnum:DragCoefficientAbsGradientx(&double_result,elements,nodes,vertices,loads,materials,parameters); break; 1612 case BalancethicknessMisfitEnum: BalancethicknessMisfitx(&double_result); break; 1613 case SurfaceAbsMisfitEnum: SurfaceAbsMisfitx(&double_result); break; 1614 1615 /*Vector */ 1616 default: 1617 1618 /*Vector layout*/ 1619 int interpolation,nodesperelement,size,nlines,ncols,array_size; 1620 int rank_interpolation=-1,rank_nodesperelement=-1,rank_arraysize=-1,max_rank_arraysize=0; 1621 bool isarray=false; 1622 1623 /*Get interpolation (and compute input if necessary)*/ 1624 for(int j=0;j<elements->Size();j++){ 1625 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(j)); 1626 element->ResultInterpolation(&rank_interpolation,&rank_nodesperelement,&rank_arraysize,output_enum); 1627 if (rank_arraysize>max_rank_arraysize)max_rank_arraysize=rank_arraysize; 1628 } 1629 rank_arraysize=max_rank_arraysize; 1630 1631 /*Broadcast for cpus that do not have any elements*/ 1632 ISSM_MPI_Reduce(&rank_interpolation,&interpolation,1,ISSM_MPI_INT,ISSM_MPI_MAX,0,IssmComm::GetComm()); 1633 ISSM_MPI_Reduce(&rank_nodesperelement,&nodesperelement,1,ISSM_MPI_INT,ISSM_MPI_MAX,0,IssmComm::GetComm()); 1634 ISSM_MPI_Reduce(&rank_arraysize,&array_size,1,ISSM_MPI_INT,ISSM_MPI_MAX,0,IssmComm::GetComm()); 1635 ISSM_MPI_Bcast(&interpolation,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 1636 ISSM_MPI_Bcast(&nodesperelement,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 1637 ISSM_MPI_Bcast(&array_size,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 1638 1639 if(results_on_nodes){ 1640 1641 /*Allocate matrices*/ 1642 int nbe = this->elements->NumberOfElements(); 1643 IssmDouble* values = xNewZeroInit<IssmDouble>(nbe*nodesperelement); 1644 IssmDouble* allvalues = xNew<IssmDouble>(nbe*nodesperelement); 1645 1646 /*Fill-in matrix*/ 1647 for(int j=0;j<elements->Size();j++){ 1648 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(j)); 1649 element->ResultToPatch(values,nodesperelement,output_enum); 1650 } 1651 1652 /*Gather from all cpus*/ 1653 ISSM_MPI_Allreduce((void*)values,(void*)allvalues,nbe*nodesperelement,ISSM_MPI_PDOUBLE,ISSM_MPI_SUM,IssmComm::GetComm()); 1654 xDelete<IssmDouble>(values); 1655 1656 if(save_results)results->AddResult(new GenericExternalResult<IssmDouble*>(results->Size()+1,output_enum,allvalues,nbe,nodesperelement,step,time)); 1657 xDelete<IssmDouble>(allvalues); 1658 1659 } 1660 else{ 1661 1662 /*Allocate vector depending on interpolation*/ 1663 switch(interpolation){ 1664 case P0Enum: isarray = false; size = this->elements->NumberOfElements(); break; 1665 case P1Enum: isarray = false; size = this->vertices->NumberOfVertices(); break; 1666 case P0ArrayEnum: isarray = true; nlines = this->elements->NumberOfElements(); ncols= array_size; break; 1667 default: _error_("Interpolation "<<EnumToStringx(interpolation)<<" not supported yet"); 1668 1669 } 1670 if (!isarray){ 1671 Vector<IssmDouble> *vector_result = new Vector<IssmDouble>(size); 1672 1673 /*Fill in vector*/ 1674 for(int j=0;j<elements->Size();j++){ 1675 Element* element=(Element*)elements->GetObjectByOffset(j); 1676 element->ResultToVector(vector_result,output_enum); 1677 } 1678 vector_result->Assemble(); 1679 1680 if(save_results)results->AddResult(new GenericExternalResult<Vector<IssmDouble>*>(results->Size()+1,output_enum,vector_result,step,time)); 1681 } 1682 else{ 1683 IssmDouble* values = xNewZeroInit<IssmDouble>(nlines*ncols); 1684 IssmDouble* allvalues = xNew<IssmDouble>(nlines*ncols); 1685 1686 /*Fill-in matrix*/ 1687 for(int j=0;j<elements->Size();j++){ 1688 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(j)); 1689 element->ResultToMatrix(values,ncols, output_enum); 1690 } 1691 /*Gather from all cpus*/ 1692 ISSM_MPI_Allreduce((void*)values,(void*)allvalues,ncols*nlines,ISSM_MPI_PDOUBLE,ISSM_MPI_SUM,IssmComm::GetComm()); 1693 xDelete<IssmDouble>(values); 1694 1695 if(save_results)results->AddResult(new GenericExternalResult<IssmDouble*>(results->Size()+1,output_enum,allvalues,nlines,ncols,step,time)); 1696 xDelete<IssmDouble>(allvalues); 1697 } 1698 } 1699 isvec = true; 1700 break; 1701 } 1702 } 1703 1704 } 1705 1706 /*Add result to Results*/ 1707 if(!isvec && save_results){ 1708 results->AddResult(new GenericExternalResult<IssmPDouble>(results->Size()+1,output_string,reCast<IssmPDouble>(double_result),step,time)); 1709 } 1710 } 1711 1712 /*Assign pointer and clean up*/ 1713 *presults = results; 1714 } 1715 /*}}}*/ 1716 void FemModel::RequestedOutputsx(Results **presults,int* requested_outputs, int numoutputs,bool save_results){/*{{{*/ 1717 1718 /*Convert list of enums to list of string*/ 1719 char** enumlist = xNew<char*>(numoutputs); 1720 for(int i=0;i<numoutputs;i++){ 1721 EnumToStringx(&enumlist[i],requested_outputs[i]); 1722 } 1723 1724 /*Call main module*/ 1725 this->RequestedOutputsx(presults,enumlist,numoutputs,save_results); 1726 1727 /*clean up and return*/ 1728 for(int i=0;i<numoutputs;i++) xDelete<char>(enumlist[i]); 1729 xDelete<char*>(enumlist); 1730 return; 871 1731 } 872 1732 /*}}}*/ … … 975 1835 } 976 1836 /*}}}*/ 977 void FemModel::RequestedOutputsx(Results **presults,char** requested_outputs, int numoutputs, bool save_results){/*{{{*/ 978 979 /*Intermediaries*/ 980 bool isvec,results_on_nodes; 981 int step,output_enum; 982 IssmDouble time; 983 IssmDouble double_result; 984 const char *output_string = NULL; 985 986 /*recover results*/ 987 Results* results = *presults; 988 if(!results) results = new Results(); 989 990 /*Get time and step*/ 991 parameters->FindParam(&step,StepEnum); 992 parameters->FindParam(&time,TimeEnum); 993 parameters->FindParam(&results_on_nodes,SettingsResultsOnNodesEnum); 994 995 /*Go through all requested output*/ 996 for(int i=0;i<numoutputs;i++){ 997 998 output_string = requested_outputs[i]; 999 output_enum = StringToEnumx(output_string,false); 1000 isvec = false; 1001 1002 /*If string is not an enum, it is defined in output definitions*/ 1003 if(output_enum<0){ 1004 double_result = OutputDefinitionsResponsex(this,output_string); 1005 if(save_results){ 1006 results->AddResult(new GenericExternalResult<IssmPDouble>(results->Size()+1,output_string,reCast<IssmPDouble>(double_result),step,time)); 1007 continue; 1008 } 1009 } 1010 else{ 1011 /*last chance for the output definition, if the enum is one of Outputdefinition[1-10]Enum:*/ 1012 if(output_enum>=Outputdefinition1Enum && output_enum <=Outputdefinition10Enum){ 1013 double_result = OutputDefinitionsResponsex(this,output_enum); 1014 if(save_results){ 1015 results->AddResult(new GenericExternalResult<IssmPDouble>(results->Size()+1,output_string,reCast<IssmPDouble>(double_result),step,time)); 1016 continue; 1017 } 1018 } 1019 else{ 1020 switch(output_enum){ 1021 1022 /*Scalar output*/ 1023 case DivergenceEnum: this->Divergencex(&double_result); break; 1024 case MaxDivergenceEnum: this->MaxDivergencex(&double_result); break; 1025 case IceMassEnum: this->IceMassx(&double_result); break; 1026 case IceVolumeEnum: this->IceVolumex(&double_result); break; 1027 case IceVolumeAboveFloatationEnum: this->IceVolumeAboveFloatationx(&double_result); break; 1028 case GroundedAreaEnum: this->GroundedAreax(&double_result); break; 1029 case FloatingAreaEnum: this->FloatingAreax(&double_result); break; 1030 case MinVelEnum: this->MinVelx(&double_result); break; 1031 case MaxVelEnum: this->MaxVelx(&double_result); break; 1032 case MinVxEnum: this->MinVxx(&double_result); break; 1033 case MaxVxEnum: this->MaxVxx(&double_result); break; 1034 case MaxAbsVxEnum: this->MaxAbsVxx(&double_result); break; 1035 case MinVyEnum: this->MinVyx(&double_result); break; 1036 case MaxVyEnum: this->MaxVyx(&double_result); break; 1037 case MaxAbsVyEnum: this->MaxAbsVyx(&double_result); break; 1038 case MinVzEnum: this->MinVzx(&double_result); break; 1039 case MaxVzEnum: this->MaxVzx(&double_result); break; 1040 case MaxAbsVzEnum: this->MaxAbsVzx(&double_result); break; 1041 case MassFluxEnum: this->MassFluxx(&double_result); break; 1042 case TotalFloatingBmbEnum: this->TotalFloatingBmbx(&double_result); break; 1043 case TotalGroundedBmbEnum: this->TotalGroundedBmbx(&double_result); break; 1044 case TotalSmbEnum: this->TotalSmbx(&double_result); break; 1045 1046 /*Scalar control output*/ 1047 case SurfaceAbsVelMisfitEnum: SurfaceAbsVelMisfitx(&double_result,elements,nodes,vertices,loads,materials,parameters); break; 1048 case SurfaceRelVelMisfitEnum: SurfaceRelVelMisfitx(&double_result,elements,nodes,vertices,loads,materials,parameters); break; 1049 case SurfaceLogVelMisfitEnum: SurfaceLogVelMisfitx(&double_result,elements,nodes,vertices,loads,materials,parameters); break; 1050 case SurfaceLogVxVyMisfitEnum: SurfaceLogVxVyMisfitx(&double_result,elements,nodes,vertices,loads,materials,parameters); break; 1051 case SurfaceAverageVelMisfitEnum: SurfaceAverageVelMisfitx(&double_result,this); break; 1052 case ThicknessAbsMisfitEnum: ThicknessAbsMisfitx(&double_result,elements,nodes,vertices,loads,materials,parameters); break; 1053 case ThicknessAbsGradientEnum: this->ThicknessAbsGradientx(&double_result); break; 1054 case ThicknessAlongGradientEnum: ThicknessAlongGradientx(&double_result,elements,nodes,vertices,loads,materials,parameters); break; 1055 case ThicknessAcrossGradientEnum: ThicknessAcrossGradientx(&double_result,elements,nodes,vertices,loads,materials,parameters); break; 1056 case ThicknessPositiveEnum: this->ThicknessPositivex(&double_result); break; 1057 case RheologyBbarAbsGradientEnum: RheologyBbarAbsGradientx(&double_result,elements,nodes,vertices,loads,materials,parameters); break; 1058 case RheologyBAbsGradientEnum: RheologyBAbsGradientx(&double_result,elements,nodes,vertices,loads,materials,parameters); break; 1059 case DragCoefficientAbsGradientEnum:DragCoefficientAbsGradientx(&double_result,elements,nodes,vertices,loads,materials,parameters); break; 1060 case BalancethicknessMisfitEnum: BalancethicknessMisfitx(&double_result); break; 1061 case SurfaceAbsMisfitEnum: SurfaceAbsMisfitx(&double_result); break; 1062 1063 /*Vector */ 1064 default: 1065 1066 /*Vector layout*/ 1067 int interpolation,nodesperelement,size,nlines,ncols,array_size; 1068 int rank_interpolation=-1,rank_nodesperelement=-1,rank_arraysize=-1,max_rank_arraysize=0; 1069 bool isarray=false; 1070 1071 /*Get interpolation (and compute input if necessary)*/ 1072 for(int j=0;j<elements->Size();j++){ 1073 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(j)); 1074 element->ResultInterpolation(&rank_interpolation,&rank_nodesperelement,&rank_arraysize,output_enum); 1075 if (rank_arraysize>max_rank_arraysize)max_rank_arraysize=rank_arraysize; 1076 } 1077 rank_arraysize=max_rank_arraysize; 1078 1079 /*Broadcast for cpus that do not have any elements*/ 1080 ISSM_MPI_Reduce(&rank_interpolation,&interpolation,1,ISSM_MPI_INT,ISSM_MPI_MAX,0,IssmComm::GetComm()); 1081 ISSM_MPI_Reduce(&rank_nodesperelement,&nodesperelement,1,ISSM_MPI_INT,ISSM_MPI_MAX,0,IssmComm::GetComm()); 1082 ISSM_MPI_Reduce(&rank_arraysize,&array_size,1,ISSM_MPI_INT,ISSM_MPI_MAX,0,IssmComm::GetComm()); 1083 ISSM_MPI_Bcast(&interpolation,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 1084 ISSM_MPI_Bcast(&nodesperelement,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 1085 ISSM_MPI_Bcast(&array_size,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 1086 1087 if(results_on_nodes){ 1088 1089 /*Allocate matrices*/ 1090 int nbe = this->elements->NumberOfElements(); 1091 IssmDouble* values = xNewZeroInit<IssmDouble>(nbe*nodesperelement); 1092 IssmDouble* allvalues = xNew<IssmDouble>(nbe*nodesperelement); 1093 1094 /*Fill-in matrix*/ 1095 for(int j=0;j<elements->Size();j++){ 1096 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(j)); 1097 element->ResultToPatch(values,nodesperelement,output_enum); 1098 } 1099 1100 /*Gather from all cpus*/ 1101 ISSM_MPI_Allreduce((void*)values,(void*)allvalues,nbe*nodesperelement,ISSM_MPI_PDOUBLE,ISSM_MPI_SUM,IssmComm::GetComm()); 1102 xDelete<IssmDouble>(values); 1103 1104 if(save_results)results->AddResult(new GenericExternalResult<IssmDouble*>(results->Size()+1,output_enum,allvalues,nbe,nodesperelement,step,time)); 1105 xDelete<IssmDouble>(allvalues); 1106 1107 } 1108 else{ 1109 1110 /*Allocate vector depending on interpolation*/ 1111 switch(interpolation){ 1112 case P0Enum: isarray = false; size = this->elements->NumberOfElements(); break; 1113 case P1Enum: isarray = false; size = this->vertices->NumberOfVertices(); break; 1114 case P0ArrayEnum: isarray = true; nlines = this->elements->NumberOfElements(); ncols= array_size; break; 1115 default: _error_("Interpolation "<<EnumToStringx(interpolation)<<" not supported yet"); 1116 1117 } 1118 if (!isarray){ 1119 Vector<IssmDouble> *vector_result = new Vector<IssmDouble>(size); 1120 1121 /*Fill in vector*/ 1122 for(int j=0;j<elements->Size();j++){ 1123 Element* element=(Element*)elements->GetObjectByOffset(j); 1124 element->ResultToVector(vector_result,output_enum); 1125 } 1126 vector_result->Assemble(); 1127 1128 if(save_results)results->AddResult(new GenericExternalResult<Vector<IssmDouble>*>(results->Size()+1,output_enum,vector_result,step,time)); 1129 } 1130 else{ 1131 IssmDouble* values = xNewZeroInit<IssmDouble>(nlines*ncols); 1132 IssmDouble* allvalues = xNew<IssmDouble>(nlines*ncols); 1133 1134 /*Fill-in matrix*/ 1135 for(int j=0;j<elements->Size();j++){ 1136 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(j)); 1137 element->ResultToMatrix(values,ncols, output_enum); 1138 } 1139 /*Gather from all cpus*/ 1140 ISSM_MPI_Allreduce((void*)values,(void*)allvalues,ncols*nlines,ISSM_MPI_PDOUBLE,ISSM_MPI_SUM,IssmComm::GetComm()); 1141 xDelete<IssmDouble>(values); 1142 1143 if(save_results)results->AddResult(new GenericExternalResult<IssmDouble*>(results->Size()+1,output_enum,allvalues,nlines,ncols,step,time)); 1144 xDelete<IssmDouble>(allvalues); 1145 } 1146 } 1147 isvec = true; 1148 break; 1149 } 1150 } 1151 1152 } 1153 1154 /*Add result to Results*/ 1155 if(!isvec && save_results){ 1156 results->AddResult(new GenericExternalResult<IssmPDouble>(results->Size()+1,output_string,reCast<IssmPDouble>(double_result),step,time)); 1157 } 1158 } 1159 1160 /*Assign pointer and clean up*/ 1161 *presults = results; 1162 } 1163 /*}}}*/ 1164 void FemModel::RequestedOutputsx(Results **presults,int* requested_outputs, int numoutputs,bool save_results){/*{{{*/ 1165 1166 /*Convert list of enums to list of string*/ 1167 char** enumlist = xNew<char*>(numoutputs); 1168 for(int i=0;i<numoutputs;i++){ 1169 EnumToStringx(&enumlist[i],requested_outputs[i]); 1170 } 1171 1172 /*Call main module*/ 1173 this->RequestedOutputsx(presults,enumlist,numoutputs,save_results); 1174 1175 /*clean up and return*/ 1176 for(int i=0;i<numoutputs;i++) xDelete<char>(enumlist[i]); 1177 xDelete<char*>(enumlist); 1178 return; 1179 } 1180 /*}}}*/ 1181 void FemModel::RequestedDependentsx(void){/*{{{*/ 1182 1183 bool isautodiff = false; 1184 IssmDouble output_value; 1185 1186 int num_dependents; 1187 IssmPDouble *dependents; 1188 DataSet* dependent_objects=NULL; 1189 int my_rank=IssmComm::GetRank(); 1190 1191 /*AD mode on?: */ 1192 parameters->FindParam(&isautodiff,AutodiffIsautodiffEnum); 1193 1194 if(isautodiff){ 1195 #ifdef _HAVE_ADOLC_ 1196 parameters->FindParam(&num_dependents,AutodiffNumDependentsEnum); 1197 parameters->FindParam(&dependent_objects,AutodiffDependentObjectsEnum); 1198 if(num_dependents){ 1199 dependents=xNew<IssmPDouble>(num_dependents); 1200 1201 /*Go through our dependent variables, and compute the response:*/ 1202 for(int i=0;i<dependent_objects->Size();i++){ 1203 DependentObject* dep=(DependentObject*)dependent_objects->GetObjectByOffset(i); 1204 dep->Responsex(&output_value,this); 1205 if (my_rank==0) { 1206 output_value>>=dependents[i]; 1207 } 1208 } 1209 } 1210 delete dependent_objects; 1211 if(num_dependents)xDelete<IssmPDouble>(dependents); 1212 #else 1213 _error_("Should not be requesting dependents when an AD library is not available!"); 1214 #endif 1215 } 1216 } 1217 /*}}}*/ 1218 void FemModel::TimeAdaptx(IssmDouble* pdt){/*{{{*/ 1219 1220 int i; 1221 1222 /*output: */ 1223 IssmDouble dt; 1224 1225 /*intermediary: */ 1226 Element *element = NULL; 1227 IssmDouble min_dt = 0; 1228 IssmDouble node_min_dt = 0; 1229 1230 /*Go through elements, and figure out the minimum of the time steps for each element (using CFL criterion): */ 1231 element=(Element*)elements->GetObjectByOffset(0); min_dt=element->TimeAdapt(); 1232 1233 for (i=1;i<elements->Size();i++){ 1234 element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 1235 dt=element->TimeAdapt(); 1236 if(dt<min_dt)min_dt=dt; 1237 } 1238 1239 /*Figure out minimum across the cluster: */ 1240 ISSM_MPI_Reduce (&min_dt,&node_min_dt,1,ISSM_MPI_DOUBLE,ISSM_MPI_MIN,0,IssmComm::GetComm() ); 1241 ISSM_MPI_Bcast(&node_min_dt,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1242 min_dt=node_min_dt; 1243 1244 /*Assign output pointers:*/ 1245 *pdt=min_dt; 1246 } 1247 /*}}}*/ 1248 void FemModel::UpdateConstraintsExtrudeFromBasex(void){ /*{{{*/ 1837 void FemModel::StrainRateparallelx(){/*{{{*/ 1249 1838 1250 1839 for(int i=0;i<elements->Size();i++){ 1251 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 1252 element->UpdateConstraintsExtrudeFromBase(); 1253 } 1254 1255 } 1256 /*}}}*/ 1257 void FemModel::UpdateConstraintsExtrudeFromTopx(void){ /*{{{*/ 1840 Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i)); 1841 element->StrainRateparallel(); 1842 } 1843 } 1844 /*}}}*/ 1845 void FemModel::StrainRateperpendicularx(){/*{{{*/ 1258 1846 1259 1847 for(int i=0;i<elements->Size();i++){ 1260 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 1261 element->UpdateConstraintsExtrudeFromTop(); 1262 } 1263 1264 } 1265 /*}}}*/ 1266 void FemModel::MassFluxx(IssmDouble* pmass_flux){/*{{{*/ 1267 1268 int i,j; 1269 Element *element = NULL; 1270 int element_id; 1271 bool ispresent = false; 1272 IssmDouble mass_flux = 0; 1273 IssmDouble all_mass_flux = 0; 1274 int counter; 1275 IssmDouble **array = NULL; 1276 int M; 1277 int *mdims_array = NULL; 1278 int *ndims_array = NULL; 1279 IssmDouble *segments = NULL; 1280 int num_segments; 1281 1282 /*First, figure out which segment to compute our mass flux on. Start with retrieving qmu_mass_flux_segments: */ 1283 this->parameters->FindParam(&ispresent,MassFluxSegmentsPresentEnum); 1284 if(!ispresent)_error_("no mass flux segments available!"); 1285 this->parameters->FindParam(&array,&M,&mdims_array,&ndims_array,MassFluxSegmentsEnum); 1286 1287 /*Retrieve index of segments being used for MassFlux computation: */ 1288 parameters->FindParam(&counter,IndexEnum); 1289 1290 /*retrieve segments from array: */ 1291 segments = array[counter-1]; //matlab to "C" indexing 1292 num_segments = mdims_array[counter-1]; 1293 1294 /*Go through segments, and then elements, and figure out which elements belong to a segment. 1295 * When we find one, use the element to compute the mass flux on the segment: */ 1296 for(i=0;i<num_segments;i++){ 1297 element_id=reCast<int,IssmDouble>(*(segments+5*i+4)); 1298 for(j=0;j<elements->Size();j++){ 1299 element=(Element*)this->elements->GetObjectByOffset(j); 1300 if (element->Id()==element_id){ 1301 /*We found the element which owns this segment, use it to compute the mass flux: */ 1302 mass_flux+=element->MassFlux(segments+5*i+0); 1303 break; 1304 } 1305 } 1306 } 1307 1308 ISSM_MPI_Allreduce ( (void*)&mass_flux,(void*)&all_mass_flux,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,IssmComm::GetComm()); 1309 mass_flux=all_mass_flux; 1310 1311 /*Free ressources:*/ 1312 for(i=0;i<M;i++){ 1313 IssmDouble* matrix=array[i]; 1314 xDelete<IssmDouble>(matrix); 1315 } 1316 xDelete<int>(mdims_array); 1317 xDelete<int>(ndims_array); 1318 xDelete<IssmDouble*>(array); 1319 1320 /*Assign output pointers: */ 1321 *pmass_flux=mass_flux; 1322 1323 }/*}}}*/ 1324 void FemModel::MaxAbsVxx(IssmDouble* pmaxabsvx){/*{{{*/ 1325 1326 int i; 1327 IssmDouble maxabsvx; 1328 IssmDouble node_maxabsvx; 1329 IssmDouble element_maxabsvx; 1330 1331 /*Go through elements, and request velocity: */ 1332 maxabsvx=-INFINITY; 1333 for(i=0;i<this->elements->Size();i++){ 1334 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1335 element_maxabsvx=element->inputs->MaxAbs(VxEnum); 1336 if(element_maxabsvx>maxabsvx) maxabsvx=element_maxabsvx; 1337 } 1338 1339 /*Figure out maximum across the cluster: */ 1340 ISSM_MPI_Reduce(&maxabsvx,&node_maxabsvx,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1341 ISSM_MPI_Bcast(&node_maxabsvx,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1342 maxabsvx=node_maxabsvx; 1343 1344 /*Assign output pointers:*/ 1345 *pmaxabsvx=maxabsvx; 1346 1347 }/*}}}*/ 1348 void FemModel::MaxAbsVyx(IssmDouble* pmaxabsvy){/*{{{*/ 1349 1350 int i; 1351 IssmDouble maxabsvy; 1352 IssmDouble node_maxabsvy; 1353 IssmDouble element_maxabsvy; 1354 1355 /*Go through elements, and request velocity: */ 1356 maxabsvy=-INFINITY; 1357 for(i=0;i<this->elements->Size();i++){ 1358 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1359 element_maxabsvy=element->inputs->MaxAbs(VyEnum); 1360 if(element_maxabsvy>maxabsvy) maxabsvy=element_maxabsvy; 1361 } 1362 1363 /*Figure out maximum across the cluster: */ 1364 ISSM_MPI_Reduce(&maxabsvy,&node_maxabsvy,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1365 ISSM_MPI_Bcast(&node_maxabsvy,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1366 maxabsvy=node_maxabsvy; 1367 1368 /*Assign output pointers:*/ 1369 *pmaxabsvy=maxabsvy; 1370 1371 }/*}}}*/ 1372 void FemModel::MaxAbsVzx(IssmDouble* pmaxabsvz){/*{{{*/ 1373 1374 int i; 1375 IssmDouble maxabsvz; 1376 IssmDouble node_maxabsvz; 1377 IssmDouble element_maxabsvz; 1378 1379 /*Go through elements, and request velocity: */ 1380 maxabsvz=-INFINITY; 1381 for(i=0;i<this->elements->Size();i++){ 1382 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1383 element_maxabsvz=element->inputs->MaxAbs(VzEnum); 1384 if(element_maxabsvz>maxabsvz) maxabsvz=element_maxabsvz; 1385 } 1386 1387 /*Figure out maximum across the cluster: */ 1388 ISSM_MPI_Reduce(&maxabsvz,&node_maxabsvz,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1389 ISSM_MPI_Bcast(&node_maxabsvz,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1390 maxabsvz=node_maxabsvz; 1391 1392 /*Assign output pointers:*/ 1393 *pmaxabsvz=maxabsvz; 1394 1395 }/*}}}*/ 1396 void FemModel::MaxVelx(IssmDouble* pmaxvel){/*{{{*/ 1397 1398 int i; 1399 IssmDouble maxvel; 1400 IssmDouble node_maxvel; 1401 IssmDouble element_maxvel; 1402 1403 /*Go through elements, and request velocity: */ 1404 maxvel=-INFINITY; 1405 for(i=0;i<this->elements->Size();i++){ 1406 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1407 element_maxvel = element->inputs->Max(VelEnum); 1408 if(element_maxvel>maxvel) maxvel=element_maxvel; 1409 } 1410 1411 /*Figure out maximum across the cluster: */ 1412 ISSM_MPI_Reduce(&maxvel,&node_maxvel,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1413 ISSM_MPI_Bcast(&node_maxvel,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1414 maxvel=node_maxvel; 1415 1416 /*Assign output pointers:*/ 1417 *pmaxvel=maxvel; 1418 1419 }/*}}}*/ 1420 void FemModel::MaxVxx(IssmDouble* pmaxvx){/*{{{*/ 1421 1422 int i; 1423 IssmDouble maxvx; 1424 IssmDouble node_maxvx; 1425 IssmDouble element_maxvx; 1426 1427 /*Go through elements, and request velocity: */ 1428 maxvx=-INFINITY; 1429 for(i=0;i<this->elements->Size();i++){ 1430 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1431 element_maxvx = element->inputs->Max(VxEnum); 1432 if(element_maxvx>maxvx) maxvx=element_maxvx; 1433 } 1434 1435 /*Figure out maximum across the cluster: */ 1436 ISSM_MPI_Reduce(&maxvx,&node_maxvx,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1437 ISSM_MPI_Bcast(&node_maxvx,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1438 maxvx=node_maxvx; 1439 1440 /*Assign output pointers:*/ 1441 *pmaxvx=maxvx; 1442 1443 }/*}}}*/ 1444 void FemModel::MaxVyx(IssmDouble* pmaxvy){/*{{{*/ 1445 1446 int i; 1447 IssmDouble maxvy; 1448 IssmDouble node_maxvy; 1449 IssmDouble element_maxvy; 1450 1451 /*Go through elements, and request velocity: */ 1452 maxvy=-INFINITY; 1453 for(i=0;i<this->elements->Size();i++){ 1454 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1455 element_maxvy = element->inputs->Max(VyEnum); 1456 if(element_maxvy>maxvy) maxvy=element_maxvy; 1457 } 1458 1459 /*Figure out maximum across the cluster: */ 1460 ISSM_MPI_Reduce(&maxvy,&node_maxvy,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1461 ISSM_MPI_Bcast(&node_maxvy,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1462 maxvy=node_maxvy; 1463 1464 /*Assign output pointers:*/ 1465 *pmaxvy=maxvy; 1466 1467 }/*}}}*/ 1468 void FemModel::MaxVzx(IssmDouble* pmaxvz){/*{{{*/ 1469 1470 int i; 1471 IssmDouble maxvz; 1472 IssmDouble node_maxvz; 1473 IssmDouble element_maxvz; 1474 1475 /*Go through elements, and request velocity: */ 1476 maxvz=-INFINITY; 1477 for(i=0;i<this->elements->Size();i++){ 1478 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1479 element_maxvz = element->inputs->Max(VzEnum); 1480 if(element_maxvz>maxvz) maxvz=element_maxvz; 1481 } 1482 1483 /*Figure out maximum across the cluster: */ 1484 ISSM_MPI_Reduce(&maxvz,&node_maxvz,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1485 ISSM_MPI_Bcast(&node_maxvz,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1486 maxvz=node_maxvz; 1487 1488 /*Assign output pointers:*/ 1489 *pmaxvz=maxvz; 1490 1491 }/*}}}*/ 1492 void FemModel::MinVelx(IssmDouble* pminvel){/*{{{*/ 1493 1494 int i; 1495 IssmDouble minvel; 1496 IssmDouble node_minvel; 1497 IssmDouble element_minvel; 1498 1499 /*Go through elements, and request velocity: */ 1500 minvel=INFINITY; 1501 for(i=0;i<this->elements->Size();i++){ 1502 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1503 element_minvel = element->inputs->Min(VelEnum); 1504 if(element_minvel<minvel) minvel=element_minvel; 1505 } 1506 1507 /*Figure out minimum across the cluster: */ 1508 ISSM_MPI_Reduce(&minvel,&node_minvel,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1509 ISSM_MPI_Bcast(&node_minvel,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1510 minvel=node_minvel; 1511 1512 /*Assign output pointers:*/ 1513 *pminvel=minvel; 1514 1515 }/*}}}*/ 1516 void FemModel::MinVxx(IssmDouble* pminvx){/*{{{*/ 1517 1518 int i; 1519 IssmDouble minvx; 1520 IssmDouble node_minvx; 1521 IssmDouble element_minvx; 1522 1523 /*Go through elements, and request velocity: */ 1524 minvx=INFINITY; 1525 for(i=0;i<this->elements->Size();i++){ 1526 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1527 element_minvx = element->inputs->Min(VxEnum); 1528 if(element_minvx<minvx) minvx=element_minvx; 1529 } 1530 1531 /*Figure out minimum across the cluster: */ 1532 ISSM_MPI_Reduce(&minvx,&node_minvx,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1533 ISSM_MPI_Bcast(&node_minvx,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1534 minvx=node_minvx; 1535 1536 /*Assign output pointers:*/ 1537 *pminvx=minvx; 1538 1539 }/*}}}*/ 1540 void FemModel::MinVyx(IssmDouble* pminvy){/*{{{*/ 1541 1542 int i; 1543 IssmDouble minvy; 1544 IssmDouble node_minvy; 1545 IssmDouble element_minvy; 1546 1547 /*Go through elements, and request velocity: */ 1548 minvy=INFINITY; 1549 for(i=0;i<this->elements->Size();i++){ 1550 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1551 element_minvy = element->inputs->Min(VyEnum); 1552 if(element_minvy<minvy) minvy=element_minvy; 1553 } 1554 1555 /*Figure out minimum across the cluster: */ 1556 ISSM_MPI_Reduce(&minvy,&node_minvy,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1557 ISSM_MPI_Bcast(&node_minvy,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1558 minvy=node_minvy; 1559 1560 /*Assign output pointers:*/ 1561 *pminvy=minvy; 1562 1563 }/*}}}*/ 1564 void FemModel::MinVzx(IssmDouble* pminvz){/*{{{*/ 1565 1566 int i; 1567 IssmDouble minvz; 1568 IssmDouble node_minvz; 1569 IssmDouble element_minvz; 1570 1571 /*Go through elements, and request velocity: */ 1572 minvz=INFINITY; 1573 for(i=0;i<this->elements->Size();i++){ 1574 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1575 element_minvz = element->inputs->Min(VzEnum); 1576 if(element_minvz<minvz) minvz=element_minvz; 1577 } 1578 1579 /*Figure out minimum across the cluster: */ 1580 ISSM_MPI_Reduce(&minvz,&node_minvz,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1581 ISSM_MPI_Bcast(&node_minvz,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1582 minvz=node_minvz; 1583 1584 /*Assign output pointers:*/ 1585 *pminvz=minvz; 1586 1587 }/*}}}*/ 1588 void FemModel::TotalFloatingBmbx(IssmDouble* pFbmb){/*{{{*/ 1589 1590 IssmDouble local_fbmb = 0; 1591 IssmDouble total_fbmb; 1592 1593 for(int i=0;i<this->elements->Size();i++){ 1594 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1595 local_fbmb+=element->TotalFloatingBmb(); 1596 } 1597 ISSM_MPI_Reduce(&local_fbmb,&total_fbmb,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 1598 ISSM_MPI_Bcast(&total_fbmb,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1599 1600 /*Assign output pointers: */ 1601 *pFbmb=total_fbmb; 1602 1603 }/*}}}*/ 1604 void FemModel::TotalGroundedBmbx(IssmDouble* pGbmb){/*{{{*/ 1605 1606 IssmDouble local_gbmb = 0; 1607 IssmDouble total_gbmb; 1608 1609 for(int i=0;i<this->elements->Size();i++){ 1610 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1611 local_gbmb+=element->TotalGroundedBmb(); 1612 } 1613 ISSM_MPI_Reduce(&local_gbmb,&total_gbmb,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 1614 ISSM_MPI_Bcast(&total_gbmb,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1615 1616 /*Assign output pointers: */ 1617 *pGbmb=total_gbmb; 1618 1619 }/*}}}*/ 1620 void FemModel::TotalSmbx(IssmDouble* pSmb){/*{{{*/ 1621 1622 IssmDouble local_smb = 0; 1623 IssmDouble total_smb; 1624 1625 for(int i=0;i<this->elements->Size();i++){ 1626 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1627 local_smb+=element->TotalSmb(); 1628 } 1629 ISSM_MPI_Reduce(&local_smb,&total_smb,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 1630 ISSM_MPI_Bcast(&total_smb,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1631 1632 /*Assign output pointers: */ 1633 *pSmb=total_smb; 1634 1635 }/*}}}*/ 1636 void FemModel::Divergencex(IssmDouble* pdiv){/*{{{*/ 1637 1638 IssmDouble local_divergence=0; 1639 IssmDouble total_divergence; 1640 1641 for(int i=0;i<this->elements->Size();i++){ 1642 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1643 local_divergence+=element->Divergence(); 1644 } 1645 ISSM_MPI_Reduce(&local_divergence,&total_divergence,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 1646 ISSM_MPI_Bcast(&total_divergence,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1647 1648 /*Assign output pointers: */ 1649 *pdiv=total_divergence; 1650 1651 }/*}}}*/ 1652 void FemModel::MaxDivergencex(IssmDouble* pdiv){/*{{{*/ 1653 1654 IssmDouble local_divergence; 1655 IssmDouble node_max_divergence; 1656 IssmDouble max_divergence = -INFINITY; 1657 1658 for(int i=0;i<this->elements->Size();i++){ 1659 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1660 local_divergence=element->Divergence(); 1661 if(fabs(local_divergence)>max_divergence) max_divergence=fabs(local_divergence); 1662 } 1663 ISSM_MPI_Reduce(&max_divergence,&node_max_divergence,1,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,0,IssmComm::GetComm() ); 1664 ISSM_MPI_Bcast(&node_max_divergence,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1665 max_divergence=node_max_divergence; 1666 1667 /*Assign output pointers: */ 1668 *pdiv=max_divergence; 1669 1670 }/*}}}*/ 1671 void FemModel::FloatingAreax(IssmDouble* pV){/*{{{*/ 1672 1673 IssmDouble local_floating_area= 0; 1674 IssmDouble total_floating_area; 1675 1676 for(int i=0;i<this->elements->Size();i++){ 1677 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1678 local_floating_area+=element->FloatingArea(); 1679 } 1680 ISSM_MPI_Reduce(&local_floating_area,&total_floating_area,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 1681 ISSM_MPI_Bcast(&total_floating_area,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1682 1683 /*Assign output pointers: */ 1684 *pV=total_floating_area; 1685 1686 }/*}}}*/ 1687 void FemModel::GetInputLocalMinMaxOnNodesx(IssmDouble** pmin,IssmDouble** pmax,IssmDouble* ug){/*{{{*/ 1688 1689 /*Get vector sizes for current configuration*/ 1690 int configuration_type; 1691 this->parameters->FindParam(&configuration_type,ConfigurationTypeEnum); 1692 int numnodes = this->nodes->NumberOfNodes(configuration_type); 1693 1694 /*Initialize output vectors*/ 1695 IssmDouble* uLmin_local = xNew<IssmDouble>(numnodes); 1696 IssmDouble* uLmax_local = xNew<IssmDouble>(numnodes); 1697 IssmDouble* uLmin = xNew<IssmDouble>(numnodes); 1698 IssmDouble* uLmax = xNew<IssmDouble>(numnodes); 1699 for(int i=0;i<numnodes;i++){ 1700 uLmin_local[i] = +1.e+50; 1701 uLmax_local[i] = -1.e+50; 1702 } 1703 1704 for(int i=0;i<this->elements->Size();i++){ 1705 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1706 element->GetInputLocalMinMaxOnNodes(uLmin_local,uLmax_local,ug); 1707 } 1708 1709 /*Synchronize all CPUs*/ 1710 ISSM_MPI_Allreduce((void*)uLmin_local,(void*)uLmin,numnodes,ISSM_MPI_DOUBLE,ISSM_MPI_MIN,IssmComm::GetComm()); 1711 ISSM_MPI_Allreduce((void*)uLmax_local,(void*)uLmax,numnodes,ISSM_MPI_DOUBLE,ISSM_MPI_MAX,IssmComm::GetComm()); 1712 xDelete<IssmDouble>(uLmin_local); 1713 xDelete<IssmDouble>(uLmax_local); 1714 1715 /*Assign output pointers: */ 1716 *pmin=uLmin; 1717 *pmax=uLmax; 1718 1719 }/*}}}*/ 1720 void FemModel::GroundedAreax(IssmDouble* pV){/*{{{*/ 1721 1722 IssmDouble local_grounded_area= 0; 1723 IssmDouble total_grounded_area; 1724 1725 for(int i=0;i<this->elements->Size();i++){ 1726 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1727 local_grounded_area+=element->GroundedArea(); 1728 } 1729 ISSM_MPI_Reduce(&local_grounded_area,&total_grounded_area,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 1730 ISSM_MPI_Bcast(&total_grounded_area,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1731 1732 /*Assign output pointers: */ 1733 *pV=total_grounded_area; 1734 1735 }/*}}}*/ 1736 void FemModel::IceMassx(IssmDouble* pM){/*{{{*/ 1737 1738 IssmDouble local_ice_mass = 0; 1739 IssmDouble total_ice_mass; 1740 1741 for(int i=0;i<this->elements->Size();i++){ 1742 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1743 local_ice_mass+=element->IceMass(); 1744 } 1745 ISSM_MPI_Reduce(&local_ice_mass,&total_ice_mass,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 1746 ISSM_MPI_Bcast(&total_ice_mass,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1747 1748 /*Assign output pointers: */ 1749 *pM=total_ice_mass; 1750 1751 }/*}}}*/ 1752 void FemModel::IceVolumex(IssmDouble* pV){/*{{{*/ 1753 1754 IssmDouble local_ice_volume = 0; 1755 IssmDouble total_ice_volume; 1756 1757 for(int i=0;i<this->elements->Size();i++){ 1758 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1759 local_ice_volume+=element->IceVolume(); 1760 } 1761 ISSM_MPI_Reduce(&local_ice_volume,&total_ice_volume,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 1762 ISSM_MPI_Bcast(&total_ice_volume,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1763 1764 /*Assign output pointers: */ 1765 *pV=total_ice_volume; 1766 1767 }/*}}}*/ 1768 void FemModel::IceVolumeAboveFloatationx(IssmDouble* pV){/*{{{*/ 1769 1770 IssmDouble local_ice_volume_af = 0; 1771 IssmDouble total_ice_volume_af; 1772 1773 for(int i=0;i<this->elements->Size();i++){ 1774 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1775 local_ice_volume_af+=element->IceVolumeAboveFloatation(); 1776 } 1777 ISSM_MPI_Reduce(&local_ice_volume_af,&total_ice_volume_af,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 1778 ISSM_MPI_Bcast(&total_ice_volume_af,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1779 1780 /*Assign output pointers: */ 1781 *pV=total_ice_volume_af; 1782 1783 }/*}}}*/ 1784 void FemModel::ElementResponsex(IssmDouble* presponse,int response_enum){/*{{{*/ 1785 1786 int found=0; 1787 int sumfound=0; 1788 int cpu_found=-1; 1789 int index; 1790 IssmDouble response; 1791 Element* element=NULL; 1792 1793 /*retrieve element we are interested in: */ 1794 this->parameters->FindParam(&index,IndexEnum); 1795 int my_rank=IssmComm::GetRank(); 1796 1797 /*now, go through our elements, and retrieve the one with this id: index: */ 1798 for(int i=0;i<this->elements->Size();i++){ 1799 element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 1800 if (element->Id()==index){ 1801 found=1; 1802 cpu_found=my_rank; 1803 break; 1804 } 1805 } 1806 1807 /*Broadcast whether we found the element: */ 1808 ISSM_MPI_Allreduce ( &found,&sumfound,1,ISSM_MPI_INT,ISSM_MPI_SUM,IssmComm::GetComm()); 1809 if(!sumfound)_error_("could not find material with id" << index << " to compute ElementResponse"); 1810 1811 /*Ok, we found the element, compute responseocity: */ 1812 if(my_rank==cpu_found){ 1813 element->ElementResponse(&response,response_enum); 1814 } 1815 1816 /*Broadcast and plug into response: */ 1817 ISSM_MPI_Allreduce ( &cpu_found,&cpu_found,1,ISSM_MPI_INT,ISSM_MPI_MAX,IssmComm::GetComm()); 1818 ISSM_MPI_Bcast(&response,1,ISSM_MPI_DOUBLE,cpu_found,IssmComm::GetComm()); 1819 1820 /*Assign output pointers: */ 1821 *presponse=response; 1822 1823 }/*}}}*/ 1824 void FemModel::BalancethicknessMisfitx(IssmDouble* presponse){/*{{{*/ 1825 1826 /*output: */ 1827 IssmDouble J=0.; 1828 IssmDouble J_sum; 1829 1830 IssmDouble weight,vx,vy,H,dvx[2],dvy[2],dH[2]; 1831 IssmDouble temp,Jdet,dhdt,groundedice_melting,surface_mass_balance; 1832 IssmDouble* xyz_list = NULL; 1833 IssmDouble dp[3]; 1834 1835 /*Compute Misfit: */ 1848 Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i)); 1849 element->StrainRateperpendicular(); 1850 } 1851 } 1852 /*}}}*/ 1853 void FemModel::StressIntensityFactorx(){/*{{{*/ 1854 1855 /*Update input for basal element only*/ 1836 1856 for(int i=0;i<elements->Size();i++){ 1837 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 1838 1839 /*If on water, return 0: */ 1840 if(!element->IsIceInElement()) continue; 1841 1842 /* Get node coordinates*/ 1843 element->GetVerticesCoordinates(&xyz_list); 1844 Input* weights_input = element->GetInput(InversionCostFunctionsCoefficientsEnum); _assert_(weights_input); 1845 Input* thickness_input = element->GetInput(ThicknessEnum); _assert_(thickness_input); 1846 Input* vx_input = element->GetInput(VxEnum); _assert_(vx_input); 1847 Input* vy_input = element->GetInput(VyEnum); _assert_(vy_input); 1848 Input* surface_mass_balance_input = element->GetInput(SmbMassBalanceEnum); _assert_(surface_mass_balance_input); 1849 Input* groundedice_melting_input = element->GetInput(BasalforcingsGroundediceMeltingRateEnum); _assert_(groundedice_melting_input); 1850 Input* dhdt_input = element->GetInput(BalancethicknessThickeningRateEnum); _assert_(dhdt_input); 1851 1852 /* Start looping on the number of gaussian points: */ 1853 Gauss* gauss=element->NewGauss(2); 1854 for(int ig=gauss->begin();ig<gauss->end();ig++){ 1855 1856 gauss->GaussPoint(ig); 1857 1858 /* Get Jacobian determinant: */ 1859 element->JacobianDeterminant(&Jdet,xyz_list,gauss); 1860 1861 /*Get all parameters at gaussian point*/ 1862 weights_input->GetInputValue(&weight,gauss,BalancethicknessMisfitEnum); 1863 thickness_input->GetInputValue(&H, gauss); 1864 thickness_input->GetInputDerivativeValue(&dH[0],xyz_list,gauss); 1865 surface_mass_balance_input->GetInputValue(&surface_mass_balance,gauss); 1866 groundedice_melting_input->GetInputValue(&groundedice_melting,gauss); 1867 dhdt_input->GetInputValue(&dhdt,gauss); 1868 vx_input->GetInputValue(&vx,gauss); 1869 vx_input->GetInputDerivativeValue(&dvx[0],xyz_list,gauss); 1870 vy_input->GetInputValue(&vy,gauss); 1871 vy_input->GetInputDerivativeValue(&dvy[0],xyz_list,gauss); 1872 1873 /*Balance thickness soft constraint J = 1/2 (div(Hv)-a)^2*/ 1874 temp = vx*dH[0]+vy*dH[1]+H*(dvx[0]+dvy[1]) - (surface_mass_balance-groundedice_melting-dhdt); 1875 J +=weight*1/2*temp*temp*Jdet*gauss->weight; 1876 } 1877 1878 /*clean up and Return: */ 1879 xDelete<IssmDouble>(xyz_list); 1880 delete gauss; 1881 } 1882 1883 /*Sum all J from all cpus of the cluster:*/ 1884 ISSM_MPI_Reduce (&J,&J_sum,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 1885 ISSM_MPI_Bcast(&J_sum,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1886 J=J_sum; 1887 1888 /*Assign output pointers: */ 1889 *presponse=J; 1890 1891 }/*}}}*/ 1857 Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i)); 1858 element->StressIntensityFactor(); 1859 } 1860 } 1861 /*}}}*/ 1892 1862 void FemModel::SurfaceAbsMisfitx(IssmDouble* presponse){/*{{{*/ 1893 1863 … … 2059 2029 } 2060 2030 /*}}}*/ 2061 void FemModel::CostFunctionx(IssmDouble* pJ,IssmDouble** pJlist,int* pn){/*{{{*/ 2062 2063 /*Intermediary*/ 2064 int num_responses; 2065 int *responses = NULL; 2066 Results *cost_functions = NULL; 2067 2068 /*Recover parameters*/ 2069 parameters->FindParam(&num_responses,InversionNumCostFunctionsEnum); 2070 parameters->FindParam(&responses,NULL,InversionCostFunctionsEnum); 2071 2072 /*Get the value of all cost functions*/ 2073 this->RequestedOutputsx(&cost_functions,responses,num_responses); 2074 2075 /*Get and add all contributions one by one*/ 2076 IssmDouble J=0; 2077 IssmDouble* Jlist = xNew<IssmDouble>(num_responses); 2078 for(int i=0;i<num_responses;i++){ 2079 ExternalResult* result=(ExternalResult*)cost_functions->GetObjectByOffset(i); 2080 Jlist[i] = reCast<IssmDouble>(result->GetValue()); 2081 J += Jlist[i]; 2082 } 2083 _assert_(cost_functions->Size()==num_responses); 2031 void FemModel::TimeAdaptx(IssmDouble* pdt){/*{{{*/ 2032 2033 int i; 2034 2035 /*output: */ 2036 IssmDouble dt; 2037 2038 /*intermediary: */ 2039 Element *element = NULL; 2040 IssmDouble min_dt = 0; 2041 IssmDouble node_min_dt = 0; 2042 2043 /*Go through elements, and figure out the minimum of the time steps for each element (using CFL criterion): */ 2044 element=(Element*)elements->GetObjectByOffset(0); min_dt=element->TimeAdapt(); 2045 2046 for (i=1;i<elements->Size();i++){ 2047 element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 2048 dt=element->TimeAdapt(); 2049 if(dt<min_dt)min_dt=dt; 2050 } 2051 2052 /*Figure out minimum across the cluster: */ 2053 ISSM_MPI_Reduce (&min_dt,&node_min_dt,1,ISSM_MPI_DOUBLE,ISSM_MPI_MIN,0,IssmComm::GetComm() ); 2054 ISSM_MPI_Bcast(&node_min_dt,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 2055 min_dt=node_min_dt; 2056 2057 /*Assign output pointers:*/ 2058 *pdt=min_dt; 2059 } 2060 /*}}}*/ 2061 void FemModel::TotalFloatingBmbx(IssmDouble* pFbmb){/*{{{*/ 2062 2063 IssmDouble local_fbmb = 0; 2064 IssmDouble total_fbmb; 2065 2066 for(int i=0;i<this->elements->Size();i++){ 2067 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 2068 local_fbmb+=element->TotalFloatingBmb(); 2069 } 2070 ISSM_MPI_Reduce(&local_fbmb,&total_fbmb,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 2071 ISSM_MPI_Bcast(&total_fbmb,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 2084 2072 2085 2073 /*Assign output pointers: */ 2086 delete cost_functions; 2087 xDelete<int>(responses); 2088 if(pJ) *pJ = J; 2089 if(pJlist) *pJlist = Jlist; 2090 else xDelete<IssmDouble>(Jlist); 2091 if(pn) *pn = num_responses; 2092 } 2093 /*}}}*/ 2094 void FemModel::OutputControlsx(Results **presults){/*{{{*/ 2095 2096 /*parameters: */ 2097 int num_controls,step; 2098 IssmDouble time; 2099 int *control_type = NULL; 2100 2101 /*recover results*/ 2102 Results* results = *presults; 2103 if(!results) results = new Results(); 2104 2105 /*Get list of Controls*/ 2106 this->parameters->FindParam(&num_controls,InversionNumControlParametersEnum); 2107 this->parameters->FindParam(&control_type,NULL,InversionControlParametersEnum); 2108 this->parameters->FindParam(&step,StepEnum); 2109 this->parameters->FindParam(&time,TimeEnum); 2110 2111 for(int i=0;i<num_controls;i++){ 2112 2113 int control_enum = control_type[i]; 2114 int gradient_enum; 2115 2116 switch(i){ 2117 case 0: gradient_enum = Gradient1Enum; break; 2118 case 1: gradient_enum = Gradient2Enum; break; 2119 case 2: gradient_enum = Gradient3Enum; break; 2120 default: _error_("more than 3 controls not implemented yet"); 2121 } 2122 2123 /*Allocate vector*/ 2124 Vector<IssmPDouble> *vector_control = new Vector<IssmPDouble>(this->vertices->NumberOfVertices()); 2125 Vector<IssmPDouble> *vector_gradient = new Vector<IssmPDouble>(this->vertices->NumberOfVertices()); 2126 2127 /*Fill in vector*/ 2128 for(int j=0;j<elements->Size();j++){ 2129 Element* element=(Element*)elements->GetObjectByOffset(j); 2130 element->ControlToVectors(vector_control,vector_gradient,control_enum); 2131 } 2132 vector_control->Assemble(); 2133 vector_gradient->Assemble(); 2134 2135 results->AddResult(new GenericExternalResult<Vector<IssmPDouble>*>(results->Size()+1,control_enum,vector_control ,step,time)); 2136 results->AddResult(new GenericExternalResult<Vector<IssmPDouble>*>(results->Size()+1,gradient_enum,vector_gradient,step,time)); 2137 } 2138 2139 /*Clean up and return*/ 2140 xDelete<int>(control_type); 2141 } 2142 /*}}}*/ 2143 void FemModel::StressIntensityFactorx(){/*{{{*/ 2144 2145 /*Update input for basal element only*/ 2074 *pFbmb=total_fbmb; 2075 2076 }/*}}}*/ 2077 void FemModel::TotalGroundedBmbx(IssmDouble* pGbmb){/*{{{*/ 2078 2079 IssmDouble local_gbmb = 0; 2080 IssmDouble total_gbmb; 2081 2082 for(int i=0;i<this->elements->Size();i++){ 2083 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 2084 local_gbmb+=element->TotalGroundedBmb(); 2085 } 2086 ISSM_MPI_Reduce(&local_gbmb,&total_gbmb,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 2087 ISSM_MPI_Bcast(&total_gbmb,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 2088 2089 /*Assign output pointers: */ 2090 *pGbmb=total_gbmb; 2091 2092 }/*}}}*/ 2093 void FemModel::TotalSmbx(IssmDouble* pSmb){/*{{{*/ 2094 2095 IssmDouble local_smb = 0; 2096 IssmDouble total_smb; 2097 2098 for(int i=0;i<this->elements->Size();i++){ 2099 Element* element=xDynamicCast<Element*>(this->elements->GetObjectByOffset(i)); 2100 local_smb+=element->TotalSmb(); 2101 } 2102 ISSM_MPI_Reduce(&local_smb,&total_smb,1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() ); 2103 ISSM_MPI_Bcast(&total_smb,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 2104 2105 /*Assign output pointers: */ 2106 *pSmb=total_smb; 2107 2108 }/*}}}*/ 2109 void FemModel::UpdateConstraintsExtrudeFromBasex(void){ /*{{{*/ 2110 2146 2111 for(int i=0;i<elements->Size();i++){ 2147 Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i)); 2148 element->StressIntensityFactor(); 2149 } 2150 } 2151 /*}}}*/ 2152 void FemModel::CalvingRateLevermannx(){/*{{{*/ 2112 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 2113 element->UpdateConstraintsExtrudeFromBase(); 2114 } 2115 2116 } 2117 /*}}}*/ 2118 void FemModel::UpdateConstraintsExtrudeFromTopx(void){ /*{{{*/ 2153 2119 2154 2120 for(int i=0;i<elements->Size();i++){ 2155 Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i)); 2156 element->CalvingRateLevermann(); 2157 } 2158 } 2159 /*}}}*/ 2160 void FemModel::CalvingRateDevx(){/*{{{*/ 2161 2162 for(int i=0;i<elements->Size();i++){ 2163 Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i)); 2164 element->CalvingRateDev(); 2165 } 2166 } 2167 /*}}}*/ 2168 void FemModel::StrainRateparallelx(){/*{{{*/ 2169 2170 for(int i=0;i<elements->Size();i++){ 2171 Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i)); 2172 element->StrainRateparallel(); 2173 } 2174 } 2175 /*}}}*/ 2176 void FemModel::StrainRateperpendicularx(){/*{{{*/ 2177 2178 for(int i=0;i<elements->Size();i++){ 2179 Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i)); 2180 element->StrainRateperpendicular(); 2181 } 2182 } 2183 /*}}}*/ 2184 void FemModel::DeviatoricStressx(){/*{{{*/ 2185 2186 for(int i=0;i<elements->Size();i++){ 2187 Element* element=dynamic_cast<Element*>(this->elements->GetObjectByOffset(i)); 2188 element->ComputeDeviatoricStressTensor(); 2189 } 2121 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 2122 element->UpdateConstraintsExtrudeFromTop(); 2123 } 2124 2125 } 2126 /*}}}*/ 2127 void FemModel::UpdateConstraintsx(void){ /*{{{*/ 2128 2129 IssmDouble time; 2130 int analysis_type; 2131 2132 /*retrieve parameters: */ 2133 parameters->FindParam(&analysis_type,AnalysisTypeEnum); 2134 parameters->FindParam(&time,TimeEnum); 2135 2136 /*start module: */ 2137 if(VerboseModule()) _printf0_(" Updating constraints and active domain of analysis " << EnumToStringx(analysis_type) << " for time: " << time << "\n"); 2138 2139 Analysis* analysis= EnumToAnalysis(analysis_type); 2140 analysis->UpdateConstraints(this); 2141 delete analysis; 2142 2143 /*Second, constraints might be time dependent: */ 2144 SpcNodesx(nodes,constraints,parameters,analysis_type); 2145 2146 /*Now, update degrees of freedoms: */ 2147 NodesDofx(nodes,parameters,analysis_type); 2148 2149 } 2150 /*}}}*/ 2151 int FemModel::UpdateVertexPositionsx(void){ /*{{{*/ 2152 2153 IssmDouble *surface = NULL; 2154 IssmDouble *bed = NULL; 2155 2156 if(VerboseSolution()) _printf0_(" updating vertices positions\n"); 2157 2158 /*get vertex vectors for bed and thickness: */ 2159 GetVectorFromInputsx(&surface ,this, SurfaceEnum,VertexPIdEnum); 2160 GetVectorFromInputsx(&bed ,this, BaseEnum, VertexPIdEnum); 2161 2162 /*Allocate vector*/ 2163 Vector<IssmDouble> *vx=new Vector<IssmDouble>(vertices->NumberOfVertices()); 2164 Vector<IssmDouble> *vy=new Vector<IssmDouble>(vertices->NumberOfVertices()); 2165 Vector<IssmDouble> *vz=new Vector<IssmDouble>(vertices->NumberOfVertices()); 2166 2167 /*Update verices new geometry: */ 2168 for(int i=0;i<vertices->Size();i++){ 2169 Vertex* vertex=(Vertex*)vertices->GetObjectByOffset(i); 2170 vertex->UpdatePosition(vx,vy,vz,parameters,surface,bed); 2171 } 2172 2173 /*Assemble mesh velocity*/ 2174 vx->Assemble(); 2175 vy->Assemble(); 2176 vz->Assemble(); 2177 2178 /*Update element inputs*/ 2179 InputUpdateFromVectorx(this,vx,VxMeshEnum,VertexPIdEnum); 2180 InputUpdateFromVectorx(this,vy,VyMeshEnum,VertexPIdEnum); 2181 InputUpdateFromVectorx(this,vz,VzMeshEnum,VertexPIdEnum); 2182 2183 /*Free ressources:*/ 2184 delete vx; 2185 delete vy; 2186 delete vz; 2187 xDelete<IssmDouble>(bed); 2188 xDelete<IssmDouble>(surface); 2189 return 1; 2190 2190 } 2191 2191 /*}}}*/ … … 2608 2608 } 2609 2609 /*}}}*/ 2610 void FemModel::InitFromBuffers(char* buffer, int buffersize, char* toolkits, int in_solution_type, bool trace, IssmPDouble* X){/*{{{*/2611 2612 /*intermediary*/2613 int i;2614 int analysis_type;2615 FILE *IOMODEL = NULL;2616 FILE *toolkitsoptionsfid = NULL;2617 FILE *output_fid = NULL;2618 int my_rank;2619 size_t outputsize;2620 char *outputbuffer;2621 const char* rootpath=""; //needed for Dakota runs only, which we won't do here.2622 2623 /*recover my_rank:*/2624 my_rank=IssmComm::GetRank();2625 2626 /*Initialize internal data: */2627 this->solution_type = in_solution_type;2628 this->analysis_counter = nummodels-1; //point to last analysis_type carried out.2629 this->results = new Results(); //not initialized by CreateDataSets2630 2631 /*Open input file on cpu 0 and create IoModel */2632 if(my_rank==0) IOMODEL = fmemopen((void*)buffer, buffersize, "rb");2633 IoModel* iomodel = new IoModel(IOMODEL,in_solution_type,trace,X);2634 2635 /*Figure out what analyses are activated for this solution*/2636 SolutionAnalysesList(&this->analysis_type_list,&this->nummodels,iomodel,this->solution_type);2637 2638 /*Open toolkits file: */2639 toolkitsoptionsfid=fmemopen((void*)toolkits, strlen(toolkits)+1, "r");2640 2641 /*create datasets for all analyses*/2642 ModelProcessorx(&this->elements,&this->nodes,&this->vertices,&this->materials,&this->constraints,&this->loads,&this->parameters,iomodel,toolkitsoptionsfid,(char*)rootpath,this->solution_type,this->nummodels,this->analysis_type_list);2643 2644 /*do the post-processing of the datasets to get an FemModel that can actually run analyses: */2645 for(i=0;i<nummodels;i++){2646 2647 if(VerboseMProcessor()) _printf0_(" Processing finite element model of analysis " << EnumToStringx(analysis_type_list[i]) << ":\n");2648 analysis_type=analysis_type_list[i];2649 this->SetCurrentConfiguration(analysis_type);2650 2651 if(i==0){2652 if(VerboseMProcessor()) _printf0_(" creating vertex PIDs\n");2653 VerticesDofx(vertices,parameters); //only call once, we only have one set of vertices2654 }2655 2656 if(VerboseMProcessor()) _printf0_(" resolving node constraints\n");2657 SpcNodesx(nodes,constraints,parameters,analysis_type);2658 2659 if(VerboseMProcessor()) _printf0_(" creating nodal degrees of freedom\n");2660 NodesDofx(nodes,parameters,analysis_type);2661 2662 if(VerboseMProcessor()) _printf0_(" configuring element and loads\n");2663 ConfigureObjectsx(elements, loads, nodes, vertices, materials,parameters);2664 }2665 2666 /*Close input file and toolkits file descriptors: */2667 if(my_rank==0) fclose(IOMODEL);2668 fclose(toolkitsoptionsfid);2669 2670 /*Open output file once for all and add output file descriptor to parameters*/2671 output_fid=open_memstream(&outputbuffer,&outputsize);2672 if(output_fid==NULL)_error_("could not initialize output stream");2673 this->parameters->SetParam(output_fid,OutputFilePointerEnum);2674 this->parameters->AddObject(new GenericParam<char**>(&outputbuffer,OutputBufferPointerEnum));2675 this->parameters->AddObject(new GenericParam<size_t*>(&outputsize,OutputBufferSizePointerEnum));2676 2677 /*Clean up*/2678 delete iomodel;2679 }/*}}}*/2680 2610 void FemModel::CleanUpJs(char** poutput, size_t* psize){/*{{{*/ 2681 2611 … … 2717 2647 } 2718 2648 /*}}}*/ 2649 void FemModel::InitFromBuffers(char* buffer, int buffersize, char* toolkits, int in_solution_type, bool trace, IssmPDouble* X){/*{{{*/ 2650 2651 /*intermediary*/ 2652 int i; 2653 int analysis_type; 2654 FILE *IOMODEL = NULL; 2655 FILE *toolkitsoptionsfid = NULL; 2656 FILE *output_fid = NULL; 2657 int my_rank; 2658 size_t outputsize; 2659 char *outputbuffer; 2660 const char* rootpath=""; //needed for Dakota runs only, which we won't do here. 2661 2662 /*recover my_rank:*/ 2663 my_rank=IssmComm::GetRank(); 2664 2665 /*Initialize internal data: */ 2666 this->solution_type = in_solution_type; 2667 this->analysis_counter = nummodels-1; //point to last analysis_type carried out. 2668 this->results = new Results(); //not initialized by CreateDataSets 2669 2670 /*Open input file on cpu 0 and create IoModel */ 2671 if(my_rank==0) IOMODEL = fmemopen((void*)buffer, buffersize, "rb"); 2672 IoModel* iomodel = new IoModel(IOMODEL,in_solution_type,trace,X); 2673 2674 /*Figure out what analyses are activated for this solution*/ 2675 SolutionAnalysesList(&this->analysis_type_list,&this->nummodels,iomodel,this->solution_type); 2676 2677 /*Open toolkits file: */ 2678 toolkitsoptionsfid=fmemopen((void*)toolkits, strlen(toolkits)+1, "r"); 2679 2680 /*create datasets for all analyses*/ 2681 ModelProcessorx(&this->elements,&this->nodes,&this->vertices,&this->materials,&this->constraints,&this->loads,&this->parameters,iomodel,toolkitsoptionsfid,(char*)rootpath,this->solution_type,this->nummodels,this->analysis_type_list); 2682 2683 /*do the post-processing of the datasets to get an FemModel that can actually run analyses: */ 2684 for(i=0;i<nummodels;i++){ 2685 2686 if(VerboseMProcessor()) _printf0_(" Processing finite element model of analysis " << EnumToStringx(analysis_type_list[i]) << ":\n"); 2687 analysis_type=analysis_type_list[i]; 2688 this->SetCurrentConfiguration(analysis_type); 2689 2690 if(i==0){ 2691 if(VerboseMProcessor()) _printf0_(" creating vertex PIDs\n"); 2692 VerticesDofx(vertices,parameters); //only call once, we only have one set of vertices 2693 } 2694 2695 if(VerboseMProcessor()) _printf0_(" resolving node constraints\n"); 2696 SpcNodesx(nodes,constraints,parameters,analysis_type); 2697 2698 if(VerboseMProcessor()) _printf0_(" creating nodal degrees of freedom\n"); 2699 NodesDofx(nodes,parameters,analysis_type); 2700 2701 if(VerboseMProcessor()) _printf0_(" configuring element and loads\n"); 2702 ConfigureObjectsx(elements, loads, nodes, vertices, materials,parameters); 2703 } 2704 2705 /*Close input file and toolkits file descriptors: */ 2706 if(my_rank==0) fclose(IOMODEL); 2707 fclose(toolkitsoptionsfid); 2708 2709 /*Open output file once for all and add output file descriptor to parameters*/ 2710 output_fid=open_memstream(&outputbuffer,&outputsize); 2711 if(output_fid==NULL)_error_("could not initialize output stream"); 2712 this->parameters->SetParam(output_fid,OutputFilePointerEnum); 2713 this->parameters->AddObject(new GenericParam<char**>(&outputbuffer,OutputBufferPointerEnum)); 2714 this->parameters->AddObject(new GenericParam<size_t*>(&outputsize,OutputBufferSizePointerEnum)); 2715 2716 /*Clean up*/ 2717 delete iomodel; 2718 }/*}}}*/ 2719 2719 #endif -
issm/trunk-jpl/src/c/classes/FemModel.h
r20723 r20810 28 28 public: 29 29 30 int analysis_counter; //counter into analysis_type_list 31 int *analysis_type_list; //list of analyses this femmodel is going to carry out 30 32 int nummodels; 31 33 int solution_type; 32 int *analysis_type_list; //list of analyses this femmodel is going to carry out33 int analysis_counter; //counter into analysis_type_list34 34 35 35 Profiler* profiler; //keep time, cpu and mem statistics while we are running. 36 36 37 Constraints *constraints; //one set of constraints. each constraint knows which analysis_type it handles 37 38 Elements *elements; //elements (one set for all analyses) 38 Nodes *nodes; //one set of nodes39 Vertices *vertices; //one set of vertices40 Constraints *constraints; //one set of constraints. each constraint knows which analysis_type it handles41 39 Loads *loads; //one set of constraints. each constraint knows which analysis_type it handles 42 40 Materials *materials; //one set of materials, for each element 41 Nodes *nodes; //one set of nodes 43 42 Parameters *parameters; //one set of parameters, independent of the analysis_type 44 43 Results *results; //results that cannot be fit into the elements 44 Vertices *vertices; //one set of vertices 45 45 46 46 /*constructors, destructors: */ … … 50 50 51 51 /*Methods:*/ 52 void CheckPoint(void); 53 void CleanUp(void); 54 FemModel* copy(); 52 55 void Echo(); 53 FemModel* copy();54 56 void InitFromFiles(char* rootpath, char* inputfilename, char* outputfilename, char* petscfilename, char* lockfilename, char* restartfilename, const int solution_type,bool trace,IssmPDouble* X=NULL); 55 void SolutionAnalysesList(int** panalyses,int* pnumanalyses,IoModel* iomodel,int solutiontype); 56 void CleanUp(void); 57 void Solve(void); 57 void Marshall(char** pmarshalled_data, int* pmarshalled_data_size, int marshall_direction); 58 void Restart(void); 58 59 void SetCurrentConfiguration(int configuration_type); 59 60 void SetCurrentConfiguration(int configuration_type,int analysis_type); 60 void CheckPoint(void); 61 void Marshall(char** pmarshalled_data, int* pmarshalled_data_size, int marshall_direction); 62 void Restart(void); 61 void SolutionAnalysesList(int** panalyses,int* pnumanalyses,IoModel* iomodel,int solutiontype); 62 void Solve(void); 63 63 64 64 /*Modules*/ 65 void BalancethicknessMisfitx(IssmDouble* pV); 66 void CalvingRateDevx(); 67 void CalvingRateLevermannx(); 68 void DeviatoricStressx(); 69 void Divergencex(IssmDouble* pdiv); 65 70 void ElementOperationx(void (Element::*function)(void)); 71 void ElementResponsex(IssmDouble* presponse,int response_enum); 72 void FloatingAreax(IssmDouble* pV); 66 73 void GetInputLocalMinMaxOnNodesx(IssmDouble** pmin,IssmDouble** pmax,IssmDouble* ug); 74 void GroundedAreax(IssmDouble* pV); 75 void IceMassx(IssmDouble* pV); 76 void IceVolumex(IssmDouble* pV); 77 void IceVolumeAboveFloatationx(IssmDouble* pV); 67 78 void MassFluxx(IssmDouble* presponse); 68 79 void MaxAbsVxx(IssmDouble* presponse); 69 80 void MaxAbsVyx(IssmDouble* presponse); 70 81 void MaxAbsVzx(IssmDouble* presponse); 82 void MaxDivergencex(IssmDouble* pdiv); 71 83 void MaxVelx(IssmDouble* presponse); 72 84 void MaxVxx(IssmDouble* presponse); … … 77 89 void MinVyx(IssmDouble* presponse); 78 90 void MinVzx(IssmDouble* presponse); 91 void ResetLevelset(); 92 void StrainRateparallelx(); 93 void StrainRateperpendicularx(); 94 void StressIntensityFactorx(); 79 95 void TotalFloatingBmbx(IssmDouble* pFbmb); 80 96 void TotalGroundedBmbx(IssmDouble* pGbmb); 81 97 void TotalSmbx(IssmDouble* pSmb); 82 void Divergencex(IssmDouble* pdiv);83 void MaxDivergencex(IssmDouble* pdiv);84 void FloatingAreax(IssmDouble* pV);85 void GroundedAreax(IssmDouble* pV);86 void IceMassx(IssmDouble* pV);87 void IceVolumex(IssmDouble* pV);88 void IceVolumeAboveFloatationx(IssmDouble* pV);89 void ElementResponsex(IssmDouble* presponse,int response_enum);90 void BalancethicknessMisfitx(IssmDouble* pV);91 void StressIntensityFactorx();92 void StrainRateparallelx();93 void StrainRateperpendicularx();94 void DeviatoricStressx();95 void CalvingRateLevermannx();96 void CalvingRateDevx();97 void ResetLevelset();98 98 #ifdef _HAVE_DAKOTA_ 99 99 void DakotaResponsesx(double* d_responses,char** responses_descriptors,int numresponsedescriptors,int d_numresponses); 100 100 #endif 101 void CostFunctionx(IssmDouble* pJ,IssmDouble** pJlist,int* pn); 102 void OutputControlsx(Results **presults); 103 void RequestedDependentsx(void); 101 104 void RequestedOutputsx(Results **presults,char** requested_outputs, int numoutputs,bool save_results=true); 102 105 void RequestedOutputsx(Results **presults,int* requested_outputs, int numoutputs,bool save_results=true); 103 void RequestedDependentsx(void);104 106 void Responsex(IssmDouble* presponse,int response_descriptor_enum); 105 107 void Responsex(IssmDouble* presponse,const char* response_descriptor); 106 void OutputControlsx(Results **presults); 107 void CostFunctionx(IssmDouble* pJ,IssmDouble** pJlist,int* pn); 108 void SurfaceAbsMisfitx( IssmDouble* pJ); 108 109 void ThicknessAbsGradientx( IssmDouble* pJ); 109 110 void ThicknessPositivex(IssmDouble* pJ); 110 void SurfaceAbsMisfitx( IssmDouble* pJ);111 111 #ifdef _HAVE_GIA_ 112 112 void Deflection(Vector<IssmDouble>* wg,Vector<IssmDouble>* dwgdt, IssmDouble* x, IssmDouble* y); … … 117 117 IssmDouble SealevelriseOceanAverage(Vector<IssmDouble>* Sg); 118 118 #endif 119 void HydrologyEPLupdateDomainx(IssmDouble* pEplcount); 119 120 void TimeAdaptx(IssmDouble* pdt); 121 void UpdateConstraintsExtrudeFromBasex(); 122 void UpdateConstraintsExtrudeFromTopx(); 123 void UpdateConstraintsL2ProjectionEPLx(IssmDouble* pL2count); 120 124 void UpdateConstraintsx(void); 121 125 int UpdateVertexPositionsx(void); 122 void UpdateConstraintsExtrudeFromBasex();123 void UpdateConstraintsExtrudeFromTopx();124 void HydrologyEPLupdateDomainx(IssmDouble* pEplcount);125 void UpdateConstraintsL2ProjectionEPLx(IssmDouble* pL2count);126 126 127 127 #ifdef _HAVE_JAVASCRIPT_ 128 128 FemModel(IssmDouble* buffer, int buffersize, char* toolkits, char* solution, char* modelname,ISSM_MPI_Comm incomm, bool trace=false); 129 void CleanUpJs(char** poutput, size_t* psize); 129 130 void InitFromBuffers(char* buffer, int buffersize, char* toolkits, int solution_type,bool trace,IssmPDouble* X=NULL); 130 void CleanUpJs(char** poutput, size_t* psize);131 131 #endif 132 132 }; -
issm/trunk-jpl/src/c/classes/GiaDeflectionCoreArgs.h
r15141 r20810 9 9 10 10 /*inputs: */ 11 IssmDouble currenttime; 12 IssmDouble* hes; //loading history (in ice thickness) 13 int numtimes; //loading history length 11 14 IssmDouble ri; //radial distance from center of disk to vertex i 12 15 IssmDouble re; //radius of disk 13 IssmDouble* hes; //loading history (in ice thickness)14 16 IssmDouble* times; //loading history times 15 int numtimes; //loading history length16 IssmDouble currenttime;17 17 18 18 /*gia material parameters: */ 19 IssmDouble lithosphere_density; 19 20 IssmDouble lithosphere_shear_modulus; 20 IssmDouble lithosphere_density; 21 IssmDouble lithosphere_thickness; 22 IssmDouble mantle_density; 21 23 IssmDouble mantle_shear_modulus; 22 24 IssmDouble mantle_viscosity; 23 IssmDouble mantle_density;24 IssmDouble lithosphere_thickness;25 25 26 26 /*gia solution parameters: */ -
issm/trunk-jpl/src/c/classes/Hook.cpp
r19254 r20810 59 59 60 60 /*Some of the Object functionality: */ 61 void Hook::Echo(void){/*{{{*/ 62 _assert_(this); 63 int i; 64 if (num){ 65 _printf_(" Hook: \n"); 66 _printf_(" num=" << this->num << "\n"); 67 _printf_(" ids: "); 68 for(i=0;i<this->num;i++) _printf_(this->ids[i] << " "); 69 _printf_("\n"); 70 _printf_(" offsets: "); 71 for (i=0;i<this->num;i++) _printf_(this->offsets[i] << " "); 72 _printf_("\n"); 73 } 74 else{ 75 _printf_(" Hook: num=0 \n"); 76 } 61 Object* Hook::copy(void){/*{{{*/ 62 63 /*output: */ 64 Hook* output=NULL; 65 66 /*initalize output: */ 67 output=new Hook(this->ids,this->num); 68 69 for(int i=0;i<output->num;i++){ 70 output->objects[i] = this->objects[i]; 71 output->offsets[i] = this->offsets[i]; 72 } 73 74 return (Object*)output; 77 75 } 78 76 /*}}}*/ … … 104 102 } 105 103 /*}}}*/ 106 Object* Hook::copy(void){/*{{{*/ 107 108 /*output: */ 109 Hook* output=NULL; 110 111 /*initalize output: */ 112 output=new Hook(this->ids,this->num); 113 114 for(int i=0;i<output->num;i++){ 115 output->objects[i] = this->objects[i]; 116 output->offsets[i] = this->offsets[i]; 117 } 118 119 return (Object*)output; 104 void Hook::Echo(void){/*{{{*/ 105 _assert_(this); 106 int i; 107 if (num){ 108 _printf_(" Hook: \n"); 109 _printf_(" num=" << this->num << "\n"); 110 _printf_(" ids: "); 111 for(i=0;i<this->num;i++) _printf_(this->ids[i] << " "); 112 _printf_("\n"); 113 _printf_(" offsets: "); 114 for (i=0;i<this->num;i++) _printf_(this->offsets[i] << " "); 115 _printf_("\n"); 116 } 117 else{ 118 _printf_(" Hook: num=0 \n"); 119 } 120 120 } 121 121 /*}}}*/ … … 143 143 144 144 /*Hook management: */ 145 void Hook::reset(){/*{{{*/146 147 /*intermediary: */148 Object* object=NULL;149 int i;150 151 for(i=0;i<this->num;i++){152 this->objects[i]=NULL; //reset this node.153 }154 }155 /*}}}*/156 145 void Hook::configure(DataSet* dataset){/*{{{*/ 157 146 … … 196 185 } 197 186 /*}}}*/ 187 Object** Hook::deliverp(void){/*{{{*/ 188 return objects; 189 } 190 /*}}}*/ 198 191 Object* Hook::delivers(void){/*{{{*/ 199 192 … … 208 201 209 202 /*}}}*/ 210 Object** Hook::deliverp(void){/*{{{*/211 return objects;203 int Hook::GetNum(void){/*{{{*/ 204 return this->num; 212 205 } 213 206 /*}}}*/ … … 216 209 } 217 210 /*}}}*/ 218 int Hook::GetNum(void){/*{{{*/ 219 return this->num; 211 void Hook::reset(){/*{{{*/ 212 213 /*intermediary: */ 214 Object* object=NULL; 215 int i; 216 217 for(i=0;i<this->num;i++){ 218 this->objects[i]=NULL; //reset this node. 219 } 220 220 } 221 221 /*}}}*/ -
issm/trunk-jpl/src/c/classes/Hook.h
r19215 r20810 18 18 private: 19 19 20 int *ids; //list of object ids, to go look for them in datasets. 20 21 int num; //number of objects being hooked onto 21 22 Object **objects; //list of object pointers 22 int *ids; //list of object ids, to go look for them in datasets.23 23 int *offsets; //list of object offsets into datasets, to speed up lookup. 24 24 … … 31 31 /*}}}*/ 32 32 /*Object like functionality:{{{*/ 33 Object* copy(void); 34 void DeepEcho(void); 33 35 void Echo(void); 34 void DeepEcho(void);35 Object* copy(void);36 36 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction); 37 37 /*}}}*/ 38 38 /*Hook management: {{{*/ 39 void configure(DataSet* dataset); 40 Object** deliverp(void); //deliver all objects 39 41 Object* delivers(void); //single object deliver 40 Object** deliverp(void); //deliver all objects41 void configure(DataSet* dataset);42 int GetNum(void); 43 int* Ids(void); 42 44 void reset(void); 43 45 Hook* Spawn(int* indices, int numindices); 44 int* Ids(void);45 int GetNum(void);46 46 /*}}}*/ 47 47 }; -
issm/trunk-jpl/src/c/classes/Inputs/BoolInput.cpp
r19254 r20810 29 29 30 30 /*Object virtual functions definitions:*/ 31 void BoolInput::Echo(void){/*{{{*/ 32 this->DeepEcho(); 31 Object* BoolInput::copy() {/*{{{*/ 32 33 return new BoolInput(this->enum_type,this->value); 34 33 35 } 34 36 /*}}}*/ … … 38 40 } 39 41 /*}}}*/ 40 int BoolInput::Id(void){ return -1; }/*{{{*/ 41 /*}}}*/ 42 int BoolInput::ObjectEnum(void){/*{{{*/ 43 44 return BoolInputEnum; 45 42 void BoolInput::Echo(void){/*{{{*/ 43 this->DeepEcho(); 46 44 } 47 45 /*}}}*/ 48 Object* BoolInput::copy() {/*{{{*/ 49 50 return new BoolInput(this->enum_type,this->value); 51 52 } 46 int BoolInput::Id(void){ return -1; }/*{{{*/ 53 47 /*}}}*/ 54 48 void BoolInput::Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){ /*{{{*/ … … 61 55 } 62 56 /*}}}*/ 57 int BoolInput::ObjectEnum(void){/*{{{*/ 58 59 return BoolInputEnum; 60 61 } 62 /*}}}*/ 63 63 64 64 /*BoolInput management*/ … … 66 66 67 67 return this->enum_type; 68 69 } 70 /*}}}*/ 71 Input* BoolInput::SpawnSegInput(int index1,int index2){/*{{{*/ 72 73 /*output*/ 74 BoolInput* outinput=new BoolInput(); 75 76 /*only copy current value*/ 77 outinput->enum_type=this->enum_type; 78 outinput->value=this->value; 79 80 /*Assign output*/ 81 return outinput; 68 82 69 83 } … … 83 97 } 84 98 /*}}}*/ 85 Input* BoolInput::SpawnSegInput(int index1,int index2){/*{{{*/86 87 /*output*/88 BoolInput* outinput=new BoolInput();89 90 /*only copy current value*/91 outinput->enum_type=this->enum_type;92 outinput->value=this->value;93 94 /*Assign output*/95 return outinput;96 97 }98 /*}}}*/99 99 100 100 /*Object functions*/ 101 void BoolInput::GetInputValue(bool* pvalue){/*{{{*/102 *pvalue=value;103 }104 /*}}}*/105 void BoolInput::GetInputValue(int* pvalue){_error_("not supported yet!");}/*{{{*/106 /*}}}*/107 void BoolInput::GetInputValue(IssmDouble* pvalue){_error_("not supported yet!");}/*{{{*/108 /*}}}*/109 void BoolInput::GetInputValue(IssmDouble* pvalue,Gauss* gauss){_error_("not supported yet!");}/*{{{*/110 /*}}}*/111 void BoolInput::ChangeEnum(int newenumtype){/*{{{*/112 this->enum_type=newenumtype;113 }114 /*}}}*/115 void BoolInput::SquareMin(IssmDouble* psquaremin,Parameters* parameters){/*{{{*/116 /*square of a bool is the bool itself: */117 *psquaremin=value;118 }119 /*}}}*/120 void BoolInput::Scale(IssmDouble scale_factor){/*{{{*/121 /*a bool cannot be scaled: */122 }123 /*}}}*/124 101 void BoolInput::AXPY(Input* xinput,IssmDouble scalar){/*{{{*/ 125 102 … … 142 119 } 143 120 /*}}}*/ 121 void BoolInput::ChangeEnum(int newenumtype){/*{{{*/ 122 this->enum_type=newenumtype; 123 } 124 /*}}}*/ 125 void BoolInput::Configure(Parameters* parameters){/*{{{*/ 126 /*do nothing: */ 127 } 128 /*}}}*/ 144 129 void BoolInput::Extrude(int start){/*{{{*/ 145 130 … … 147 132 return; 148 133 } 134 /*}}}*/ 135 void BoolInput::GetInputValue(bool* pvalue){/*{{{*/ 136 *pvalue=value; 137 } 138 /*}}}*/ 139 void BoolInput::GetInputValue(int* pvalue){_error_("not supported yet!");}/*{{{*/ 140 /*}}}*/ 141 void BoolInput::GetInputValue(IssmDouble* pvalue){_error_("not supported yet!");}/*{{{*/ 142 /*}}}*/ 143 void BoolInput::GetInputValue(IssmDouble* pvalue,Gauss* gauss){_error_("not supported yet!");}/*{{{*/ 149 144 /*}}}*/ 150 145 void BoolInput::GetVectorFromInputs(Vector<IssmDouble>* vector,int* doflist){/*{{{*/ … … 154 149 } 155 150 /*}}}*/ 156 void BoolInput:: Configure(Parameters* parameters){/*{{{*/157 /* do nothing: */151 void BoolInput::Scale(IssmDouble scale_factor){/*{{{*/ 152 /*a bool cannot be scaled: */ 158 153 } 159 154 /*}}}*/ 155 void BoolInput::SquareMin(IssmDouble* psquaremin,Parameters* parameters){/*{{{*/ 156 /*square of a bool is the bool itself: */ 157 *psquaremin=value; 158 } 159 /*}}}*/ -
issm/trunk-jpl/src/c/classes/Inputs/BoolInput.h
r19725 r20810 22 22 /*}}}*/ 23 23 /*Object virtual functions definitions:{{{ */ 24 Object *copy(); 25 void DeepEcho(); 24 26 void Echo(); 25 void DeepEcho();26 27 int Id(); 28 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction); 27 29 int ObjectEnum(); 28 Object *copy();29 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction);30 30 /*}}}*/ 31 31 /*BoolInput management: {{{*/ 32 void AddTimeValues(IssmDouble* values,int step,IssmDouble time){_error_("not supported yet");}; 33 void Configure(Parameters* parameters); 34 int GetResultArraySize(void){return 1;}; 35 int GetResultInterpolation(void){return P0Enum;}; 36 int GetResultNumberOfNodes(void){return 1;}; 32 37 int InstanceEnum(); 33 Input* SpawnTriaInput(int index1,int index2,int index3);34 Input* SpawnSegInput(int index1,int index2);35 38 Input* PointwiseDivide(Input* inputB){_error_("not implemented yet");}; 36 39 Input* PointwiseMin(Input* inputB){_error_("not implemented yet");}; 37 40 Input* PointwiseMax(Input* inputB){_error_("not implemented yet");}; 38 int GetResultInterpolation(void){return P0Enum;}; 39 int GetResultNumberOfNodes(void){return 1;}; 40 int GetResultArraySize(void){return 1;}; 41 Input* SpawnSegInput(int index1,int index2); 42 Input* SpawnTriaInput(int index1,int index2,int index3); 41 43 void ResultToPatch(IssmDouble* values,int nodesperelement,int sid){_error_("not supported yet");}; 42 void Configure(Parameters* parameters);43 void AddTimeValues(IssmDouble* values,int step,IssmDouble time){_error_("not supported yet");};44 44 /*}}}*/ 45 45 /*numerics: {{{*/ 46 void AXPY(Input* xinput,IssmDouble scalar); 47 void ChangeEnum(int newenumtype); 48 void Constrain(IssmDouble cm_min, IssmDouble cm_max){_error_("Constrain not implemented for booleans");}; 49 void ConstrainMin(IssmDouble minimum){_error_("not implemented yet");}; 50 void Extrude(int start); 51 void GetInputAllTimeAverages(IssmDouble** pvalues,IssmDouble** ptimes, int* pnumtimes){_error_("not implemented yet");}; 52 void GetInputAverage(IssmDouble* pvalue){_error_("not implemented yet");}; 53 void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, Gauss* gauss){_error_("not implemented yet");}; 54 void GetInputDerivativeAverageValue(IssmDouble* derivativevalues, IssmDouble* xyz_list){_error_("not implemented yet");}; 55 void GetInputUpToCurrentTimeAverages(IssmDouble** pvalues, IssmDouble** ptimes, int* pnumtimes, IssmDouble currenttime){_error_("not implemented yet");}; 46 56 void GetInputValue(bool* pvalue); 47 57 void GetInputValue(int* pvalue); … … 50 60 void GetInputValue(IssmDouble* pvalue,Gauss* gauss,IssmDouble time){_error_("not implemented yet");}; 51 61 void GetInputValue(IssmDouble* pvalue,Gauss* gauss ,int index){_error_("not implemented yet");}; 52 void GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, Gauss* gauss){_error_("not implemented yet");}; 53 void GetInputAverage(IssmDouble* pvalue){_error_("not implemented yet");}; 54 void GetInputDerivativeAverageValue(IssmDouble* derivativevalues, IssmDouble* xyz_list){_error_("not implemented yet");}; 55 void GetInputAllTimeAverages(IssmDouble** pvalues,IssmDouble** ptimes, int* pnumtimes){_error_("not implemented yet");}; 56 void GetInputUpToCurrentTimeAverages(IssmDouble** pvalues, IssmDouble** ptimes, int* pnumtimes, IssmDouble currenttime){_error_("not implemented yet");}; 57 void ChangeEnum(int newenumtype); 58 void SquareMin(IssmDouble* psquaremin, Parameters* parameters); 59 void ConstrainMin(IssmDouble minimum){_error_("not implemented yet");}; 62 void GetVectorFromInputs(Vector<IssmDouble>* vector,int* doflist); 60 63 IssmDouble InfinityNorm(void){_error_("InfinityNorm not implemented for booleans");}; 61 64 IssmDouble Max(void){_error_("Max not implemented for booleans");}; … … 65 68 void Set(IssmDouble setvalue){_error_("Set not implemented yet");}; 66 69 void Scale(IssmDouble scale_factor); 67 void AXPY(Input* xinput,IssmDouble scalar); 68 void Constrain(IssmDouble cm_min, IssmDouble cm_max){_error_("Constrain not implemented for booleans");}; 69 void Extrude(int start); 70 void SquareMin(IssmDouble* psquaremin, Parameters* parameters); 70 71 void VerticallyIntegrate(Input* thickness_input){_error_("not supported yet");}; 71 void GetVectorFromInputs(Vector<IssmDouble>* vector,int* doflist);72 72 /*}}}*/ 73 73 -
issm/trunk-jpl/src/c/classes/IoModel.cpp
r20690 r20810 377 377 } 378 378 /*}}}*/ 379 void IoModel::FetchIndependentConstant(int* pXcount,IssmPDouble* X,const char* constant_name){/*{{{*/380 381 /*recover my_rank:*/382 int my_rank=IssmComm::GetRank();383 384 /*recover Xcount if X is not NULL:*/385 int Xcount = 0;386 if(X) Xcount=*pXcount;387 388 #ifdef _HAVE_ADOLC_ //cannot come here unless you are running AD mode, from DeclaredIndependents:389 390 /*output: */391 IssmPDouble pscalar;392 IssmDouble scalar; //same as pscalar, except it's an ADOLC independent variable393 int code;394 395 /*Set file pointer to beginning of the data: */396 fid=this->SetFilePointerToData(&code,NULL,constant_name);397 if(code!=3) _error_("expecting a IssmDouble for \"" << constant_name<<"\"");398 399 /*We have to read a scalar from disk. First read the dimensions of the scalar, then the scalar: */400 if(my_rank==0){401 if(fread(&pscalar,sizeof(IssmPDouble),1,fid)!=1)_error_("could not read scalar ");402 403 /*Now, before we even broadcast this to other nodes, declare the scalar as an independent variable!. If we404 *have been supplied an X vector, use it instead of what we just read: */405 if(X){406 scalar<<=X[Xcount];407 }408 else{409 scalar<<=pscalar;410 }411 }412 413 ISSM_MPI_Bcast(&scalar,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());414 this->AddConstantIndependent(new IoConstant(scalar,constant_name));415 416 /*increment offset into X vector, now that we have read 1 value:*/417 Xcount++; *pXcount=Xcount;418 #endif419 }420 /*}}}*/421 void IoModel::FetchIndependentData(int* pXcount,IssmPDouble* X,const char* data_name){/*{{{*/422 423 /*recover my_rank:*/424 int my_rank=IssmComm::GetRank();425 426 /*recover Xcount if X is not NULL:*/427 int Xcount = 0;428 if(X) Xcount=*pXcount;429 430 #ifdef _HAVE_ADOLC_ //cannot come here unless you are running AD mode, from DeclaredIndependents:431 432 /*Intermediaries*/433 int M,N;434 IssmPDouble* buffer=NULL; //a buffer to read the data from disk435 IssmDouble* matrix=NULL; //our independent variable436 int code,layout;437 438 /*Set file pointer to beginning of the data: */439 fid=this->SetFilePointerToData(&code,&layout,data_name);440 if((code!=5) && (code!=6) && (code!=7))_error_("expecting a IssmDouble, integer or boolean matrix for \"" << data_name<<"\"");441 442 /*We have to read a matrix from disk. First read the dimensions of the matrix, then the whole matrix: */443 /*numberofelements: */444 if(my_rank==0){445 if(fread(&M,sizeof(int),1,fid)!=1) _error_("could not read number of rows for matrix ");446 }447 ISSM_MPI_Bcast(&M,1,ISSM_MPI_INT,0,IssmComm::GetComm());448 449 if(my_rank==0){450 if(fread(&N,sizeof(int),1,fid)!=1) _error_("could not read number of columns for matrix ");451 }452 ISSM_MPI_Bcast(&N,1,ISSM_MPI_INT,0,IssmComm::GetComm());453 454 /*Now allocate matrix: */455 if(M*N){456 buffer=xNew<IssmPDouble>(M*N);457 matrix=xNew<IssmDouble>(M*N);458 459 /*Read matrix on node 0, then broadcast: */460 if(my_rank==0){461 if(fread(buffer,M*N*sizeof(IssmPDouble),1,fid)!=1) _error_("could not read matrix ");462 463 /*Now, before we even broadcast this to other nodes, declare the whole matrix as a independent variable!464 If we have been supplied an X vector, use it instead of what we just read: */465 if(X){466 for(int i=0;i<M*N;i++) matrix[i]<<=X[Xcount+i]; /*<<= ADOLC overloaded operator to declare independent*/467 }468 else{469 for(int i=0;i<M*N;i++) matrix[i]<<=buffer[i];470 }471 }472 ISSM_MPI_Bcast(matrix,M*N,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());473 474 xDelete<IssmPDouble>(buffer);475 }476 else _error_("cannot declare the independent variable \"" << data_name << "\" if it's empty!");477 478 /*Add to data as independent*/479 this->AddDataIndependent(new IoData(matrix,code,layout,M,N,data_name));480 481 /*increment offset into X vector, now that we have read M*N values:*/482 Xcount+=M*N; *pXcount=Xcount;483 #endif484 }485 /*}}}*/486 void IoModel::FindConstant(bool* pvalue,const char* constant_name){/*{{{*/487 488 /*Intermediary*/489 vector<IoConstant*>::iterator iter;490 491 for(iter=constants.begin();iter<constants.end();iter++){492 IoConstant* ioconstant=*iter;493 494 if(strcmp(ioconstant->name,constant_name)==0){495 ioconstant->constant->GetParameterValue(pvalue);496 return;497 }498 }499 500 for(vector<IoConstant*>::iterator iter=constants.begin();iter<constants.end();iter++) (*iter)->constant->Echo();501 _error_("Could not find constant \""<<constant_name<<"\"");502 }503 /*}}}*/504 void IoModel::FindConstant(int* pvalue,const char* constant_name){/*{{{*/505 506 /*Intermediary*/507 vector<IoConstant*>::iterator iter;508 509 for(iter=constants.begin();iter<constants.end();iter++){510 IoConstant* ioconstant=*iter;511 512 if(strcmp(ioconstant->name,constant_name)==0){513 ioconstant->constant->GetParameterValue(pvalue);514 return;515 }516 }517 518 _error_("Could not find constant \""<<constant_name <<"\"");519 }520 /*}}}*/521 void IoModel::FindConstant(IssmDouble* pvalue,const char* constant_name){/*{{{*/522 523 /*Intermediary*/524 vector<IoConstant*>::iterator iter;525 526 for(iter=constants.begin();iter<constants.end();iter++){527 IoConstant* ioconstant=*iter;528 529 if(strcmp(ioconstant->name,constant_name)==0){530 ioconstant->constant->GetParameterValue(pvalue);531 return;532 }533 }534 535 _error_("Could not find constant \""<<constant_name <<"\"");536 }537 /*}}}*/538 void IoModel::FindConstant(char** pvalue,const char* constant_name){/*{{{*/539 540 /*Intermediary*/541 vector<IoConstant*>::iterator iter;542 543 for(iter=constants.begin();iter<constants.end();iter++){544 IoConstant* ioconstant=*iter;545 546 if(strcmp(ioconstant->name,constant_name)==0){547 ioconstant->constant->GetParameterValue(pvalue);548 return;549 }550 }551 552 _error_("Could not find constant \""<<constant_name <<"\"");553 }554 /*}}}*/555 void IoModel::FindConstant(char*** pvalue,int* psize,const char* constant_name){/*{{{*/556 557 /*Intermediary*/558 vector<IoConstant*>::iterator iter;559 560 for(iter=constants.begin();iter<constants.end();iter++){561 IoConstant* ioconstant=*iter;562 563 if(strcmp(ioconstant->name,constant_name)==0){564 ioconstant->constant->GetParameterValue(pvalue,psize);565 return;566 }567 }568 569 _error_("Could not find constant \""<<constant_name <<"\"");570 }571 /*}}}*/572 int IoModel::NumIndependents(void){/*{{{*/573 574 /*Initialize output*/575 int num_independents = 0;576 577 /*Process constants*/578 for(vector<IoConstant*>::iterator iter=constants.begin();iter<constants.end();iter++){579 if((*iter)->isindependent){580 num_independents+= 1;581 }582 }583 584 /*Process data*/585 for(vector<IoData*>::iterator iter=data.begin();iter<data.end();iter++){586 if((*iter)->isindependent){587 num_independents+= (*iter)->M*(*iter)->N;588 }589 }590 591 /*return*/592 return num_independents;593 }594 /*}}}*/595 void IoModel::FillIndependents(IssmDouble* xp){/*{{{*/596 597 _assert_(xp);598 599 /*Initialize local num ind*/600 int local_num_ind = 0;601 602 /*Process constants*/603 for(vector<IoConstant*>::iterator iter=constants.begin();iter<constants.end();iter++){604 if((*iter)->isindependent){605 (*iter)->constant->GetParameterValue(&xp[local_num_ind]);606 local_num_ind += 1;607 }608 }609 610 /*Process data*/611 for(vector<IoData*>::iterator iter=data.begin();iter<data.end();iter++){612 if((*iter)->isindependent){613 for(int i=0;i<(*iter)->M*(*iter)->N;i++){614 xp[local_num_ind+i] = (*iter)->data[i];615 }616 local_num_ind += (*iter)->M*(*iter)->N;617 }618 }619 620 _assert_(local_num_ind == this->NumIndependents());621 }622 /*}}}*/623 379 Param* IoModel::CopyConstantObject(const char* constant_name,int param_enum){/*{{{*/ 624 380 … … 651 407 652 408 return NULL; 653 }654 /*}}}*/655 void IoModel::StartTrace(bool trace){/*{{{*/656 657 bool autodiff = false;658 bool iscontrol = false;659 bool keep=false;660 IssmDouble gcTriggerRatio;661 IssmDouble gcTriggerMaxSize;662 IssmDouble obufsize;663 IssmDouble lbufsize;664 IssmDouble cbufsize;665 IssmDouble tbufsize;666 667 int my_rank=IssmComm::GetRank();668 669 this->FetchData(&autodiff,"md.autodiff.isautodiff");670 this->FetchData(&iscontrol,"md.inversion.iscontrol");671 672 if(trace || (autodiff && !iscontrol)){673 #ifdef _HAVE_ADOLC_674 /*Retrieve parameters: */675 this->FetchData(&keep,"md.autodiff.keep");676 int keepTaylors=keep?1:0;677 this->FetchData(&gcTriggerRatio,"md.autodiff.gcTriggerRatio");678 this->FetchData(&gcTriggerMaxSize,"md.autodiff.gcTriggerMaxSize");679 this->FetchData(&obufsize,"md.autodiff.obufsize");680 this->FetchData(&lbufsize,"md.autodiff.lbufsize");681 this->FetchData(&cbufsize,"md.autodiff.cbufsize");682 this->FetchData(&tbufsize,"md.autodiff.tbufsize");683 684 /*Set garbage collection parameters: */685 setStoreManagerControl(reCast<IssmPDouble>(gcTriggerRatio),reCast<size_t>(gcTriggerMaxSize));686 687 /*Start trace: */688 int skipFileDeletion=1;689 trace_on(my_rank,keepTaylors,reCast<size_t>(obufsize),reCast<size_t>(lbufsize),reCast<size_t>(cbufsize),reCast<size_t>(tbufsize),skipFileDeletion);690 #endif691 }692 693 409 } 694 410 /*}}}*/ … … 1519 1235 } 1520 1236 /*}}}*/ 1237 void IoModel::FetchDataToInput(Elements* elements,const char* vector_name,int input_enum,IssmDouble default_value){/*{{{*/ 1238 1239 /*First, look whether it is not already loaded in this->data*/ 1240 vector<IoData*>::iterator iter; 1241 for(iter=data.begin();iter<data.end();iter++){ 1242 IoData* iodata=*iter; 1243 if(strcmp(iodata->name,vector_name)==0){ 1244 _assert_(iodata->code==7); 1245 for(int i=0;i<elements->Size();i++){ 1246 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 1247 element->InputCreate(iodata->data,this,iodata->M,iodata->N,iodata->layout,input_enum,iodata->code);//we need i to index into elements. 1248 } 1249 return; 1250 } 1251 } 1252 1253 /*intermediary: */ 1254 int code,vector_layout; 1255 IssmDouble *doublearray = NULL; 1256 int M,N; 1257 1258 /*First of, find the record for the name, and get code of data type: */ 1259 this->SetFilePointerToData(&code, &vector_layout,vector_name); 1260 1261 /*Defaulting only supported for double arrays*/ 1262 if(code!=7) _error_(vector_name<<" is not a double array"); 1263 1264 this->FetchData(&doublearray,&M,&N,vector_name); 1265 1266 for(int i=0;i<elements->Size();i++){ 1267 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 1268 if(!doublearray) element->AddInput(input_enum,&default_value,P0Enum); 1269 else element->InputCreate(doublearray,this,M,N,vector_layout,input_enum,code);//we need i to index into elements. 1270 } 1271 1272 /*Free ressources*/ 1273 xDelete<IssmDouble>(doublearray); 1274 } 1275 /*}}}*/ 1276 void IoModel::FetchDataToInput(Elements* elements,const char* vector_name,int input_enum){/*{{{*/ 1277 1278 /*First, look whether it is not already loaded in this->data*/ 1279 vector<IoData*>::iterator iter; 1280 for(iter=data.begin();iter<data.end();iter++){ 1281 IoData* iodata=*iter; 1282 if(strcmp(iodata->name,vector_name)==0){ 1283 for(int i=0;i<elements->Size();i++){ 1284 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 1285 element->InputCreate(iodata->data,this,iodata->M,iodata->N,iodata->layout,input_enum,iodata->code);//we need i to index into elements. 1286 } 1287 return; 1288 } 1289 } 1290 1291 /*intermediary: */ 1292 int i; 1293 int code,vector_layout; 1294 1295 /*variables being fetched: */ 1296 bool boolean; 1297 int integer; 1298 IssmDouble scalar; 1299 char *string = NULL; 1300 IssmDouble *doublearray = NULL; 1301 int M,N; 1302 1303 /*First of, find the record for the name, and get code of data type: */ 1304 this->SetFilePointerToData(&code, &vector_layout,vector_name); 1305 1306 switch(code){ 1307 case 1: //boolean constant 1308 this->FetchData(&boolean,vector_name); 1309 for(i=0;i<elements->Size();i++){ 1310 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 1311 element->InputUpdateFromConstant(boolean,input_enum); 1312 } 1313 break; 1314 case 2: //integer constant 1315 this->FetchData(&integer,vector_name); 1316 for(i=0;i<elements->Size();i++){ 1317 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 1318 element->InputUpdateFromConstant(integer,input_enum); 1319 } 1320 break; 1321 case 3: //IssmDouble constant 1322 this->FetchData(&scalar,vector_name); 1323 for(i=0;i<elements->Size();i++){ 1324 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 1325 element->InputUpdateFromConstant(scalar,input_enum); 1326 } 1327 break; 1328 case 5: //boolean vector 1329 this->FetchData(&doublearray,&M,&N,vector_name); //we still have a doublearray, because it might include times in transient mode 1330 if(!doublearray) _error_("\""<<vector_name<<"\" not found in binary file"); 1331 for(i=0;i<elements->Size();i++){ 1332 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 1333 element->InputCreate(doublearray,this,M,N,vector_layout,input_enum,code);//we need i to index into elements. 1334 } 1335 break; 1336 case 6: //int vector 1337 this->FetchData(&doublearray,&M,&N,vector_name); //we still have a doublearray, because it might include times in transient mode 1338 if(!doublearray) _error_("\""<<vector_name<<"\" not found in binary file"); 1339 for(i=0;i<elements->Size();i++){ 1340 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 1341 element->InputCreate(doublearray,this,M,N,vector_layout,input_enum,code);//we need i to index into elements. 1342 } 1343 break; 1344 case 7: //IssmDouble vector 1345 this->FetchData(&doublearray,&M,&N,vector_name); 1346 if(!doublearray) _error_("\""<<vector_name<<"\" not found in binary file"); 1347 for(i=0;i<elements->Size();i++){ 1348 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 1349 element->InputCreate(doublearray,this,M,N,vector_layout,input_enum,code);//we need i to index into elements. 1350 } 1351 break; 1352 default: 1353 _error_("data code " << code << " not supported yet (detected while processing \""<<vector_name<<"\")"); 1354 break; 1355 } 1356 /*Free ressources*/ 1357 xDelete<IssmDouble>(doublearray); 1358 xDelete<char>(string); 1359 } 1360 /*}}}*/ 1361 void IoModel::FetchIndependentConstant(int* pXcount,IssmPDouble* X,const char* constant_name){/*{{{*/ 1362 1363 /*recover my_rank:*/ 1364 int my_rank=IssmComm::GetRank(); 1365 1366 /*recover Xcount if X is not NULL:*/ 1367 int Xcount = 0; 1368 if(X) Xcount=*pXcount; 1369 1370 #ifdef _HAVE_ADOLC_ //cannot come here unless you are running AD mode, from DeclaredIndependents: 1371 1372 /*output: */ 1373 IssmPDouble pscalar; 1374 IssmDouble scalar; //same as pscalar, except it's an ADOLC independent variable 1375 int code; 1376 1377 /*Set file pointer to beginning of the data: */ 1378 fid=this->SetFilePointerToData(&code,NULL,constant_name); 1379 if(code!=3) _error_("expecting a IssmDouble for \"" << constant_name<<"\""); 1380 1381 /*We have to read a scalar from disk. First read the dimensions of the scalar, then the scalar: */ 1382 if(my_rank==0){ 1383 if(fread(&pscalar,sizeof(IssmPDouble),1,fid)!=1)_error_("could not read scalar "); 1384 1385 /*Now, before we even broadcast this to other nodes, declare the scalar as an independent variable!. If we 1386 *have been supplied an X vector, use it instead of what we just read: */ 1387 if(X){ 1388 scalar<<=X[Xcount]; 1389 } 1390 else{ 1391 scalar<<=pscalar; 1392 } 1393 } 1394 1395 ISSM_MPI_Bcast(&scalar,1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1396 this->AddConstantIndependent(new IoConstant(scalar,constant_name)); 1397 1398 /*increment offset into X vector, now that we have read 1 value:*/ 1399 Xcount++; *pXcount=Xcount; 1400 #endif 1401 } 1402 /*}}}*/ 1403 void IoModel::FetchIndependentData(int* pXcount,IssmPDouble* X,const char* data_name){/*{{{*/ 1404 1405 /*recover my_rank:*/ 1406 int my_rank=IssmComm::GetRank(); 1407 1408 /*recover Xcount if X is not NULL:*/ 1409 int Xcount = 0; 1410 if(X) Xcount=*pXcount; 1411 1412 #ifdef _HAVE_ADOLC_ //cannot come here unless you are running AD mode, from DeclaredIndependents: 1413 1414 /*Intermediaries*/ 1415 int M,N; 1416 IssmPDouble* buffer=NULL; //a buffer to read the data from disk 1417 IssmDouble* matrix=NULL; //our independent variable 1418 int code,layout; 1419 1420 /*Set file pointer to beginning of the data: */ 1421 fid=this->SetFilePointerToData(&code,&layout,data_name); 1422 if((code!=5) && (code!=6) && (code!=7))_error_("expecting a IssmDouble, integer or boolean matrix for \"" << data_name<<"\""); 1423 1424 /*We have to read a matrix from disk. First read the dimensions of the matrix, then the whole matrix: */ 1425 /*numberofelements: */ 1426 if(my_rank==0){ 1427 if(fread(&M,sizeof(int),1,fid)!=1) _error_("could not read number of rows for matrix "); 1428 } 1429 ISSM_MPI_Bcast(&M,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 1430 1431 if(my_rank==0){ 1432 if(fread(&N,sizeof(int),1,fid)!=1) _error_("could not read number of columns for matrix "); 1433 } 1434 ISSM_MPI_Bcast(&N,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 1435 1436 /*Now allocate matrix: */ 1437 if(M*N){ 1438 buffer=xNew<IssmPDouble>(M*N); 1439 matrix=xNew<IssmDouble>(M*N); 1440 1441 /*Read matrix on node 0, then broadcast: */ 1442 if(my_rank==0){ 1443 if(fread(buffer,M*N*sizeof(IssmPDouble),1,fid)!=1) _error_("could not read matrix "); 1444 1445 /*Now, before we even broadcast this to other nodes, declare the whole matrix as a independent variable! 1446 If we have been supplied an X vector, use it instead of what we just read: */ 1447 if(X){ 1448 for(int i=0;i<M*N;i++) matrix[i]<<=X[Xcount+i]; /*<<= ADOLC overloaded operator to declare independent*/ 1449 } 1450 else{ 1451 for(int i=0;i<M*N;i++) matrix[i]<<=buffer[i]; 1452 } 1453 } 1454 ISSM_MPI_Bcast(matrix,M*N,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); 1455 1456 xDelete<IssmPDouble>(buffer); 1457 } 1458 else _error_("cannot declare the independent variable \"" << data_name << "\" if it's empty!"); 1459 1460 /*Add to data as independent*/ 1461 this->AddDataIndependent(new IoData(matrix,code,layout,M,N,data_name)); 1462 1463 /*increment offset into X vector, now that we have read M*N values:*/ 1464 Xcount+=M*N; *pXcount=Xcount; 1465 #endif 1466 } 1467 /*}}}*/ 1521 1468 void IoModel::FetchMultipleData(char*** pstrings,int* pnumstrings,const char* data_name){/*{{{*/ 1522 1469 … … 1897 1844 } 1898 1845 /*}}}*/ 1899 void IoModel::FetchDataToInput(Elements* elements,const char* vector_name,int input_enum,IssmDouble default_value){/*{{{*/ 1900 1901 /*First, look whether it is not already loaded in this->data*/ 1902 vector<IoData*>::iterator iter; 1903 for(iter=data.begin();iter<data.end();iter++){ 1904 IoData* iodata=*iter; 1905 if(strcmp(iodata->name,vector_name)==0){ 1906 _assert_(iodata->code==7); 1907 for(int i=0;i<elements->Size();i++){ 1908 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 1909 element->InputCreate(iodata->data,this,iodata->M,iodata->N,iodata->layout,input_enum,iodata->code);//we need i to index into elements. 1910 } 1846 void IoModel::FillIndependents(IssmDouble* xp){/*{{{*/ 1847 1848 _assert_(xp); 1849 1850 /*Initialize local num ind*/ 1851 int local_num_ind = 0; 1852 1853 /*Process constants*/ 1854 for(vector<IoConstant*>::iterator iter=constants.begin();iter<constants.end();iter++){ 1855 if((*iter)->isindependent){ 1856 (*iter)->constant->GetParameterValue(&xp[local_num_ind]); 1857 local_num_ind += 1; 1858 } 1859 } 1860 1861 /*Process data*/ 1862 for(vector<IoData*>::iterator iter=data.begin();iter<data.end();iter++){ 1863 if((*iter)->isindependent){ 1864 for(int i=0;i<(*iter)->M*(*iter)->N;i++){ 1865 xp[local_num_ind+i] = (*iter)->data[i]; 1866 } 1867 local_num_ind += (*iter)->M*(*iter)->N; 1868 } 1869 } 1870 1871 _assert_(local_num_ind == this->NumIndependents()); 1872 } 1873 /*}}}*/ 1874 void IoModel::FindConstant(bool* pvalue,const char* constant_name){/*{{{*/ 1875 1876 /*Intermediary*/ 1877 vector<IoConstant*>::iterator iter; 1878 1879 for(iter=constants.begin();iter<constants.end();iter++){ 1880 IoConstant* ioconstant=*iter; 1881 1882 if(strcmp(ioconstant->name,constant_name)==0){ 1883 ioconstant->constant->GetParameterValue(pvalue); 1911 1884 return; 1912 1885 } 1913 1886 } 1914 1887 1915 /*intermediary: */ 1916 int code,vector_layout; 1917 IssmDouble *doublearray = NULL; 1918 int M,N; 1919 1920 /*First of, find the record for the name, and get code of data type: */ 1921 this->SetFilePointerToData(&code, &vector_layout,vector_name); 1922 1923 /*Defaulting only supported for double arrays*/ 1924 if(code!=7) _error_(vector_name<<" is not a double array"); 1925 1926 this->FetchData(&doublearray,&M,&N,vector_name); 1927 1928 for(int i=0;i<elements->Size();i++){ 1929 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 1930 if(!doublearray) element->AddInput(input_enum,&default_value,P0Enum); 1931 else element->InputCreate(doublearray,this,M,N,vector_layout,input_enum,code);//we need i to index into elements. 1932 } 1933 1934 /*Free ressources*/ 1935 xDelete<IssmDouble>(doublearray); 1936 } 1937 /*}}}*/ 1938 void IoModel::FetchDataToInput(Elements* elements,const char* vector_name,int input_enum){/*{{{*/ 1939 1940 /*First, look whether it is not already loaded in this->data*/ 1941 vector<IoData*>::iterator iter; 1942 for(iter=data.begin();iter<data.end();iter++){ 1943 IoData* iodata=*iter; 1944 if(strcmp(iodata->name,vector_name)==0){ 1945 for(int i=0;i<elements->Size();i++){ 1946 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 1947 element->InputCreate(iodata->data,this,iodata->M,iodata->N,iodata->layout,input_enum,iodata->code);//we need i to index into elements. 1948 } 1888 for(vector<IoConstant*>::iterator iter=constants.begin();iter<constants.end();iter++) (*iter)->constant->Echo(); 1889 _error_("Could not find constant \""<<constant_name<<"\""); 1890 } 1891 /*}}}*/ 1892 void IoModel::FindConstant(int* pvalue,const char* constant_name){/*{{{*/ 1893 1894 /*Intermediary*/ 1895 vector<IoConstant*>::iterator iter; 1896 1897 for(iter=constants.begin();iter<constants.end();iter++){ 1898 IoConstant* ioconstant=*iter; 1899 1900 if(strcmp(ioconstant->name,constant_name)==0){ 1901 ioconstant->constant->GetParameterValue(pvalue); 1949 1902 return; 1950 1903 } 1951 1904 } 1952 1905 1953 /*intermediary: */ 1954 int i; 1955 int code,vector_layout; 1956 1957 /*variables being fetched: */ 1958 bool boolean; 1959 int integer; 1960 IssmDouble scalar; 1961 char *string = NULL; 1962 IssmDouble *doublearray = NULL; 1963 int M,N; 1964 1965 /*First of, find the record for the name, and get code of data type: */ 1966 this->SetFilePointerToData(&code, &vector_layout,vector_name); 1967 1968 switch(code){ 1969 case 1: //boolean constant 1970 this->FetchData(&boolean,vector_name); 1971 for(i=0;i<elements->Size();i++){ 1972 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 1973 element->InputUpdateFromConstant(boolean,input_enum); 1974 } 1975 break; 1976 case 2: //integer constant 1977 this->FetchData(&integer,vector_name); 1978 for(i=0;i<elements->Size();i++){ 1979 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 1980 element->InputUpdateFromConstant(integer,input_enum); 1981 } 1982 break; 1983 case 3: //IssmDouble constant 1984 this->FetchData(&scalar,vector_name); 1985 for(i=0;i<elements->Size();i++){ 1986 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 1987 element->InputUpdateFromConstant(scalar,input_enum); 1988 } 1989 break; 1990 case 5: //boolean vector 1991 this->FetchData(&doublearray,&M,&N,vector_name); //we still have a doublearray, because it might include times in transient mode 1992 if(!doublearray) _error_("\""<<vector_name<<"\" not found in binary file"); 1993 for(i=0;i<elements->Size();i++){ 1994 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 1995 element->InputCreate(doublearray,this,M,N,vector_layout,input_enum,code);//we need i to index into elements. 1996 } 1997 break; 1998 case 6: //int vector 1999 this->FetchData(&doublearray,&M,&N,vector_name); //we still have a doublearray, because it might include times in transient mode 2000 if(!doublearray) _error_("\""<<vector_name<<"\" not found in binary file"); 2001 for(i=0;i<elements->Size();i++){ 2002 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 2003 element->InputCreate(doublearray,this,M,N,vector_layout,input_enum,code);//we need i to index into elements. 2004 } 2005 break; 2006 case 7: //IssmDouble vector 2007 this->FetchData(&doublearray,&M,&N,vector_name); 2008 if(!doublearray) _error_("\""<<vector_name<<"\" not found in binary file"); 2009 for(i=0;i<elements->Size();i++){ 2010 Element* element=xDynamicCast<Element*>(elements->GetObjectByOffset(i)); 2011 element->InputCreate(doublearray,this,M,N,vector_layout,input_enum,code);//we need i to index into elements. 2012 } 2013 break; 2014 default: 2015 _error_("data code " << code << " not supported yet (detected while processing \""<<vector_name<<"\")"); 2016 break; 2017 } 2018 /*Free ressources*/ 2019 xDelete<IssmDouble>(doublearray); 2020 xDelete<char>(string); 1906 _error_("Could not find constant \""<<constant_name <<"\""); 1907 } 1908 /*}}}*/ 1909 void IoModel::FindConstant(IssmDouble* pvalue,const char* constant_name){/*{{{*/ 1910 1911 /*Intermediary*/ 1912 vector<IoConstant*>::iterator iter; 1913 1914 for(iter=constants.begin();iter<constants.end();iter++){ 1915 IoConstant* ioconstant=*iter; 1916 1917 if(strcmp(ioconstant->name,constant_name)==0){ 1918 ioconstant->constant->GetParameterValue(pvalue); 1919 return; 1920 } 1921 } 1922 1923 _error_("Could not find constant \""<<constant_name <<"\""); 1924 } 1925 /*}}}*/ 1926 void IoModel::FindConstant(char** pvalue,const char* constant_name){/*{{{*/ 1927 1928 /*Intermediary*/ 1929 vector<IoConstant*>::iterator iter; 1930 1931 for(iter=constants.begin();iter<constants.end();iter++){ 1932 IoConstant* ioconstant=*iter; 1933 1934 if(strcmp(ioconstant->name,constant_name)==0){ 1935 ioconstant->constant->GetParameterValue(pvalue); 1936 return; 1937 } 1938 } 1939 1940 _error_("Could not find constant \""<<constant_name <<"\""); 1941 } 1942 /*}}}*/ 1943 void IoModel::FindConstant(char*** pvalue,int* psize,const char* constant_name){/*{{{*/ 1944 1945 /*Intermediary*/ 1946 vector<IoConstant*>::iterator iter; 1947 1948 for(iter=constants.begin();iter<constants.end();iter++){ 1949 IoConstant* ioconstant=*iter; 1950 1951 if(strcmp(ioconstant->name,constant_name)==0){ 1952 ioconstant->constant->GetParameterValue(pvalue,psize); 1953 return; 1954 } 1955 } 1956 1957 _error_("Could not find constant \""<<constant_name <<"\""); 2021 1958 } 2022 1959 /*}}}*/ … … 2057 1994 } 2058 1995 /*}}}*/ 2059 FILE* IoModel::SetFilePointerToData(int* pcode,int* pvector_type,const char* data_name){/*{{{*/ 2060 2061 int my_rank; 2062 2063 int found = 0; 2064 const char* mddot = "md."; 2065 char* record_name = NULL; 2066 int record_name_size; 2067 int record_length; 2068 int record_code; //1 to 7 number 2069 int vector_type = 0; //nodal or elementary 2070 2071 /*recover my_rank:*/ 2072 my_rank=IssmComm::GetRank(); 2073 _assert_(strncmp(data_name,mddot,3)==0); 2074 2075 /*Go find in the binary file, the position of the data we want to fetch: */ 2076 if(my_rank==0){ 2077 2078 /*First set FILE* position to the beginning of the file: */ 2079 fseek(fid,0,SEEK_SET); 2080 2081 /*Now march through file looking for the correct data identifier: */ 2082 for(;;){ 2083 /*Read size of first string name: */ 2084 if(fread(&record_name_size,sizeof(int),1,fid)==0){ 2085 /*we have reached the end of the file. break: */ 2086 xDelete<char>(record_name); 2087 break; 2088 } 2089 if(record_name_size<3 || record_name_size>80){ 2090 _error_("error while looking in binary file. Found a string of size "<<record_name_size); 2091 } 2092 2093 /*Allocate string of correct size: */ 2094 record_name=xNew<char>(record_name_size+1); 2095 record_name[record_name_size]='\0'; 2096 2097 /*Read record_name: */ 2098 if(fread(record_name,record_name_size*sizeof(char),1,fid)==0){ 2099 /*we have reached the end of the file. break: */ 2100 found=0; 2101 xDelete<char>(record_name); 2102 break; 2103 } 2104 if(strncmp(record_name,mddot,3)!=0){ 2105 _error_("error while reading binary file: record does not start with \"md.\": "<<record_name); 2106 } 2107 2108 /*Is this the record sought for? : */ 2109 if(strcmp(record_name,data_name)==0){ 2110 /*Ok, we have found the correct string. Pass the record length, and read data type code: */ 2111 fseek(fid,sizeof(int),SEEK_CUR); 2112 if(fread(&record_code,sizeof(int),1,fid)!=1) _error_("Could not read record_code"); 2113 2114 /*if record_code points to a vector, get its type (nodal or elementary): */ 2115 if(5<=record_code && record_code<=7){ 2116 if(fread(&vector_type,sizeof(int),1,fid)!=1) _error_("Could not read vector_type"); 2117 } 2118 found=1; 2119 xDelete<char>(record_name); 2120 break; 2121 } 2122 else{ 2123 /*This is not the correct string, read the record length, and use it to skip this record: */ 2124 if(fread(&record_length,sizeof(int),1,fid)!=1) _error_("Could not read record_length"); 2125 /*skip: */ 2126 fseek(fid,record_length,SEEK_CUR); 2127 xDelete<char>(record_name); 2128 } 2129 } 2130 } 2131 ISSM_MPI_Bcast(&found,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 2132 if(!found)_error_("could not find data with name \"" << data_name << "\" in binary file"); 2133 2134 /*Broadcast code and vector type: */ 2135 ISSM_MPI_Bcast(&record_code,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 2136 ISSM_MPI_Bcast(&vector_type,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 2137 2138 /*Assign output pointers:*/ 2139 *pcode=record_code; 2140 if(pvector_type)*pvector_type=vector_type; 2141 2142 return fid; 1996 int IoModel::NumIndependents(void){/*{{{*/ 1997 1998 /*Initialize output*/ 1999 int num_independents = 0; 2000 2001 /*Process constants*/ 2002 for(vector<IoConstant*>::iterator iter=constants.begin();iter<constants.end();iter++){ 2003 if((*iter)->isindependent){ 2004 num_independents+= 1; 2005 } 2006 } 2007 2008 /*Process data*/ 2009 for(vector<IoData*>::iterator iter=data.begin();iter<data.end();iter++){ 2010 if((*iter)->isindependent){ 2011 num_independents+= (*iter)->M*(*iter)->N; 2012 } 2013 } 2014 2015 /*return*/ 2016 return num_independents; 2143 2017 } 2144 2018 /*}}}*/ … … 2284 2158 } 2285 2159 /*}}}*/ 2160 FILE* IoModel::SetFilePointerToData(int* pcode,int* pvector_type,const char* data_name){/*{{{*/ 2161 2162 int my_rank; 2163 2164 int found = 0; 2165 const char* mddot = "md."; 2166 char* record_name = NULL; 2167 int record_name_size; 2168 int record_length; 2169 int record_code; //1 to 7 number 2170 int vector_type = 0; //nodal or elementary 2171 2172 /*recover my_rank:*/ 2173 my_rank=IssmComm::GetRank(); 2174 _assert_(strncmp(data_name,mddot,3)==0); 2175 2176 /*Go find in the binary file, the position of the data we want to fetch: */ 2177 if(my_rank==0){ 2178 2179 /*First set FILE* position to the beginning of the file: */ 2180 fseek(fid,0,SEEK_SET); 2181 2182 /*Now march through file looking for the correct data identifier: */ 2183 for(;;){ 2184 /*Read size of first string name: */ 2185 if(fread(&record_name_size,sizeof(int),1,fid)==0){ 2186 /*we have reached the end of the file. break: */ 2187 xDelete<char>(record_name); 2188 break; 2189 } 2190 if(record_name_size<3 || record_name_size>80){ 2191 _error_("error while looking in binary file. Found a string of size "<<record_name_size); 2192 } 2193 2194 /*Allocate string of correct size: */ 2195 record_name=xNew<char>(record_name_size+1); 2196 record_name[record_name_size]='\0'; 2197 2198 /*Read record_name: */ 2199 if(fread(record_name,record_name_size*sizeof(char),1,fid)==0){ 2200 /*we have reached the end of the file. break: */ 2201 found=0; 2202 xDelete<char>(record_name); 2203 break; 2204 } 2205 if(strncmp(record_name,mddot,3)!=0){ 2206 _error_("error while reading binary file: record does not start with \"md.\": "<<record_name); 2207 } 2208 2209 /*Is this the record sought for? : */ 2210 if(strcmp(record_name,data_name)==0){ 2211 /*Ok, we have found the correct string. Pass the record length, and read data type code: */ 2212 fseek(fid,sizeof(int),SEEK_CUR); 2213 if(fread(&record_code,sizeof(int),1,fid)!=1) _error_("Could not read record_code"); 2214 2215 /*if record_code points to a vector, get its type (nodal or elementary): */ 2216 if(5<=record_code && record_code<=7){ 2217 if(fread(&vector_type,sizeof(int),1,fid)!=1) _error_("Could not read vector_type"); 2218 } 2219 found=1; 2220 xDelete<char>(record_name); 2221 break; 2222 } 2223 else{ 2224 /*This is not the correct string, read the record length, and use it to skip this record: */ 2225 if(fread(&record_length,sizeof(int),1,fid)!=1) _error_("Could not read record_length"); 2226 /*skip: */ 2227 fseek(fid,record_length,SEEK_CUR); 2228 xDelete<char>(record_name); 2229 } 2230 } 2231 } 2232 ISSM_MPI_Bcast(&found,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 2233 if(!found)_error_("could not find data with name \"" << data_name << "\" in binary file"); 2234 2235 /*Broadcast code and vector type: */ 2236 ISSM_MPI_Bcast(&record_code,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 2237 ISSM_MPI_Bcast(&vector_type,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 2238 2239 /*Assign output pointers:*/ 2240 *pcode=record_code; 2241 if(pvector_type)*pvector_type=vector_type; 2242 2243 return fid; 2244 } 2245 /*}}}*/ 2246 void IoModel::StartTrace(bool trace){/*{{{*/ 2247 2248 bool autodiff = false; 2249 bool iscontrol = false; 2250 bool keep=false; 2251 IssmDouble gcTriggerRatio; 2252 IssmDouble gcTriggerMaxSize; 2253 IssmDouble obufsize; 2254 IssmDouble lbufsize; 2255 IssmDouble cbufsize; 2256 IssmDouble tbufsize; 2257 2258 int my_rank=IssmComm::GetRank(); 2259 2260 this->FetchData(&autodiff,"md.autodiff.isautodiff"); 2261 this->FetchData(&iscontrol,"md.inversion.iscontrol"); 2262 2263 if(trace || (autodiff && !iscontrol)){ 2264 #ifdef _HAVE_ADOLC_ 2265 /*Retrieve parameters: */ 2266 this->FetchData(&keep,"md.autodiff.keep"); 2267 int keepTaylors=keep?1:0; 2268 this->FetchData(&gcTriggerRatio,"md.autodiff.gcTriggerRatio"); 2269 this->FetchData(&gcTriggerMaxSize,"md.autodiff.gcTriggerMaxSize"); 2270 this->FetchData(&obufsize,"md.autodiff.obufsize"); 2271 this->FetchData(&lbufsize,"md.autodiff.lbufsize"); 2272 this->FetchData(&cbufsize,"md.autodiff.cbufsize"); 2273 this->FetchData(&tbufsize,"md.autodiff.tbufsize"); 2274 2275 /*Set garbage collection parameters: */ 2276 setStoreManagerControl(reCast<IssmPDouble>(gcTriggerRatio),reCast<size_t>(gcTriggerMaxSize)); 2277 2278 /*Start trace: */ 2279 int skipFileDeletion=1; 2280 trace_on(my_rank,keepTaylors,reCast<size_t>(obufsize),reCast<size_t>(lbufsize),reCast<size_t>(cbufsize),reCast<size_t>(tbufsize),skipFileDeletion); 2281 #endif 2282 } 2283 2284 } 2285 /*}}}*/ -
issm/trunk-jpl/src/c/classes/IoModel.h
r20690 r20810 18 18 class IoConstant { /*holds single IssmDouble, int, bool and char from input*/ 19 19 public: 20 Param* constant; 20 21 bool isindependent; 21 22 char* name; 22 Param* constant;23 23 24 24 ~IoConstant(); … … 33 33 class IoData { /*holds temporary data (array), memory intensive*/ 34 34 public: 35 int code; 36 IssmDouble* data; 35 37 bool isindependent; 38 int layout; 39 int M,N; 36 40 char* name; 37 int M,N;38 int code;39 int layout;40 IssmDouble* data;41 41 42 42 ~IoData(); … … 67 67 68 68 /*Mesh properties and connectivity tables*/ 69 int domaindim; 69 70 int domaintype; 70 int domaindim;71 int meshelementtype;72 int numberofvertices;73 int numberofelements;74 int numberoffaces;75 int numberofedges;76 int facescols;77 71 int *elements; 78 int *faces;79 72 int *edges; 80 73 int *elementtoedgeconnectivity; 81 74 int *elementtofaceconnectivity; 75 int *faces; 76 int facescols; 77 int meshelementtype; 78 int *numbernodetoelementconnectivity; 79 int numberofedges; 80 int numberofelements; 81 int numberoffaces; 82 int numberofvertices; 82 83 int *singlenodetoelementconnectivity; 83 int *numbernodetoelementconnectivity;84 84 85 85 /*Data to synchronize through low level object drivers: */ 86 int constraintcounter; //keep track of how many constraints are being created in each analysis 87 int loadcounter; //keep track of how many loads are being created in each analysis 86 88 int nodecounter; //keep track of how many nodes are being created in each analysis 87 int loadcounter; //keep track of how many loads are being created in each analysis88 int constraintcounter; //keep track of how many constraints are being created in each analysis89 89 90 90 /*Methods*/ … … 98 98 void AddData(IoData* data_in); 99 99 void AddDataIndependent(IoData* data_in); 100 void FetchIndependentConstant(int* pXcount,IssmPDouble* X,const char* name); 101 void FetchIndependentData(int* pXcount,IssmPDouble* X,const char* name); 102 void FillIndependents(IssmDouble* xp); 100 103 void FindConstant(bool* pvalue,const char* constant_name); 101 104 void FindConstant(int* pvalue,const char* constant_name); … … 103 106 void FindConstant(char **pvalue,const char* constant_name); 104 107 void FindConstant(char ***pvalue,int* psize,const char* constant_name); 105 void FetchIndependentConstant(int* pXcount,IssmPDouble* X,const char* name);106 void FetchIndependentData(int* pXcount,IssmPDouble* X,const char* name);107 108 int NumIndependents(); 108 void FillIndependents(IssmDouble* xp);109 109 110 110 /*Input/Output*/ … … 112 112 Param *CopyConstantObject(const char* constant_name,int param_enum); 113 113 IssmDouble *Data(const char* data_name); 114 void DeclareIndependents(bool trace,IssmPDouble* X); 114 115 void DeleteData(int num,...); 115 116 void DeleteData(IssmDouble* vector,const char* data_name); … … 123 124 void FetchData(IssmDouble** pscalarmatrix,int* pM,int* pN,const char* data_name); 124 125 void FetchData(IssmDouble*** pmatrixarray,int** pmdims,int** pndims, int* pnumrecords,const char* data_name); 126 void FetchData(Option **poption,int index); 127 void FetchData(int num,...); 128 void FetchDataToInput(Elements* elements,const char* vector_name,int input_enum); 129 void FetchDataToInput(Elements* elements,const char* vector_name,int input_enum,IssmDouble default_value); 130 void FetchIndependent(const char* dependent_name); 125 131 void FetchMultipleData(char*** pstringarray,int* pnumstrings,const char* data_name); 126 132 void FetchMultipleData(IssmDouble*** pmatrixarray,int** pmdims,int** pndims, int* pnumrecords,const char* data_name); … … 128 134 void FetchMultipleData(int** pvector, int* pnum_instances,const char* data_name); 129 135 void FetchMultipleData(IssmDouble** pvector, int* pnum_instances,const char* data_name); 130 void FetchData(Option **poption,int index);131 void FetchData(int num,...);132 void FetchDataToInput(Elements* elements,const char* vector_name,int input_enum);133 void FetchDataToInput(Elements* elements,const char* vector_name,int input_enum,IssmDouble default_value);134 136 void LastIndex(int *pindex); 137 fpos_t* SetFilePointersToData(int** pcodes,int** pvector_types, int* pnum_instances, const char* data_name); 135 138 FILE* SetFilePointerToData(int* pcode,int* pvector_type, const char* data_name); 136 fpos_t* SetFilePointersToData(int** pcodes,int** pvector_types, int* pnum_instances, const char* data_name);137 void DeclareIndependents(bool trace,IssmPDouble* X);138 139 void StartTrace(bool trace); 139 void FetchIndependent(const char* dependent_name);140 140 }; 141 141 -
issm/trunk-jpl/src/c/classes/Masscon.h
r19198 r20810 54 54 /*}}}*/ 55 55 /*Object virtual function resolutoin: */ 56 Object* copy() {/*{{{*/ 57 Masscon* mf = new Masscon(this->name,this->definitionenum,this->levelset,this->M); 58 return (Object*) mf; 59 } 60 /*}}}*/ 61 void DeepEcho(void){/*{{{*/ 62 this->Echo(); 63 } 64 /*}}}*/ 56 65 void Echo(void){/*{{{*/ 57 66 _printf_(" Masscon: " << this->name << " " << this->definitionenum << "\n"); … … 60 69 } 61 70 /*}}}*/ 62 void DeepEcho(void){/*{{{*/63 this->Echo();64 }65 /*}}}*/66 71 int Id(void){/*{{{*/ 67 72 return -1; 68 }69 /*}}}*/70 int ObjectEnum(void){/*{{{*/71 return MassconEnum;72 }73 /*}}}*/74 Object* copy() {/*{{{*/75 Masscon* mf = new Masscon(this->name,this->definitionenum,this->levelset,this->M);76 return (Object*) mf;77 73 } 78 74 /*}}}*/ … … 81 77 } 82 78 /*}}}*/ 79 int ObjectEnum(void){/*{{{*/ 80 return MassconEnum; 81 } 82 /*}}}*/ 83 83 /*Definition virtual function resolutoin: */ 84 int DefinitionEnum(){/*{{{*/ 85 86 return this->definitionenum; 87 } 88 /*}}}*/ 84 89 char* Name(){/*{{{*/ 85 90 … … 88 93 89 94 return name2; 90 }91 /*}}}*/92 int DefinitionEnum(){/*{{{*/93 94 return this->definitionenum;95 95 } 96 96 /*}}}*/ -
issm/trunk-jpl/src/c/classes/Massconaxpby.h
r19198 r20810 63 63 /*}}}*/ 64 64 /*Object virtual function resolutoin: */ 65 Object* copy() {/*{{{*/ 66 Massconaxpby* mf = new Massconaxpby(this->name,this->definitionenum,this->namex,this->namey, this->alpha, this->beta); 67 return (Object*) mf; 68 } 69 /*}}}*/ 70 void DeepEcho(void){/*{{{*/ 71 this->Echo(); 72 } 73 /*}}}*/ 65 74 void Echo(void){/*{{{*/ 66 75 _printf_(" Massconaxpby: " << this->name << " " << this->definitionenum << "\n"); … … 71 80 } 72 81 /*}}}*/ 73 void DeepEcho(void){/*{{{*/74 this->Echo();75 }76 /*}}}*/77 82 int Id(void){/*{{{*/ 78 83 return -1; 79 }80 /*}}}*/81 int ObjectEnum(void){/*{{{*/82 return MassconaxpbyEnum;83 }84 /*}}}*/85 Object* copy() {/*{{{*/86 Massconaxpby* mf = new Massconaxpby(this->name,this->definitionenum,this->namex,this->namey, this->alpha, this->beta);87 return (Object*) mf;88 84 } 89 85 /*}}}*/ … … 92 88 } 93 89 /*}}}*/ 90 int ObjectEnum(void){/*{{{*/ 91 return MassconaxpbyEnum; 92 } 93 /*}}}*/ 94 94 /*Definition virtual function resolutoin: */ 95 int DefinitionEnum(){/*{{{*/ 96 97 return this->definitionenum; 98 } 99 /*}}}*/ 95 100 char* Name(){/*{{{*/ 96 101 … … 99 104 100 105 return name2; 101 }102 /*}}}*/103 int DefinitionEnum(){/*{{{*/104 105 return this->definitionenum;106 106 } 107 107 /*}}}*/ -
issm/trunk-jpl/src/c/classes/Massfluxatgate.h
r19198 r20810 94 94 95 95 /*Object virtual function resolutoin: */ 96 Object* copy() {/*{{{*/ 97 return new Massfluxatgate(this->name,this->definitionenum,this->numsegments,this->x1,this->y1,this->x2,this->y2,this->elements); 98 } 99 /*}}}*/ 100 void DeepEcho(void){/*{{{*/ 101 this->Echo(); 102 } 103 /*}}}*/ 96 104 void Echo(void){/*{{{*/ 97 105 _printf_(" Massfluxatgate: " << name << " " << this->definitionenum << "\n"); … … 105 113 } 106 114 /*}}}*/ 107 void DeepEcho(void){/*{{{*/108 this->Echo();109 }110 /*}}}*/111 115 int Id(void){/*{{{*/ 112 116 return -1; … … 117 121 } 118 122 /*}}}*/ 119 Object* copy() {/*{{{*/120 return new Massfluxatgate(this->name,this->definitionenum,this->numsegments,this->x1,this->y1,this->x2,this->y2,this->elements);121 }122 /*}}}*/123 123 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){/*{{{*/ 124 124 _error_("not implemented yet!"); … … 126 126 /*}}}*/ 127 127 /*Definition virtual function resolutoin: */ 128 int DefinitionEnum(){/*{{{*/ 129 130 return this->definitionenum; 131 } 132 /*}}}*/ 128 133 char* Name(){/*{{{*/ 129 134 … … 132 137 133 138 return name2; 134 }135 /*}}}*/136 int DefinitionEnum(){/*{{{*/137 138 return this->definitionenum;139 139 } 140 140 /*}}}*/ -
issm/trunk-jpl/src/c/classes/Misfit.h
r19198 r20810 25 25 26 26 int definitionenum; 27 bool local; 28 int model_enum; 27 29 char* name; 28 int model_enum;29 30 int observation_enum; 31 char* timeinterpolation; 30 32 int weights_enum; 31 char* timeinterpolation;32 bool local;33 33 34 int lock; // if lock is on, we just return the value stored in "misfit". this is used so we don't compute misfit past the final_time 34 35 IssmDouble misfit; //value carried over in time. 35 int lock; // if lock is on, we just return the value stored in "misfit". this is used so we don't compute misfit past the final_time36 36 37 37 /*Misfit constructors, destructors :*/ … … 76 76 /*}}}*/ 77 77 /*Object virtual function resolutoin: */ 78 Object* copy() {/*{{{*/ 79 Misfit* mf = new Misfit(this->name,this->definitionenum, this->model_enum,this->observation_enum,this->timeinterpolation,this->local,this->weights_enum); 80 mf->misfit=this->misfit; 81 mf->lock=this->lock; 82 return (Object*) mf; 83 } 84 /*}}}*/ 85 void DeepEcho(void){/*{{{*/ 86 this->Echo(); 87 } 88 /*}}}*/ 78 89 void Echo(void){/*{{{*/ 79 90 _printf_(" Misfit: " << name << " " << this->definitionenum << "\n"); … … 85 96 } 86 97 /*}}}*/ 87 void DeepEcho(void){/*{{{*/88 this->Echo();89 }90 /*}}}*/91 98 int Id(void){/*{{{*/ 92 99 return -1; 93 }94 /*}}}*/95 int ObjectEnum(void){/*{{{*/96 return MisfitEnum;97 }98 /*}}}*/99 Object* copy() {/*{{{*/100 Misfit* mf = new Misfit(this->name,this->definitionenum, this->model_enum,this->observation_enum,this->timeinterpolation,this->local,this->weights_enum);101 mf->misfit=this->misfit;102 mf->lock=this->lock;103 return (Object*) mf;104 100 } 105 101 /*}}}*/ … … 108 104 } 109 105 /*}}}*/ 106 int ObjectEnum(void){/*{{{*/ 107 return MisfitEnum; 108 } 109 /*}}}*/ 110 110 /*Definition virtual function resolutoin: */ 111 int DefinitionEnum(){/*{{{*/ 112 113 return this->definitionenum; 114 } 115 /*}}}*/ 111 116 char* Name(){/*{{{*/ 112 117 … … 115 120 116 121 return name2; 117 }118 /*}}}*/119 int DefinitionEnum(){/*{{{*/120 121 return this->definitionenum;122 122 } 123 123 /*}}}*/ -
issm/trunk-jpl/src/c/classes/Nodalvalue.h
r20038 r20810 27 27 28 28 int definitionenum; 29 int model_enum; 29 30 char* name; 30 int model_enum;31 31 int node; 32 32 … … 56 56 /*}}}*/ 57 57 /*Object virtual function resolutoin: */ 58 Object* copy() {/*{{{*/ 59 Nodalvalue* mf = new Nodalvalue(this->name,this->definitionenum, this->model_enum,this->node); 60 return (Object*) mf; 61 } 62 /*}}}*/ 63 void DeepEcho(void){/*{{{*/ 64 this->Echo(); 65 } 66 /*}}}*/ 58 67 void Echo(void){/*{{{*/ 59 68 _printf_(" Nodalvalue: " << name << " " << this->definitionenum << "\n"); … … 62 71 } 63 72 /*}}}*/ 64 void DeepEcho(void){/*{{{*/65 this->Echo();66 }67 /*}}}*/68 73 int Id(void){/*{{{*/ 69 74 return -1; 70 }71 /*}}}*/72 int ObjectEnum(void){/*{{{*/73 return NodalvalueEnum;74 }75 /*}}}*/76 Object* copy() {/*{{{*/77 Nodalvalue* mf = new Nodalvalue(this->name,this->definitionenum, this->model_enum,this->node);78 return (Object*) mf;79 75 } 80 76 /*}}}*/ … … 83 79 } 84 80 /*}}}*/ 81 int ObjectEnum(void){/*{{{*/ 82 return NodalvalueEnum; 83 } 84 /*}}}*/ 85 85 /*Definition virtual function resolutoin: */ 86 int DefinitionEnum(){/*{{{*/ 87 88 return this->definitionenum; 89 } 90 /*}}}*/ 86 91 char* Name(){/*{{{*/ 87 92 … … 90 95 91 96 return name2; 92 }93 /*}}}*/94 int DefinitionEnum(){/*{{{*/95 96 return this->definitionenum;97 97 } 98 98 /*}}}*/ -
issm/trunk-jpl/src/c/classes/Node.cpp
r20690 r20810 165 165 166 166 /*Object virtual functions definitions:*/ 167 void Node::DeepEcho(void){/*{{{*/ 168 169 _printf_("Node:\n"); 170 _printf_(" id: " << id << "\n"); 171 _printf_(" sid: " << sid << "\n"); 172 _printf_(" analysis_enum: " << EnumToStringx(analysis_enum) << "\n"); 173 _printf_(" approximation: " << EnumToStringx(approximation) << "\n"); 174 _printf_(" indexingupdate: " << indexingupdate << "\n"); 175 indexing.DeepEcho(); 176 177 } 178 /*}}}*/ 167 179 void Node::Echo(void){/*{{{*/ 168 180 … … 177 189 } 178 190 /*}}}*/ 179 void Node::DeepEcho(void){/*{{{*/180 181 _printf_("Node:\n");182 _printf_(" id: " << id << "\n");183 _printf_(" sid: " << sid << "\n");184 _printf_(" analysis_enum: " << EnumToStringx(analysis_enum) << "\n");185 _printf_(" approximation: " << EnumToStringx(approximation) << "\n");186 _printf_(" indexingupdate: " << indexingupdate << "\n");187 indexing.DeepEcho();188 189 }190 /*}}}*/191 191 int Node::Id(void){ return id; }/*{{{*/ 192 192 /*}}}*/ … … 199 199 200 200 /*Node management:*/ 201 void Node::GetCoordinateSystem(IssmDouble* coord_system_out){/*{{{*/ 202 203 /*Copy coord_system*/ 204 for(int k=0;k<3;k++) for(int l=0;l<3;l++) coord_system_out[3*k+l]=this->coord_system[k][l]; 205 206 } 207 /*}}}*/ 201 208 int Node::GetDof(int dofindex,int setenum){/*{{{*/ 202 209 … … 380 387 } 381 388 /*}}}*/ 382 int Node::Sid(void){/*{{{*/383 return sid;384 }385 /*}}}*/386 int Node::Lid(void){/*{{{*/387 return lid;388 }389 /*}}}*/390 void Node::GetCoordinateSystem(IssmDouble* coord_system_out){/*{{{*/391 392 /*Copy coord_system*/393 for(int k=0;k<3;k++) for(int l=0;l<3;l++) coord_system_out[3*k+l]=this->coord_system[k][l];394 395 }396 /*}}}*/397 389 bool Node::InAnalysis(int in_analysis_enum){/*{{{*/ 398 390 if (in_analysis_enum==this->analysis_enum) return true; … … 400 392 } 401 393 /*}}}*/ 394 int Node::Lid(void){/*{{{*/ 395 return lid; 396 } 397 /*}}}*/ 398 int Node::Sid(void){/*{{{*/ 399 return sid; 400 } 401 /*}}}*/ 402 402 403 403 /*Node numerics:*/ 404 void Node::Activate(void){/*{{{*/ 405 406 if(!IsActive() && !this->indexing.freeze){ 407 this->indexingupdate = true; 408 indexing.Activate(); 409 } 410 411 } 412 /*}}}*/ 404 413 void Node::ApplyConstraint(int dof,IssmDouble value){/*{{{*/ 405 414 … … 408 417 DofInSSet(dof); 409 418 this->indexing.svalues[dof]=value; 410 }411 /*}}}*/412 bool Node::RequiresDofReindexing(void){/*{{{*/413 414 return this->indexingupdate;415 416 }417 /*}}}*/418 void Node::ReindexingDone(void){/*{{{*/419 420 this->indexingupdate = false;421 422 }423 /*}}}*/424 void Node::RelaxConstraint(int dof){/*{{{*/425 426 /*Dof should be added to the f-set, and taken out of the s-set:*/427 DofInFSet(dof);428 this->indexing.svalues[dof]=0.;429 419 } 430 420 /*}}}*/ … … 456 446 } 457 447 /*}}}*/ 448 void Node::Deactivate(void){/*{{{*/ 449 450 if(IsActive() && !this->indexing.freeze){ 451 this->indexingupdate = true; 452 indexing.Deactivate(); 453 } 454 455 } 456 /*}}}*/ 457 void Node::DofInFSet(int dof){/*{{{*/ 458 459 /*Put dof for this node into the f set (ie, this dof will NOT be constrained 460 * to a fixed value during computations. */ 461 _assert_(dof<this->indexing.gsize); 462 463 if(this->indexing.f_set[dof] == 0){ 464 if(this->indexing.freeze) _error_("Cannot change dof of frozen node"); 465 this->indexingupdate = true; 466 this->indexing.f_set[dof]=1; 467 this->indexing.s_set[dof]=0; 468 } 469 } 470 /*}}}*/ 458 471 void Node::DofInSSet(int dof){/*{{{*/ 459 472 … … 470 483 } 471 484 /*}}}*/ 472 void Node::DofInFSet(int dof){/*{{{*/473 474 /*Put dof for this node into the f set (ie, this dof will NOT be constrained475 * to a fixed value during computations. */476 _assert_(dof<this->indexing.gsize);477 478 if(this->indexing.f_set[dof] == 0){479 if(this->indexing.freeze) _error_("Cannot change dof of frozen node");480 this->indexingupdate = true;481 this->indexing.f_set[dof]=1;482 this->indexing.s_set[dof]=0;483 }484 }485 /*}}}*/486 485 void Node::FreezeDof(int dof){/*{{{*/ 487 486 … … 489 488 //FIXME: for now we don't want this element to change so we use freeze 490 489 this->indexing.freeze =true; 491 492 }493 /*}}}*/494 void Node::Deactivate(void){/*{{{*/495 496 if(IsActive() && !this->indexing.freeze){497 this->indexingupdate = true;498 indexing.Deactivate();499 }500 501 }502 /*}}}*/503 void Node::HardDeactivate(void){/*{{{*/504 505 this->indexing.Deactivate();506 this->indexing.freeze =true;507 508 }509 /*}}}*/510 void Node::Activate(void){/*{{{*/511 512 if(!IsActive() && !this->indexing.freeze){513 this->indexingupdate = true;514 indexing.Activate();515 }516 517 }518 /*}}}*/519 bool Node::IsActive(void){/*{{{*/520 521 return indexing.active;522 490 523 491 } … … 575 543 } 576 544 /*}}}*/ 545 void Node::HardDeactivate(void){/*{{{*/ 546 547 this->indexing.Deactivate(); 548 this->indexing.freeze =true; 549 550 } 551 /*}}}*/ 552 bool Node::IsActive(void){/*{{{*/ 553 554 return indexing.active; 555 556 } 557 /*}}}*/ 577 558 int Node::IsClone(){/*{{{*/ 578 559 579 560 return indexing.clone; 561 562 } 563 /*}}}*/ 564 void Node::ReindexingDone(void){/*{{{*/ 565 566 this->indexingupdate = false; 567 568 } 569 /*}}}*/ 570 void Node::RelaxConstraint(int dof){/*{{{*/ 571 572 /*Dof should be added to the f-set, and taken out of the s-set:*/ 573 DofInFSet(dof); 574 this->indexing.svalues[dof]=0.; 575 } 576 /*}}}*/ 577 bool Node::RequiresDofReindexing(void){/*{{{*/ 578 579 return this->indexingupdate; 580 580 581 581 } … … 738 738 } 739 739 else _error_("set of enum type " << EnumToStringx(setenum) << " not supported yet!"); 740 } 741 /*}}}*/ 742 void Node::SetClone(int* minranks){/*{{{*/ 743 744 int my_rank; 745 746 /*recover my_rank:*/ 747 my_rank=IssmComm::GetRank(); 748 749 if (minranks[sid]==my_rank){ 750 indexing.clone=false; 751 } 752 else{ 753 /*!there is a cpu with lower rank that has the same node, 754 therefore, I am a clone*/ 755 indexing.clone=true; 756 } 740 757 } 741 758 /*}}}*/ … … 788 805 } 789 806 /*}}}*/ 790 void Node::SetClone(int* minranks){/*{{{*/791 792 int my_rank;793 794 /*recover my_rank:*/795 my_rank=IssmComm::GetRank();796 797 if (minranks[sid]==my_rank){798 indexing.clone=false;799 }800 else{801 /*!there is a cpu with lower rank that has the same node,802 therefore, I am a clone*/803 indexing.clone=true;804 }805 }806 /*}}}*/807 807 808 808 /*Methods inherent to Node: */ 809 int* GetGlobalDofList(Node** nodes,int numnodes,int setenum,int approximation){/*{{{*/ 810 811 int i,numdof,count; 812 int* ndof_list=NULL; 813 int *doflist = NULL; 814 815 if(numnodes){ 816 817 /*Allocate:*/ 818 ndof_list=xNew<int>(numnodes); 819 820 /*First, figure out size of doflist: */ 821 numdof=0; 822 for(i=0;i<numnodes;i++){ 823 ndof_list[i]=nodes[i]->GetNumberOfDofs(approximation,setenum); 824 numdof+=ndof_list[i]; 825 } 826 827 if(numdof){ 828 /*Allocate: */ 829 doflist=xNew<int>(numdof); 830 831 /*Populate: */ 832 count=0; 833 for(i=0;i<numnodes;i++){ 834 nodes[i]->GetDofList(&doflist[count],approximation,setenum); 835 count+=ndof_list[i]; 836 } 837 } 838 else doflist=NULL; 839 } 840 /*Free ressources:*/ 841 xDelete<int>(ndof_list); 842 843 return doflist; 844 } 845 /*}}}*/ 809 846 int* GetLocalDofList(Node** nodes,int numnodes,int setenum,int approximation){ /*{{{*/ 810 847 … … 864 901 } 865 902 /*}}}*/ 866 int* GetGlobalDofList(Node** nodes,int numnodes,int setenum,int approximation){/*{{{*/867 868 int i,numdof,count;869 int* ndof_list=NULL;870 int *doflist = NULL;871 872 if(numnodes){873 874 /*Allocate:*/875 ndof_list=xNew<int>(numnodes);876 877 /*First, figure out size of doflist: */878 numdof=0;879 for(i=0;i<numnodes;i++){880 ndof_list[i]=nodes[i]->GetNumberOfDofs(approximation,setenum);881 numdof+=ndof_list[i];882 }883 884 if(numdof){885 /*Allocate: */886 doflist=xNew<int>(numdof);887 888 /*Populate: */889 count=0;890 for(i=0;i<numnodes;i++){891 nodes[i]->GetDofList(&doflist[count],approximation,setenum);892 count+=ndof_list[i];893 }894 }895 else doflist=NULL;896 }897 /*Free ressources:*/898 xDelete<int>(ndof_list);899 900 return doflist;901 }902 /*}}}*/903 903 int GetNumberOfDofs(Node** nodes,int numnodes,int setenum,int approximation){/*{{{*/ 904 904 -
issm/trunk-jpl/src/c/classes/Node.h
r20462 r20810 34 34 int lid; // "local" id (rank of this node in current partition) 35 35 36 int analysis_enum; 37 IssmDouble coord_system[3][3]; 36 38 bool indexingupdate; 37 39 DofIndexing indexing; 38 int analysis_enum;39 IssmDouble coord_system[3][3];40 40 41 41 /*Node constructors, destructors*/ … … 45 45 46 46 /*Object virtual functions definitions:*/ 47 Object *copy(); 48 void DeepEcho(); 47 49 void Echo(); 48 void DeepEcho();49 50 int Id(); 51 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction); 50 52 int ObjectEnum(); 51 Object *copy();52 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction);53 53 54 54 /*Node numerical routines*/ 55 void Activate(void); 56 void ApplyConstraint(int dof,IssmDouble value); 55 57 void CreateNodalConstraints(Vector<IssmDouble>* ys); 56 void SetCurrentConfiguration(DataSet* nodes,Vertices* vertices); 57 int Sid(void); 58 int Lid(void); 58 void Deactivate(void); 59 void DistributeDofs(int* pdofcount,int setenum); 60 void DofInFSet(int dof); 61 void DofInSSet(int dof); 62 void FreezeDof(int dof); 63 int GetApproximation(); 59 64 void GetCoordinateSystem(IssmDouble* coord_system_out); 60 bool InAnalysis(int analysis_enum);61 int GetApproximation();62 int GetNumberOfDofs(int approximation_enum,int setenum);63 int IsClone();64 void ApplyConstraint(int dof,IssmDouble value);65 void RelaxConstraint(int dof);66 void DofInSSet(int dof);67 void DofInFSet(int dof);68 65 int GetDof(int dofindex,int setenum); 69 66 void GetDofList(int* poutdoflist,int approximation_enum,int setenum); 70 67 void GetLocalDofList(int* poutdoflist,int approximation_enum,int setenum); 71 void FreezeDof(int dof); 68 int GetNumberOfDofs(int approximation_enum,int setenum); 69 void HardDeactivate(void); 70 bool InAnalysis(int analysis_enum); 72 71 bool IsActive(void); 73 void Activate(void); 74 void Deactivate(void); 75 void HardDeactivate(void); 76 void ReindexingDone(void); 77 bool RequiresDofReindexing(void); 72 int IsClone(); 78 73 int IsFloating(); 79 74 int IsGrounded(); 75 int Lid(void); 76 void OffsetDofs(int dofcount,int setenum); 77 void ReindexingDone(void); 78 void RelaxConstraint(int dof); 79 bool RequiresDofReindexing(void); 80 void SetClone(int* minranks); 81 void SetCurrentConfiguration(DataSet* nodes,Vertices* vertices); 82 void ShowTrueDofs(int* truerows,int ncols,int setenum); 83 int Sid(void); 84 void UpdateCloneDofs(int* alltruerows,int ncols,int setenum); 80 85 void VecMerge(Vector<IssmDouble>* ug, IssmDouble* vector_serial,int setenum); 81 86 void VecReduce(Vector<IssmDouble>* vector, IssmDouble* ug_serial,int setnum); 82 void DistributeDofs(int* pdofcount,int setenum);83 void OffsetDofs(int dofcount,int setenum);84 void ShowTrueDofs(int* truerows,int ncols,int setenum);85 void UpdateCloneDofs(int* alltruerows,int ncols,int setenum);86 void SetClone(int* minranks);87 87 }; 88 88 89 89 /*Methods inherent to Node: */ 90 int* GetGlobalDofList(Node** nodes,int numnodes,int setenum,int approximation); 90 91 int* GetLocalDofList(Node** nodes,int numnodes,int setenum,int approximation); 91 int* GetGlobalDofList(Node** nodes,int numnodes,int setenum,int approximation);92 92 int GetNumberOfDofs(Node** nodes,int numnodes,int setenum,int approximation); 93 93 -
issm/trunk-jpl/src/c/classes/Nodes.cpp
r19198 r20810 164 164 } 165 165 /*}}}*/ 166 int Nodes::MaxNumDofs(int analysis_type,int setenum){/*{{{*/167 168 int max=0;169 int allmax,numdofs;170 171 /*Now go through all nodes, and get how many dofs they own, unless they are clone nodes: */172 for(int i=0;i<this->Size();i++){173 174 Node* node=xDynamicCast<Node*>(this->GetObjectByOffset(i));175 176 /*Check that this node corresponds to our analysis currently being carried out: */177 if (node->InAnalysis(analysis_type)){178 179 numdofs=node->GetNumberOfDofs(NoneApproximationEnum,setenum);180 if(numdofs>max)max=numdofs;181 }182 }183 184 /*Grab max of all cpus: */185 ISSM_MPI_Allreduce((void*)&max,(void*)&allmax,1,ISSM_MPI_INT,ISSM_MPI_MAX,IssmComm::GetComm());186 max=allmax;187 188 return max;189 }190 /*}}}*/191 166 int Nodes::MaximumId(){/*{{{*/ 192 167 … … 219 194 } 220 195 /*}}}*/ 196 int Nodes::MaxNumDofs(int analysis_type,int setenum){/*{{{*/ 197 198 int max=0; 199 int allmax,numdofs; 200 201 /*Now go through all nodes, and get how many dofs they own, unless they are clone nodes: */ 202 for(int i=0;i<this->Size();i++){ 203 204 Node* node=xDynamicCast<Node*>(this->GetObjectByOffset(i)); 205 206 /*Check that this node corresponds to our analysis currently being carried out: */ 207 if (node->InAnalysis(analysis_type)){ 208 209 numdofs=node->GetNumberOfDofs(NoneApproximationEnum,setenum); 210 if(numdofs>max)max=numdofs; 211 } 212 } 213 214 /*Grab max of all cpus: */ 215 ISSM_MPI_Allreduce((void*)&max,(void*)&allmax,1,ISSM_MPI_INT,ISSM_MPI_MAX,IssmComm::GetComm()); 216 max=allmax; 217 218 return max; 219 } 220 /*}}}*/ 221 221 int Nodes::NumberOfDofs(int analysis_type,int setenum){/*{{{*/ 222 222 -
issm/trunk-jpl/src/c/classes/Nodes.h
r15861 r20810 27 27 void DistributeDofs(int analysis_type,int SETENUM); 28 28 void FlagClones(int analysis_type); 29 bool RequiresDofReindexing(int analysis_type);29 int MaximumId(void); 30 30 int MaxNumDofs(int analysis_type,int setenum); 31 int MaximumId(void);32 31 int NumberOfDofs(int analysis_type,int setenum); 33 32 int NumberOfDofsLocal(int analysis_type,int setenum); … … 35 34 int NumberOfNodes(void); 36 35 void Ranks(int* ranks,int analysis_type); 36 bool RequiresDofReindexing(int analysis_type); 37 37 38 38 }; -
issm/trunk-jpl/src/c/classes/Profiler.cpp
r20637 r20810 41 41 42 42 /*Object virtual functions definitions:*/ 43 void Profiler::DeepEcho(void){/*{{{*/ 44 45 this->Echo(); 46 47 } 48 /*}}}*/ 43 49 void Profiler::Echo(void){/*{{{*/ 44 50 … … 49 55 } 50 56 /*}}}*/ 51 void Profiler::DeepEcho(void){/*{{{*/52 53 this->Echo();54 55 }56 /*}}}*/57 57 int Profiler::Id(void){ return -1; }/*{{{*/ 58 /*}}}*/59 int Profiler::ObjectEnum(void){/*{{{*/60 61 return ProfilerEnum;62 63 }64 58 /*}}}*/ 65 59 void Profiler::Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){ /*{{{*/ … … 76 70 77 71 } /*}}}*/ 72 int Profiler::ObjectEnum(void){/*{{{*/ 73 74 return ProfilerEnum; 75 76 } 77 /*}}}*/ 78 78 79 79 /*Profiler routines:*/ 80 IssmDouble Profiler::DeltaFlops(int inittag, int finaltag){/*{{{*/ 81 82 /*Get initial flops*/ 83 _assert_(inittag>=0); 84 _assert_(inittag<MAXIMUMSIZE); 85 if(xIsNan<IssmDouble>(this->flops[inittag])) _error_("Tag not set"); 86 IssmDouble init = this->flops[inittag]; 87 88 /*Get final flops*/ 89 _assert_(finaltag>=0); 90 _assert_(finaltag<MAXIMUMSIZE); 91 if(xIsNan<IssmDouble>(this->flops[finaltag])) _error_("Tag not set"); 92 IssmDouble final = this->flops[finaltag]; 93 94 return final-init; 95 } 96 /*}}}*/ 97 IssmDouble Profiler::DeltaTime(int inittag, int finaltag){/*{{{*/ 98 99 /*Get initial time*/ 100 _assert_(inittag>=0); 101 _assert_(inittag<MAXIMUMSIZE); 102 if(xIsNan<IssmDouble>(this->time[inittag])) _error_("Tag not set"); 103 IssmDouble init = this->time[inittag]; 104 105 /*Get final time*/ 106 _assert_(finaltag>=0); 107 _assert_(finaltag<MAXIMUMSIZE); 108 if(xIsNan<IssmDouble>(this->time[finaltag])) _error_("Tag not set"); 109 IssmDouble final = this->time[finaltag]; 110 111 #ifdef _HAVE_MPI_ 112 return final-init; 113 #else 114 return (final-init)/CLOCKS_PER_SEC; 115 #endif 116 } 117 /*}}}*/ 118 int Profiler::DeltaTimeModHour(int inittag, int finishtag){/*{{{*/ 119 120 IssmDouble delta = this->DeltaTime(inittag,finishtag); 121 return int((reCast<int,IssmDouble>(delta))/3600); 122 123 } 124 /*}}}*/ 125 int Profiler::DeltaTimeModMin(int inittag, int finishtag){/*{{{*/ 126 127 IssmDouble delta = this->DeltaTime(inittag,finishtag); 128 return int(int(reCast<int,IssmDouble>(delta))%3600/60); 129 } 130 /*}}}*/ 131 int Profiler::DeltaTimeModSec(int inittag, int finishtag){/*{{{*/ 132 133 IssmDouble delta = this->DeltaTime(inittag,finishtag); 134 return int(reCast<int,IssmDouble>(delta)%60); 135 } 136 /*}}}*/ 137 IssmDouble Profiler::Memory(int tag){/*{{{*/ 138 139 /*Get initial flops*/ 140 _assert_(tag>=0); 141 _assert_(tag<MAXIMUMSIZE); 142 if(xIsNan<IssmDouble>(this->flops[tag])) _error_("Tag not set"); 143 return this->memory[tag]; 144 } 145 /*}}}*/ 80 146 void Profiler::Tag(int tagenum,bool dontmpisync){/*{{{*/ 81 147 … … 117 183 } 118 184 /*}}}*/ 119 IssmDouble Profiler::DeltaTime(int inittag, int finaltag){/*{{{*/120 121 /*Get initial time*/122 _assert_(inittag>=0);123 _assert_(inittag<MAXIMUMSIZE);124 if(xIsNan<IssmDouble>(this->time[inittag])) _error_("Tag not set");125 IssmDouble init = this->time[inittag];126 127 /*Get final time*/128 _assert_(finaltag>=0);129 _assert_(finaltag<MAXIMUMSIZE);130 if(xIsNan<IssmDouble>(this->time[finaltag])) _error_("Tag not set");131 IssmDouble final = this->time[finaltag];132 133 #ifdef _HAVE_MPI_134 return final-init;135 #else136 return (final-init)/CLOCKS_PER_SEC;137 #endif138 }139 /*}}}*/140 IssmDouble Profiler::DeltaFlops(int inittag, int finaltag){/*{{{*/141 142 /*Get initial flops*/143 _assert_(inittag>=0);144 _assert_(inittag<MAXIMUMSIZE);145 if(xIsNan<IssmDouble>(this->flops[inittag])) _error_("Tag not set");146 IssmDouble init = this->flops[inittag];147 148 /*Get final flops*/149 _assert_(finaltag>=0);150 _assert_(finaltag<MAXIMUMSIZE);151 if(xIsNan<IssmDouble>(this->flops[finaltag])) _error_("Tag not set");152 IssmDouble final = this->flops[finaltag];153 154 return final-init;155 }156 /*}}}*/157 int Profiler::DeltaTimeModHour(int inittag, int finishtag){/*{{{*/158 159 IssmDouble delta = this->DeltaTime(inittag,finishtag);160 return int((reCast<int,IssmDouble>(delta))/3600);161 162 }163 /*}}}*/164 int Profiler::DeltaTimeModMin(int inittag, int finishtag){/*{{{*/165 166 IssmDouble delta = this->DeltaTime(inittag,finishtag);167 return int(int(reCast<int,IssmDouble>(delta))%3600/60);168 }169 /*}}}*/170 int Profiler::DeltaTimeModSec(int inittag, int finishtag){/*{{{*/171 172 IssmDouble delta = this->DeltaTime(inittag,finishtag);173 return int(reCast<int,IssmDouble>(delta)%60);174 }175 /*}}}*/176 IssmDouble Profiler::Memory(int tag){/*{{{*/177 178 /*Get initial flops*/179 _assert_(tag>=0);180 _assert_(tag<MAXIMUMSIZE);181 if(xIsNan<IssmDouble>(this->flops[tag])) _error_("Tag not set");182 return this->memory[tag];183 }184 /*}}}*/ -
issm/trunk-jpl/src/c/classes/Profiler.h
r20637 r20810 27 27 28 28 public: 29 IssmDouble time[MAXIMUMSIZE];30 29 IssmDouble flops[MAXIMUMSIZE]; 31 30 IssmDouble memory[MAXIMUMSIZE]; 31 IssmDouble time[MAXIMUMSIZE]; 32 32 33 33 /*Profiler constructors, destructors {{{*/ … … 36 36 /*}}}*/ 37 37 /*Object virtual functions definitions:{{{ */ 38 Object *copy(); 39 void DeepEcho(); 38 40 void Echo(); 39 void DeepEcho();40 41 int Id(); 42 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction); 41 43 int ObjectEnum(); 42 Object *copy();43 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction);44 44 /*}}}*/ 45 45 /*Profiler routines {{{*/ 46 void Tag(int tagenum,bool dontmpisync=false); 47 IssmDouble Memory(int tag); 46 IssmDouble DeltaFlops(int inittag, int finaltag); 48 47 IssmDouble DeltaTime(int inittag, int finaltag); 49 IssmDouble DeltaFlops(int inittag, int finaltag);50 48 int DeltaTimeModHour(int inittag, int finaltag); 51 49 int DeltaTimeModMin(int inittag, int finaltag); 52 50 int DeltaTimeModSec(int inittag, int finaltag); 51 IssmDouble Memory(int tag); 52 void Tag(int tagenum,bool dontmpisync=false); 53 53 /*}}}*/ 54 54 }; -
issm/trunk-jpl/src/c/classes/RiftStruct.h
r14222 r20810 10 10 public: 11 11 int numrifts; 12 int **riftspairs; 13 double **riftspenaltypairs; 14 int *riftsnumpairs; 15 int *riftsnumpenaltypairs; 16 int *riftsnumsegments; 12 17 int **riftssegments; 13 int *riftsnumsegments;14 int **riftspairs;15 int *riftsnumpairs;16 double **riftspenaltypairs;17 int *riftsnumpenaltypairs;18 18 int *riftstips; 19 19 double **state; -
issm/trunk-jpl/src/c/classes/Segment.h
r19198 r20810 46 46 47 47 /*Object virtual functions definitions:*/ 48 Object* copy() {/*{{{*/ 49 return new Segment(this->eid,this->x1,this->y1,this->x2,this->y2); 50 } 51 /*}}}*/ 52 void DeepEcho(void){/*{{{*/ 53 this->Echo(); 54 } 55 /*}}}*/ 48 56 void Echo(void){/*{{{*/ 49 57 … … 55 63 } 56 64 /*}}}*/ 57 void DeepEcho(void){/*{{{*/ 58 this->Echo(); 59 } 65 int Id(void){ return eid; }/*{{{*/ 60 66 /*}}}*/ 61 int Id(void){ return eid; }/*{{{*/ 67 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){/*{{{*/ 68 _error_("not implemented yet!"); 69 } 62 70 /*}}}*/ 63 71 int ObjectEnum(void){/*{{{*/ … … 67 75 } 68 76 /*}}}*/ 69 Object* copy() {/*{{{*/70 return new Segment(this->eid,this->x1,this->y1,this->x2,this->y2);71 }72 /*}}}*/73 void Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){/*{{{*/74 _error_("not implemented yet!");75 }76 /*}}}*/77 77 78 78 }; -
issm/trunk-jpl/src/c/classes/Update.h
r16783 r20810 14 14 public: 15 15 16 virtual void InputUpdateFromVector(IssmDouble* vector, int name, int type)=0; 16 virtual void InputUpdateFromConstant(IssmDouble constant, int name)=0; 17 virtual void InputUpdateFromConstant(int constant, int name)=0; 18 virtual void InputUpdateFromConstant(bool constant, int name)=0; 17 19 #ifdef _HAVE_DAKOTA_ 18 20 virtual void InputUpdateFromMatrixDakota(IssmDouble* matrix, int rows, int ncols, int name, int type)=0; 19 21 virtual void InputUpdateFromVectorDakota(IssmDouble* vector, int name, int type)=0; 20 22 #endif 21 virtual void InputUpdateFromConstant(IssmDouble constant, int name)=0;22 virtual void InputUpdateFromConstant(int constant, int name)=0;23 virtual void InputUpdateFromConstant(bool constant, int name)=0;24 23 virtual void InputUpdateFromIoModel(int index, IoModel* iomodel)=0; 24 virtual void InputUpdateFromVector(IssmDouble* vector, int name, int type)=0; 25 25 26 26 }; -
issm/trunk-jpl/src/c/classes/Vertex.cpp
r20690 r20810 62 62 63 63 /*Object virtual functions definitions:*/ 64 Object* Vertex::copy() {/*{{{*/ 65 66 return new Vertex(*this); 67 68 } 69 /*}}}*/ 70 void Vertex::DeepEcho(void){/*{{{*/ 71 this->Echo(); 72 } 73 /*}}}*/ 64 74 void Vertex::Echo(void){/*{{{*/ 65 75 … … 78 88 } 79 89 /*}}}*/ 80 void Vertex::DeepEcho(void){/*{{{*/81 this->Echo();82 }83 /*}}}*/84 90 int Vertex::Id(void){ return id; }/*{{{*/ 85 /*}}}*/86 int Vertex::ObjectEnum(void){/*{{{*/87 88 return VertexEnum;89 90 }91 /*}}}*/92 Object* Vertex::copy() {/*{{{*/93 94 return new Vertex(*this);95 96 }97 91 /*}}}*/ 98 92 void Vertex::Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){ /*{{{*/ … … 112 106 } 113 107 /*}}}*/ 108 int Vertex::ObjectEnum(void){/*{{{*/ 109 110 return VertexEnum; 111 112 } 113 /*}}}*/ 114 114 115 115 /*Vertex management: */ 116 116 int Vertex::Connectivity(void){return connectivity;}/*{{{*/ 117 117 /*}}}*/ 118 void Vertex::DistributePids(int* ppidcount){/*{{{*/ 119 120 /*retrieve current pid*/ 121 int pidcount=*ppidcount; 122 123 /*This vertex is a clone! Don't distribute pids, it will get them from another cpu!*/ 124 if(this->clone) return; 125 126 /*This vertex should distribute its pid*/ 127 this->pid=pidcount; 128 pidcount++; 129 130 /*Assign output pointers: */ 131 *ppidcount=pidcount; 132 } 133 /*}}}*/ 134 IssmDouble Vertex::GetLatitude(){/*{{{*/ 135 return this->latitute; 136 } 137 /*}}}*/ 138 IssmDouble Vertex::GetLongitude(){/*{{{*/ 139 return this->longitude; 140 } 141 /*}}}*/ 142 IssmDouble Vertex::GetRadius(){/*{{{*/ 143 return this->R; 144 } 145 /*}}}*/ 118 146 IssmDouble Vertex::GetX(){/*{{{*/ 119 147 return this->x; … … 128 156 } 129 157 /*}}}*/ 130 IssmDouble Vertex::GetLatitude(){/*{{{*/ 131 return this->latitute; 132 } 133 /*}}}*/ 134 IssmDouble Vertex::GetLongitude(){/*{{{*/ 135 return this->longitude; 136 } 137 /*}}}*/ 138 IssmDouble Vertex::GetRadius(){/*{{{*/ 139 return this->R; 158 void Vertex::OffsetPids(int pidcount){/*{{{*/ 159 160 /*This vertex is a clone, don't offset the pids*/ 161 if(this->clone) return; 162 163 /*This vertex should offset his pid, go ahead: */ 164 this->pid+=pidcount; 165 } 166 /*}}}*/ 167 int Vertex::Pid(void){ return pid; }/*{{{*/ 168 /*}}}*/ 169 void Vertex::SetClone(int* minranks){/*{{{*/ 170 171 int my_rank; 172 173 /*recover my_rank:*/ 174 my_rank=IssmComm::GetRank(); 175 176 if (minranks[this->sid]==my_rank){ 177 this->clone=false; 178 } 179 else{ 180 /*!there is a cpu with lower rank that has the same vertex, 181 therefore, I am a clone*/ 182 this->clone=true; 183 } 184 185 } 186 /*}}}*/ 187 void Vertex::ShowTruePids(int* truepids){/*{{{*/ 188 189 /*Are we a clone? : */ 190 if(this->clone)return; 191 192 /*Ok, we are not a clone, just plug our pid into truepids: */ 193 truepids[this->sid]=this->pid; 140 194 } 141 195 /*}}}*/ 142 196 int Vertex::Sid(void){ return sid; }/*{{{*/ 143 197 /*}}}*/ 144 int Vertex::Pid(void){ return pid; }/*{{{*/ 198 void Vertex::ToXYZ(Matrix<IssmDouble>* matrix){/*{{{*/ 199 200 IssmDouble xyz[3]; 201 int indices[3]; 202 203 if (this->clone==true) return; 204 205 xyz[0]=x; 206 xyz[1]=y; 207 xyz[2]=z; 208 indices[0]=0; 209 indices[1]=1; 210 indices[2]=2; 211 212 matrix->SetValues(1,&sid,3,&indices[0],&xyz[0],INS_VAL); 213 } 214 /*}}}*/ 215 void Vertex::UpdateClonePids(int* alltruepids){/*{{{*/ 216 217 /*If we are not a clone, don't update, we already have pids: */ 218 if(!this->clone)return; 219 220 /*Ok, we are a clone node, but we did not create the pid for this vertex 221 * Therefore, our pid is garbage right now. Go pick it up in the alltruepids: */ 222 this->pid=alltruepids[this->sid]; 223 } 145 224 /*}}}*/ 146 225 void Vertex::UpdatePosition(Vector<IssmDouble>* vx,Vector<IssmDouble>* vy,Vector<IssmDouble>* vz,Parameters* parameters,IssmDouble* surface,IssmDouble* bed){/*{{{*/ … … 179 258 } 180 259 /*}}}*/ 181 void Vertex::DistributePids(int* ppidcount){/*{{{*/182 183 /*retrieve current pid*/184 int pidcount=*ppidcount;185 186 /*This vertex is a clone! Don't distribute pids, it will get them from another cpu!*/187 if(this->clone) return;188 189 /*This vertex should distribute its pid*/190 this->pid=pidcount;191 pidcount++;192 193 /*Assign output pointers: */194 *ppidcount=pidcount;195 }196 /*}}}*/197 void Vertex::OffsetPids(int pidcount){/*{{{*/198 199 /*This vertex is a clone, don't offset the pids*/200 if(this->clone) return;201 202 /*This vertex should offset his pid, go ahead: */203 this->pid+=pidcount;204 }205 /*}}}*/206 void Vertex::ShowTruePids(int* truepids){/*{{{*/207 208 /*Are we a clone? : */209 if(this->clone)return;210 211 /*Ok, we are not a clone, just plug our pid into truepids: */212 truepids[this->sid]=this->pid;213 }214 /*}}}*/215 void Vertex::UpdateClonePids(int* alltruepids){/*{{{*/216 217 /*If we are not a clone, don't update, we already have pids: */218 if(!this->clone)return;219 220 /*Ok, we are a clone node, but we did not create the pid for this vertex221 * Therefore, our pid is garbage right now. Go pick it up in the alltruepids: */222 this->pid=alltruepids[this->sid];223 }224 /*}}}*/225 void Vertex::SetClone(int* minranks){/*{{{*/226 227 int my_rank;228 229 /*recover my_rank:*/230 my_rank=IssmComm::GetRank();231 232 if (minranks[this->sid]==my_rank){233 this->clone=false;234 }235 else{236 /*!there is a cpu with lower rank that has the same vertex,237 therefore, I am a clone*/238 this->clone=true;239 }240 241 }242 /*}}}*/243 void Vertex::ToXYZ(Matrix<IssmDouble>* matrix){/*{{{*/244 245 IssmDouble xyz[3];246 int indices[3];247 248 if (this->clone==true) return;249 250 xyz[0]=x;251 xyz[1]=y;252 xyz[2]=z;253 indices[0]=0;254 indices[1]=1;255 indices[2]=2;256 257 matrix->SetValues(1,&sid,3,&indices[0],&xyz[0],INS_VAL);258 }259 /*}}}*/260 260 void Vertex::VertexCoordinates(Vector<IssmDouble>* vx,Vector<IssmDouble>* vy,Vector<IssmDouble>* vz, bool spherical){/*{{{*/ 261 261 -
issm/trunk-jpl/src/c/classes/Vertex.h
r19984 r20810 49 49 /*}}}*/ 50 50 /*Vertex management:*/ 51 int Pid(void);52 int Sid(void);53 51 int Connectivity(void); 52 void DistributePids(int* ppidcount); 53 IssmDouble GetLatitude(void); 54 IssmDouble GetLongitude(void); 55 IssmDouble GetRadius(void); 54 56 IssmDouble GetX(void); 55 57 IssmDouble GetY(void); 56 58 IssmDouble GetZ(void); 57 IssmDouble GetLatitude(void); 58 IssmDouble GetLongitude(void); 59 IssmDouble GetRadius(void); 59 void OffsetPids(int pidcount); 60 int Pid(void); 61 void SetClone(int* minranks); 62 void ShowTruePids(int* borderpids); 63 int Sid(void); 64 void ToXYZ(Matrix<IssmDouble>* matrix); 65 void UpdateClonePids(int* allborderpids); 60 66 void UpdatePosition(Vector<IssmDouble>* vx,Vector<IssmDouble>* vy,Vector<IssmDouble>* vz,Parameters* parameters,IssmDouble* thickness,IssmDouble* bed); 61 void DistributePids(int* ppidcount);62 void OffsetPids(int pidcount);63 void ShowTruePids(int* borderpids);64 void UpdateClonePids(int* allborderpids);65 void SetClone(int* minranks);66 void ToXYZ(Matrix<IssmDouble>* matrix);67 67 void VertexCoordinates(Vector<IssmDouble>* vx,Vector<IssmDouble>* vy,Vector<IssmDouble>* vz,bool spherical=false); 68 68 };
Note:
See TracChangeset
for help on using the changeset viewer.