source: issm/trunk/src/c/classes/Loads/Riftfront.cpp@ 24686

Last change on this file since 24686 was 24686, checked in by Mathieu Morlighem, 5 years ago

merged trunk-jpl and trunk for revision 24684

File size: 20.8 KB
Line 
1/*!\file Riftfront.cpp
2 * \brief: implementation of the Riftfront object
3 */
4
5/*Headers:*/
6/*{{{*/
7#ifdef HAVE_CONFIG_H
8 #include <config.h>
9#else
10#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
11#endif
12
13#include "shared/shared.h"
14#include "modules/ModelProcessorx/ModelProcessorx.h"
15#include "../classes.h"
16/*}}}*/
17
18/*Element macros*/
19#define NUMVERTICES 2
20
21/*Riftfront constructors and destructor*/
22Riftfront::Riftfront(){/*{{{*/
23 this->parameters=NULL;
24 this->hnodes=NULL;
25 this->hvertices=NULL;
26 this->helements=NULL;
27 this->nodes=NULL;
28 this->vertices=NULL;
29 this->elements=NULL;
30}
31/*}}}*/
32Riftfront::Riftfront(int riftfront_id,int i, IoModel* iomodel){/*{{{*/
33
34 /*data: */
35 const int RIFTINFOSIZE = 12;
36 int riftfront_node_ids[2];
37 int riftfront_elem_ids[2];
38 IssmDouble riftfront_friction;
39 IssmDouble riftfront_fractionincrement;
40 int penalty_lock;
41
42 /*intermediary: */
43 int el1 ,el2;
44 int node1 ,node2;
45
46 /*Fetch parameters: */
47 iomodel->FindConstant(&penalty_lock,"md.stressbalance.rift_penalty_lock");
48
49 /*Ok, retrieve all the data needed to add a penalty between the two nodes: */
50 el1=reCast<int,IssmDouble>(*(iomodel->Data("md.rifts.riftstruct")+RIFTINFOSIZE*i+2));
51 el2=reCast<int,IssmDouble>(*(iomodel->Data("md.rifts.riftstruct")+RIFTINFOSIZE*i+3)) ;
52
53 node1=reCast<int,IssmDouble>(*(iomodel->Data("md.rifts.riftstruct")+RIFTINFOSIZE*i+0));
54 node2=reCast<int,IssmDouble>(*(iomodel->Data("md.rifts.riftstruct")+RIFTINFOSIZE*i+1));
55
56 /*id: */
57 this->id=riftfront_id;
58
59 /*hooks: */
60 riftfront_node_ids[0]=node1;
61 riftfront_node_ids[1]=node2;
62 riftfront_elem_ids[0]=el1;
63 riftfront_elem_ids[1]=el2;
64
65 /*Hooks: */
66 this->hnodes=new Hook(riftfront_node_ids,2);
67 this->hvertices=new Hook(riftfront_node_ids,2);
68 this->helements=new Hook(riftfront_elem_ids,2);
69
70 /*computational parameters: */
71 this->active=0;
72 this->frozen=0;
73 this->counter=0;
74 this->prestable=0;
75 this->penalty_lock=penalty_lock;
76 this->material_converged=0;
77 this->normal[0]=*(iomodel->Data("md.rifts.riftstruct")+RIFTINFOSIZE*i+4);
78 this->normal[1]=*(iomodel->Data("md.rifts.riftstruct")+RIFTINFOSIZE*i+5);
79 this->length=*(iomodel->Data("md.rifts.riftstruct")+RIFTINFOSIZE*i+6);
80 this->fraction=*(iomodel->Data("md.rifts.riftstruct")+RIFTINFOSIZE*i+9);
81 this->state=reCast<int,IssmDouble>(*(iomodel->Data("md.rifts.riftstruct")+RIFTINFOSIZE*i+11));
82
83 //intialize properties
84 this->type=SegmentRiftfrontEnum;
85 this->fill = IoRiftfillToEnum(reCast<int,IssmDouble>(*(iomodel->Data("md.rifts.riftstruct")+RIFTINFOSIZE*i+7)));
86 this->friction=*(iomodel->Data("md.rifts.riftstruct")+RIFTINFOSIZE*i+8);
87 this->fractionincrement=*(iomodel->Data("md.rifts.riftstruct")+RIFTINFOSIZE*i+10);
88 this->shelf=reCast<bool,IssmDouble>(iomodel->Data("md.mask.groundedice_levelset")[node1-1]<0.);
89
90 //parameters and hooked fields: we still can't point to them, they may not even exist. Configure will handle this.
91 this->parameters=NULL;
92 this->nodes= NULL;
93 this->vertices= NULL;
94 this->elements= NULL;
95
96}
97/*}}}*/
98Riftfront::~Riftfront(){/*{{{*/
99 this->parameters=NULL;
100 delete hnodes;
101 delete hvertices;
102 delete helements;
103}
104/*}}}*/
105
106/*Object virtual functions definitions:*/
107Object* Riftfront::copy() {/*{{{*/
108
109 Riftfront* riftfront=NULL;
110
111 riftfront=new Riftfront();
112
113 /*copy fields: */
114 riftfront->id=this->id;
115 riftfront->type=this->type;
116 riftfront->fill=this->fill;
117 riftfront->friction=this->friction;
118 riftfront->fractionincrement=this->fractionincrement;
119 riftfront->shelf=this->shelf;
120
121 /*point parameters: */
122 riftfront->parameters=this->parameters;
123
124 /*now deal with hooks and objects: */
125 riftfront->hnodes=(Hook*)this->hnodes->copy();
126 riftfront->hvertices=(Hook*)this->hvertices->copy();
127 riftfront->helements=(Hook*)this->helements->copy();
128
129 /*corresponding fields*/
130 riftfront->nodes =(Node**)riftfront->hnodes->deliverp();
131 riftfront->vertices=(Vertex**)riftfront->hvertices->deliverp();
132 riftfront->elements=(Element**)riftfront->helements->deliverp();
133
134 /*internal data: */
135 riftfront->penalty_lock=this->penalty_lock;
136 riftfront->active=this->active;
137 riftfront->frozen=this->frozen;
138 riftfront->state=this->state;
139 riftfront->counter=this->counter;
140 riftfront->prestable=this->prestable;
141 riftfront->material_converged=this->material_converged;
142 riftfront->normal[0]=this->normal[0];
143 riftfront->normal[1]=this->normal[1];
144 riftfront->length=this->length;
145 riftfront->fraction=this->fraction;
146
147 return riftfront;
148
149}
150/*}}}*/
151void Riftfront::DeepEcho(void){/*{{{*/
152
153 _printf_("Riftfront:\n");
154 _printf_(" id: " << id << "\n");
155 hnodes->DeepEcho();
156 hvertices->DeepEcho();
157 helements->DeepEcho();
158 _printf_(" parameters\n");
159 if(parameters)parameters->DeepEcho();
160}
161/*}}}*/
162void Riftfront::Echo(void){/*{{{*/
163
164 _printf_("Riftfront:\n");
165 _printf_(" id: " << id << "\n");
166 _printf_(" hnodes: " << hnodes << "\n");
167 _printf_(" hvertices: " << hvertices << "\n");
168 _printf_(" helements: " << helements << "\n");
169 _printf_(" parameters: " << parameters << "\n");
170 _printf_(" internal parameters: \n");
171 _printf_(" normal: " << normal[0] << "|" << normal[1] << "\n");
172 _printf_(" length: " << length << "\n");
173 _printf_(" penalty_lock: " << penalty_lock << "\n");
174 _printf_(" active: " <<(active ? "true":"false") << "\n");
175 _printf_(" counter: " << counter << "\n");
176 _printf_(" prestable: " << (prestable ? "true":"false") << "\n");
177 _printf_(" material_converged: " << (material_converged ? "true":"false") << "\n");
178 _printf_(" fill: " << fill << "\n");
179 _printf_(" friction: " << friction << "\n");
180 _printf_(" fraction: " << fraction << "\n");
181 _printf_(" fractionincrement: " << fractionincrement << "\n");
182 _printf_(" state: " << state << "\n");
183 _printf_(" frozen: " << (frozen ? "true":"false") << "\n");
184
185}
186/*}}}*/
187int Riftfront::Id(void){ return id; }/*{{{*/
188/*}}}*/
189void Riftfront::Marshall(char** pmarshalled_data,int* pmarshalled_data_size, int marshall_direction){ /*{{{*/
190
191 _assert_(this);
192
193 /*ok, marshall operations: */
194 MARSHALLING_ENUM(RiftfrontEnum);
195 MARSHALLING(id);
196 MARSHALLING(type);
197 MARSHALLING(fill);
198 MARSHALLING(friction);
199 MARSHALLING(fractionincrement);
200 MARSHALLING(shelf);
201
202 if(marshall_direction==MARSHALLING_BACKWARD){
203 this->hnodes = new Hook();
204 this->hvertices = new Hook();
205 this->helements = new Hook();
206 }
207
208 this->hnodes->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
209 this->hvertices->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
210 this->helements->Marshall(pmarshalled_data,pmarshalled_data_size,marshall_direction);
211
212 /*corresponding fields*/
213 nodes =(Node**)this->hnodes->deliverp();
214 vertices =(Vertex**)this->hvertices->deliverp();
215 elements =(Element**)this->helements->deliverp();
216
217 MARSHALLING(penalty_lock);
218 MARSHALLING(active);
219 MARSHALLING(frozen);
220 MARSHALLING(state);
221 MARSHALLING(counter);
222 MARSHALLING(prestable);
223 MARSHALLING(material_converged);
224 MARSHALLING(normal[0]);
225 MARSHALLING(normal[1]);
226 MARSHALLING(length);
227 MARSHALLING(fraction);
228
229}
230/*}}}*/
231int Riftfront::ObjectEnum(void){/*{{{*/
232
233 return RiftfrontEnum;
234
235}
236/*}}}*/
237
238/*Update virtual functions definitions:*/
239void Riftfront::InputUpdateFromConstant(bool constant,int name){/*{{{*/
240}
241/*}}}*/
242void Riftfront::InputUpdateFromConstant(IssmDouble constant,int name){/*{{{*/
243
244}
245/*}}}*/
246void Riftfront::InputUpdateFromVector(IssmDouble* vector, int name, int type){/*{{{*/
247
248 /*Nothing to update*/
249
250}
251/*}}}*/
252
253/*Load virtual functions definitions:*/
254void Riftfront::Configure(Elements* elementsin,Loads* loadsin,Nodes* nodesin,Vertices* verticesin,Materials* materialsin,Parameters* parametersin){/*{{{*/
255
256 /*Take care of hooking up all objects for this element, ie links the objects in the hooks to their respective
257 * datasets, using internal ids and offsets hidden in hooks: */
258 hnodes->configure(nodesin);
259 hvertices->configure(verticesin);
260 helements->configure(elementsin);
261
262 /*Initialize hooked fields*/
263 this->nodes =(Node**)hnodes->deliverp();
264 this->vertices=(Vertex**)hvertices->deliverp();
265 this->elements=(Element**)helements->deliverp();
266
267 /*point parameters to real dataset: */
268 this->parameters=parametersin;
269
270}
271/*}}}*/
272void Riftfront::CreateKMatrix(Matrix<IssmDouble>* Kff, Matrix<IssmDouble>* Kfs){/*{{{*/
273 /*do nothing: */
274 return;
275}
276/*}}}*/
277void Riftfront::CreatePVector(Vector<IssmDouble>* pf){/*{{{*/
278 /*do nothing: */
279 return;
280}
281/*}}}*/
282void Riftfront::GetNodesLidList(int* lidlist){/*{{{*/
283
284 _assert_(lidlist);
285 _assert_(nodes);
286
287 for(int i=0;i<NUMVERTICES;i++) lidlist[i]=nodes[i]->Lid();
288}
289/*}}}*/
290void Riftfront::GetNodesSidList(int* sidlist){/*{{{*/
291
292 _assert_(sidlist);
293 _assert_(nodes);
294
295 for(int i=0;i<NUMVERTICES;i++) sidlist[i]=nodes[i]->Sid();
296}
297/*}}}*/
298int Riftfront::GetNumberOfNodes(void){/*{{{*/
299
300 return NUMVERTICES;
301}
302/*}}}*/
303bool Riftfront::IsPenalty(void){/*{{{*/
304 return true;
305}
306/*}}}*/
307void Riftfront::PenaltyCreateKMatrix(Matrix<IssmDouble>* Kff, Matrix<IssmDouble>* Kfs,IssmDouble kmax){/*{{{*/
308
309 /*Retrieve parameters: */
310 ElementMatrix* Ke=NULL;
311 int analysis_type;
312 this->parameters->FindParam(&analysis_type,AnalysisTypeEnum);
313
314 switch(analysis_type){
315 case StressbalanceAnalysisEnum:
316 Ke=PenaltyCreateKMatrixStressbalanceHoriz(kmax);
317 break;
318 case AdjointHorizAnalysisEnum:
319 Ke=PenaltyCreateKMatrixStressbalanceHoriz(kmax);
320 break;
321 default:
322 _error_("analysis " << analysis_type << " (" << EnumToStringx(analysis_type) << ") not supported yet");
323 }
324
325 /*Add to global Vector*/
326 if(Ke){
327 Ke->AddToGlobal(Kff,Kfs);
328 delete Ke;
329 }
330}
331/*}}}*/
332void Riftfront::PenaltyCreatePVector(Vector<IssmDouble>* pf,IssmDouble kmax){/*{{{*/
333
334 /*Retrieve parameters: */
335 ElementVector* pe=NULL;
336 int analysis_type;
337 this->parameters->FindParam(&analysis_type,AnalysisTypeEnum);
338
339 switch(analysis_type){
340 case StressbalanceAnalysisEnum:
341 pe=PenaltyCreatePVectorStressbalanceHoriz(kmax);
342 break;
343 case AdjointHorizAnalysisEnum:
344 /*No penalty applied on load vector*/
345 break;
346 default:
347 _error_("analysis " << analysis_type << " (" << EnumToStringx(analysis_type) << ") not supported yet");
348 }
349
350 /*Add to global Vector*/
351 if(pe){
352 pe->AddToGlobal(pf);
353 delete pe;
354 }
355}
356/*}}}*/
357void Riftfront::ResetHooks(){/*{{{*/
358
359 this->nodes=NULL;
360 this->vertices=NULL;
361 this->elements=NULL;
362 this->parameters=NULL;
363
364 /*Get Element type*/
365 this->hnodes->reset();
366 this->hvertices->reset();
367 this->helements->reset();
368
369}
370/*}}}*/
371void Riftfront::SetCurrentConfiguration(Elements* elementsin,Loads* loadsin,Nodes* nodesin,Vertices* verticesin,Materials* materialsin,Parameters* parametersin){/*{{{*/
372
373}
374/*}}}*/
375void Riftfront::SetwiseNodeConnectivity(int* pd_nz,int* po_nz,Node* node,bool* flags,int* flagsindices,int set1_enum,int set2_enum){/*{{{*/
376
377 /*Output */
378 int d_nz = 0;
379 int o_nz = 0;
380
381 /*Loop over all nodes*/
382 for(int i=0;i<NUMVERTICES;i++){
383
384 if(!flags[this->nodes[i]->Lid()]){
385
386 /*flag current node so that no other element processes it*/
387 flags[this->nodes[i]->Lid()]=true;
388
389 int counter=0;
390 while(flagsindices[counter]>=0) counter++;
391 flagsindices[counter]=this->nodes[i]->Lid();
392
393 /*if node is clone, we have an off-diagonal non-zero, else it is a diagonal non-zero*/
394 switch(set2_enum){
395 case FsetEnum:
396 if(nodes[i]->fsize){
397 if(this->nodes[i]->IsClone())
398 o_nz += 1;
399 else
400 d_nz += 1;
401 }
402 break;
403 case GsetEnum:
404 if(nodes[i]->gsize){
405 if(this->nodes[i]->IsClone())
406 o_nz += 1;
407 else
408 d_nz += 1;
409 }
410 break;
411 case SsetEnum:
412 if(nodes[i]->ssize){
413 if(this->nodes[i]->IsClone())
414 o_nz += 1;
415 else
416 d_nz += 1;
417 }
418 break;
419 default: _error_("not supported");
420 }
421 }
422 }
423
424 /*Assign output pointers: */
425 *pd_nz=d_nz;
426 *po_nz=o_nz;
427}
428/*}}}*/
429
430/*Riftfront numerics*/
431ElementMatrix* Riftfront::PenaltyCreateKMatrixStressbalanceHoriz(IssmDouble kmax){/*{{{*/
432
433 const int numdof = NDOF2*NUMVERTICES;
434 IssmDouble thickness;
435 IssmDouble h[2];
436 IssmDouble penalty_offset;
437
438 /*enum of element? */
439 if(elements[0]->ObjectEnum()!=TriaEnum)_error_("only Tria element allowed for Riftfront load!");
440 Tria* tria1=(Tria*)elements[0];
441 Tria* tria2=(Tria*)elements[1];
442
443 /*Initialize Element Matrix*/
444 if(!this->active) return NULL;
445 ElementMatrix* Ke=new ElementMatrix(nodes,NUMVERTICES,this->parameters);
446
447 /*Get some parameters: */
448 this->parameters->FindParam(&penalty_offset,StressbalancePenaltyFactorEnum);
449 tria1->GetInputValue(&h[0],vertices[0],ThicknessEnum);
450 tria2->GetInputValue(&h[1],vertices[1],ThicknessEnum);
451 if (h[0]!=h[1])_error_("different thicknesses not supported for rift fronts");
452 thickness=h[0];
453
454 /*There is contact, we need to constrain the normal velocities (zero penetration), and the
455 *contact slip friction. */
456
457 /*From Peter Wriggers book (Computational Contact Mechanics, p191): */
458 Ke->values[0*numdof+0]+= +pow(normal[0],2)*kmax*pow(10,penalty_offset);
459 Ke->values[0*numdof+1]+= +normal[0]*normal[1]*kmax*pow(10,penalty_offset);
460 Ke->values[0*numdof+2]+= -pow(normal[0],2)*kmax*pow(10,penalty_offset);
461 Ke->values[0*numdof+3]+= -normal[0]*normal[1]*kmax*pow(10,penalty_offset);
462
463 Ke->values[1*numdof+0]+= +normal[0]*normal[1]*kmax*pow(10,penalty_offset);
464 Ke->values[1*numdof+1]+= +pow(normal[1],2)*kmax*pow(10,penalty_offset);
465 Ke->values[1*numdof+2]+= -normal[0]*normal[1]*kmax*pow(10,penalty_offset);
466 Ke->values[1*numdof+3]+= -pow(normal[1],2)*kmax*pow(10,penalty_offset);
467
468 Ke->values[2*numdof+0]+= -pow(normal[0],2)*kmax*pow(10,penalty_offset);
469 Ke->values[2*numdof+1]+= -normal[0]*normal[1]*kmax*pow(10,penalty_offset);
470 Ke->values[2*numdof+2]+= +pow(normal[0],2)*kmax*pow(10,penalty_offset);
471 Ke->values[2*numdof+3]+= +normal[0]*normal[1]*kmax*pow(10,penalty_offset);
472
473 Ke->values[3*numdof+0]+= -normal[0]*normal[1]*kmax*pow(10,penalty_offset);
474 Ke->values[3*numdof+1]+= -pow(normal[1],2)*kmax*pow(10,penalty_offset);
475 Ke->values[3*numdof+2]+= +normal[0]*normal[1]*kmax*pow(10,penalty_offset);
476 Ke->values[3*numdof+3]+= +pow(normal[1],2)*kmax*pow(10,penalty_offset);
477
478 /*Now take care of the friction: of type sigma=frictiontangent_velocity2-tangent_velocity1)*/
479
480 Ke->values[0*numdof+0]+= +pow(normal[1],2)*thickness*length*friction;
481 Ke->values[0*numdof+1]+= -normal[0]*normal[1]*thickness*length*friction;
482 Ke->values[0*numdof+2]+= -pow(normal[1],2)*thickness*length*friction;
483 Ke->values[0*numdof+3]+= +normal[0]*normal[1]*thickness*length*friction;
484
485 Ke->values[1*numdof+0]+= -normal[0]*normal[1]*thickness*length*friction;
486 Ke->values[1*numdof+1]+= +pow(normal[0],2)*thickness*length*friction;
487 Ke->values[1*numdof+2]+= +normal[0]*normal[1]*thickness*length*friction;
488 Ke->values[1*numdof+3]+= -pow(normal[0],2)*thickness*length*friction;
489
490 Ke->values[2*numdof+0]+= -pow(normal[1],2)*thickness*length*friction;
491 Ke->values[2*numdof+1]+= +normal[0]*normal[1]*thickness*length*friction;
492 Ke->values[2*numdof+2]+= +pow(normal[1],2)*thickness*length*friction;
493 Ke->values[2*numdof+3]+= -normal[0]*normal[1]*thickness*length*friction;
494
495 Ke->values[3*numdof+0]+= +normal[0]*normal[1]*thickness*length*friction;
496 Ke->values[3*numdof+1]+= -pow(normal[0],2)*thickness*length*friction;
497 Ke->values[3*numdof+2]+= -normal[0]*normal[1]*thickness*length*friction;
498 Ke->values[3*numdof+3]+= +pow(normal[0],2)*thickness*length*friction;
499
500 /*Clean up and return*/
501 return Ke;
502}
503/*}}}*/
504ElementVector* Riftfront::PenaltyCreatePVectorStressbalanceHoriz(IssmDouble kmax){/*{{{*/
505
506 int j;
507 IssmDouble rho_ice;
508 IssmDouble rho_water;
509 IssmDouble gravity;
510 IssmDouble thickness;
511 IssmDouble h[2];
512 IssmDouble bed;
513 IssmDouble b[2];
514 IssmDouble pressure;
515 IssmDouble pressure_litho;
516 IssmDouble pressure_air;
517 IssmDouble pressure_melange;
518 IssmDouble pressure_water;
519
520 /*enum of element? */
521 if(elements[0]->ObjectEnum()!=TriaEnum)_error_("only Tria element allowed for Riftfront load!");
522 Tria* tria1=(Tria*)elements[0];
523 Tria* tria2=(Tria*)elements[1];
524
525 /*Initialize Element Matrix*/
526 if(this->active) return NULL; /*The penalty is active. No loads implied here.*/
527 ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters);
528
529 /*Get some inputs: */
530 rho_ice=tria1->FindParam(MaterialsRhoIceEnum);
531 rho_water=tria1->FindParam(MaterialsRhoSeawaterEnum);
532 gravity=tria1->FindParam(ConstantsGEnum);
533 tria1->GetInputValue(&h[0],vertices[0],ThicknessEnum);
534 tria2->GetInputValue(&h[1],vertices[1],ThicknessEnum);
535 if (h[0]!=h[1])_error_("different thicknesses not supported for rift fronts");
536 thickness=h[0];
537 tria1->GetInputValue(&b[0],vertices[0],BaseEnum);
538 tria2->GetInputValue(&b[1],vertices[1],BaseEnum);
539 if (b[0]!=b[1])_error_("different beds not supported for rift fronts");
540 bed=b[0];
541
542 /*Ok, this rift is opening. We should put loads on both sides of the rift flanks. Because we are dealing with contact mechanics,
543 * and we want to avoid zigzagging of the loads, we want lump the loads onto nodes, not onto surfaces between nodes.:*/
544
545 /*Ok, to compute the pressure, we are going to need material properties, thickness and bed for the two nodes. We assume those properties to
546 * be the same across the rift.: */
547
548 /*Ok, now compute the pressure (in norm) that is being applied to the flanks, depending on the type of fill: */
549 if(fill==WaterEnum){
550 if(shelf){
551 /*We are on an ice shelf, hydrostatic equilibrium is used to determine the pressure for water fill: */
552 pressure=rho_ice*gravity*pow(thickness,2)/2.- rho_water*gravity*pow(bed,2)/2.;
553 }
554 else{
555 //We are on an icesheet, we assume the water column fills the entire front: */
556 pressure=rho_ice*gravity*pow(thickness,2)/2.- rho_water*gravity*pow(thickness,2)/2.;
557 }
558 }
559 else if(fill==AirEnum){
560 pressure=rho_ice*gravity*pow(thickness,2)/2.; //icefront on an ice sheet, pressure imbalance ice vs air.
561 }
562 else if(fill==IceEnum){ //icefront finding itself against another icefront (pressure imbalance is fully compensated, ice vs ice)
563 pressure=0;
564 }
565 else if(fill==MelangeEnum){ //icefront finding itself against another icefront (pressure imbalance is fully compensated, ice vs ice)
566
567 if(!shelf) _error_("fill type " << fill << " not supported on ice sheets yet.");
568
569 pressure_litho=rho_ice*gravity*pow(thickness,2)/2.;
570 pressure_air=0;
571 pressure_melange=rho_ice*gravity*pow(fraction*thickness,2)/2.;
572 pressure_water=1.0/2.0*rho_water*gravity* ( pow(bed,2.0)-pow(rho_ice/rho_water*fraction*thickness,2.0) );
573
574 pressure=pressure_litho-pressure_air-pressure_melange-pressure_water;
575 }
576 else{
577 _error_("fill type " << fill << " not supported yet.");
578 }
579
580 /*Ok, add contribution to first node, along the normal i==0: */
581 for(int j=0;j<2;j++){
582 pe->values[j]+=pressure*normal[j]*length;
583 }
584
585 /*Add contribution to second node, along the opposite normal: i==1 */
586 for(int j=0;j<2;j++){
587 pe->values[2+j]+= -pressure*normal[j]*length;
588 }
589
590 /*Clean up and return*/
591 return pe;
592}
593/*}}}*/
594int Riftfront::Constrain(int* punstable){/*{{{*/
595
596 IssmDouble penetration;
597 bool activate;
598 int unstable;
599 IssmDouble vx1;
600 IssmDouble vy1;
601 IssmDouble vx2;
602 IssmDouble vy2;
603
604 /*Objects: */
605 Tria *tria1 = NULL;
606 Tria *tria2 = NULL;
607
608 /*enum of element? */
609 if(elements[0]->ObjectEnum()!=TriaEnum)_error_("only Tria element allowed for Riftfront load!");
610
611 /*recover elements on both side of rift: */
612 tria1=(Tria*)elements[0];
613 tria2=(Tria*)elements[1];
614
615 /*Is this constraint frozen? In which case we don't touch: */
616 if (this->frozen){
617 *punstable=0;
618 return 1;
619 }
620
621 /*Is this rift segment state specified by user input? :*/
622 if (this->state==OpenEnum || this->state==ClosedEnum){
623
624 if(this->state==OpenEnum)this->active=0;
625 if(this->state==ClosedEnum)this->active=1;
626
627 /*this segment is like frozen, no instability here: */
628 *punstable=0;
629 return 1;
630 }
631
632 /*First recover velocity: */
633 tria1->GetInputValue(&vx1,vertices[0],VxEnum);
634 tria2->GetInputValue(&vx2,vertices[1],VxEnum);
635 tria1->GetInputValue(&vy1,vertices[0],VyEnum);
636 tria2->GetInputValue(&vy2,vertices[1],VyEnum);
637
638 /*Node 1 faces node 2, compute penetration of 2 into 1 (V2-V1).N (with N normal vector, and V velocity vector: */
639 penetration=(vx2-vx1)*normal[0]+(vy2-vy1)*normal[1];
640
641 /*activation: */
642 if(penetration<0)activate=true;
643 else activate=false;
644
645 /*Here, we try to avoid zigzaging. When a penalty activates and deactivates for more than penalty_lock times,
646 * we increase the fraction of melange:*/
647 if(this->counter>this->penalty_lock){
648 /*reset counter: */
649 this->counter=0;
650 /*increase melange fraction: */
651 this->fraction+=fractionincrement;
652 if (this->fraction>1)this->fraction=1.;
653 //_printf_("riftfront " << this->Id() << " fraction: " << this->fraction << "\n");
654 }
655
656 //Figure out stability of this penalty
657 if(this->active==activate){
658 unstable=0;
659 }
660 else{
661 unstable=1;
662 this->counter++;
663 }
664
665 //Set penalty flag
666 this->active=activate;
667
668 //if ((penetration>0) && (this->active==1))_printf_("Riftfront " << Id() << " wants to be released\n");
669
670 /*assign output pointer: */
671 *punstable=unstable;
672 return 1;
673}
674/*}}}*/
675void Riftfront::FreezeConstraints(void){/*{{{*/
676
677 /*Just set frozen flag to 1: */
678 this->frozen=1;
679
680}
681/*}}}*/
682bool Riftfront::IsFrozen(void){/*{{{*/
683
684 /*Just set frozen flag to 1: */
685 if(this->frozen)return 1;
686 else return 0;
687}
688/*}}}*/
Note: See TracBrowser for help on using the repository browser.