source: issm/trunk-jpl/src/c/classes/Loads/Icefront.cpp@ 15298

Last change on this file since 15298 was 15298, checked in by Mathieu Morlighem, 12 years ago

CHG: preparing quadratic elements for MacAyeal (Still some work to do...). Removed TriaP1Input and renamed TriaInput, which can have multiple interpolations

File size: 25.9 KB
RevLine 
[3683]1/*!\file Icefront.c
2 * \brief: implementation of the Icefront object
3 */
4
5/*Headers:*/
[12365]6/*{{{*/
[3683]7#ifdef HAVE_CONFIG_H
[9320]8 #include <config.h>
[3683]9#else
10#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
11#endif
12
[15012]13#include "../classes.h"
14#include "shared/shared.h"
[3683]15/*}}}*/
16
[5701]17/*Load macros*/
18#define NUMVERTICESSEG 2
19#define NUMVERTICESQUA 4
20
[4248]21/*Icefront constructors and destructor*/
[12365]22/*FUNCTION Icefront::Icefront() {{{*/
[3683]23Icefront::Icefront(){
[5714]24
[3683]25 this->inputs=NULL;
26 this->parameters=NULL;
[5714]27
[4396]28 this->hnodes=NULL;
[5714]29 this->nodes= NULL;
[14761]30 this->hvertices=NULL;
31 this->vertices= NULL;
[4396]32 this->helement=NULL;
[5714]33 this->element= NULL;
[4396]34 this->hmatpar=NULL;
[5714]35 this->matpar= NULL;
[3683]36}
37/*}}}*/
[12365]38/*FUNCTION Icefront::Icefront(int id, int i, IoModel* iomodel,int analysis_type) {{{*/
[5136]39Icefront::Icefront(int icefront_id,int i, IoModel* iomodel,int in_icefront_type, int in_analysis_type){
[3683]40
41 int segment_width;
42 int element;
[15298]43 int numnodes;
44 int numvertices;
[9356]45 int dim;
46 int numberofelements;
[3683]47
48 /*icefront constructor data: */
49 int icefront_eid;
50 int icefront_mparid;
[5713]51 int icefront_node_ids[NUMVERTICESQUA]; //initialize with largest size
[14761]52 int icefront_vertex_ids[NUMVERTICESQUA]; //initialize with largest size
[3683]53 int icefront_fill;
[13622]54
[9356]55 /*find parameters: */
[9719]56 iomodel->Constant(&dim,MeshDimensionEnum);
[9725]57 iomodel->Constant(&numberofelements,MeshNumberofelementsEnum);
[3683]58
59 /*First, retrieve element index and element type: */
[9356]60 if (dim==2){
[3683]61 segment_width=4;
62 }
63 else{
64 segment_width=6;
65 }
[9679]66 _assert_(iomodel->Data(DiagnosticIcefrontEnum));
[12557]67 element=reCast<int,IssmDouble>(*(iomodel->Data(DiagnosticIcefrontEnum)+segment_width*i+segment_width-2)-1); //element is in the penultimate column (node1 node2 ... elem fill)
[3683]68
69 /*Build ids for hook constructors: */
[12557]70 icefront_eid=reCast<int,IssmDouble>( *(iomodel->Data(DiagnosticIcefrontEnum)+segment_width*i+segment_width-2)); //matlab indexing
[9356]71 icefront_mparid=numberofelements+1; //matlab indexing
[3683]72
[5715]73 if (in_icefront_type==MacAyeal2dIceFrontEnum || in_icefront_type==MacAyeal3dIceFrontEnum){
[12557]74 icefront_node_ids[0]=iomodel->nodecounter+reCast<int>(*(iomodel->Data(DiagnosticIcefrontEnum)+segment_width*i+0));
75 icefront_node_ids[1]=iomodel->nodecounter+reCast<int>(*(iomodel->Data(DiagnosticIcefrontEnum)+segment_width*i+1));
[14761]76 icefront_vertex_ids[0]=reCast<int>(*(iomodel->Data(DiagnosticIcefrontEnum)+segment_width*i+0));
77 icefront_vertex_ids[1]=reCast<int>(*(iomodel->Data(DiagnosticIcefrontEnum)+segment_width*i+1));
[3683]78 }
[5552]79 else if (in_icefront_type==PattynIceFrontEnum || in_icefront_type==StokesIceFrontEnum){
[12557]80 icefront_node_ids[0]=iomodel->nodecounter+reCast<int>(*(iomodel->Data(DiagnosticIcefrontEnum)+segment_width*i+0));
81 icefront_node_ids[1]=iomodel->nodecounter+reCast<int>(*(iomodel->Data(DiagnosticIcefrontEnum)+segment_width*i+1));
82 icefront_node_ids[2]=iomodel->nodecounter+reCast<int>(*(iomodel->Data(DiagnosticIcefrontEnum)+segment_width*i+2));
83 icefront_node_ids[3]=iomodel->nodecounter+reCast<int>(*(iomodel->Data(DiagnosticIcefrontEnum)+segment_width*i+3));
[14761]84 icefront_vertex_ids[0]=reCast<int>(*(iomodel->Data(DiagnosticIcefrontEnum)+segment_width*i+0));
85 icefront_vertex_ids[1]=reCast<int>(*(iomodel->Data(DiagnosticIcefrontEnum)+segment_width*i+1));
86 icefront_vertex_ids[2]=reCast<int>(*(iomodel->Data(DiagnosticIcefrontEnum)+segment_width*i+2));
87 icefront_vertex_ids[3]=reCast<int>(*(iomodel->Data(DiagnosticIcefrontEnum)+segment_width*i+3));
[3683]88 }
[13036]89 else _error_("in_icefront_type " << EnumToStringx(in_icefront_type) << " not supported yet!");
[3683]90
[15298]91 if (in_icefront_type==PattynIceFrontEnum || in_icefront_type==StokesIceFrontEnum){
92 numnodes=4;
93 numvertices=4;
94 }
95 else{
96 numnodes=2;
97 numvertices=2;
98 }
[9465]99
100 /*Fill*/
[12557]101 icefront_fill=reCast<int>(iomodel->Data(DiagnosticIcefrontEnum)[segment_width*i+segment_width-1]);
[13622]102
[3683]103 /*Ok, we have everything to build the object: */
104 this->id=icefront_id;
[4003]105 this->analysis_type=in_analysis_type;
[3683]106
107 /*Hooks: */
[15298]108 this->hnodes=new Hook(icefront_node_ids,numnodes);
109 this->hvertices=new Hook(icefront_vertex_ids,numvertices);
[4396]110 this->helement=new Hook(&icefront_eid,1);
111 this->hmatpar=new Hook(&icefront_mparid,1);
[3683]112
113 //intialize and add as many inputs per element as requested:
114 this->inputs=new Inputs();
115 this->inputs->AddInput(new IntInput(FillEnum,icefront_fill));
[14688]116 this->inputs->AddInput(new IntInput(IceFrontTypeEnum,in_icefront_type));
[13622]117
[5714]118 //parameters and hooked fields: we still can't point to them, they may not even exist. Configure will handle this.
[14761]119 this->parameters = NULL;
120 this->nodes = NULL;
121 this->vertices = NULL;
122 this->element = NULL;
123 this->matpar = NULL;
[3683]124}
125
126/*}}}*/
[12365]127/*FUNCTION Icefront::~Icefront() {{{*/
[3683]128Icefront::~Icefront(){
129 delete inputs;
130 this->parameters=NULL;
[4396]131 delete hnodes;
[14761]132 delete hvertices;
[4396]133 delete helement;
134 delete hmatpar;
[3683]135}
136/*}}}*/
137
[4248]138/*Object virtual functions definitions:*/
[12365]139/*FUNCTION Icefront::Echo {{{*/
[4248]140void Icefront::Echo(void){
[15104]141 _printf_("Icefront:\n");
[15100]142 _printf_(" id: " << id << "\n");
143 _printf_(" analysis_type: " << EnumToStringx(analysis_type) << "\n");
[4396]144 hnodes->Echo();
[14761]145 hvertices->Echo();
[4396]146 helement->Echo();
147 hmatpar->Echo();
[15100]148 _printf_(" parameters: " << parameters << "\n");
[5161]149 if(parameters)parameters->Echo();
[15100]150 _printf_(" inputs: " << inputs << "\n");
[5161]151 if(inputs)inputs->Echo();
[3683]152}
153/*}}}*/
[12365]154/*FUNCTION Icefront::DeepEcho{{{*/
[3683]155void Icefront::DeepEcho(void){
156
[15104]157 _printf_("Icefront:\n");
[15100]158 _printf_(" id: " << id << "\n");
159 _printf_(" analysis_type: " << EnumToStringx(analysis_type) << "\n");
[4396]160 hnodes->DeepEcho();
[14761]161 hvertices->DeepEcho();
[4396]162 helement->DeepEcho();
163 hmatpar->DeepEcho();
[15100]164 _printf_(" parameters: " << parameters << "\n");
[5161]165 if(parameters)parameters->DeepEcho();
[15100]166 _printf_(" inputs: " << inputs << "\n");
[5161]167 if(inputs)inputs->DeepEcho();
[3683]168}
169/*}}}*/
[12365]170/*FUNCTION Icefront::Id {{{*/
[4248]171int Icefront::Id(void){ return id; }
[3683]172/*}}}*/
[12365]173/*FUNCTION Icefront::ObjectEnum{{{*/
[9883]174int Icefront::ObjectEnum(void){
[3683]175
[4248]176 return IcefrontEnum;
177
178}
179/*}}}*/
[12365]180/*FUNCTION Icefront::copy {{{*/
[4248]181Object* Icefront::copy() {
[13622]182
[4248]183 Icefront* icefront=NULL;
184
185 icefront=new Icefront();
186
187 /*copy fields: */
188 icefront->id=this->id;
189 icefront->analysis_type=this->analysis_type;
190 if(this->inputs){
191 icefront->inputs=(Inputs*)this->inputs->Copy();
192 }
193 else{
194 icefront->inputs=new Inputs();
195 }
196 /*point parameters: */
197 icefront->parameters=this->parameters;
198
199 /*now deal with hooks and objects: */
[14761]200 icefront->hnodes = (Hook*)this->hnodes->copy();
201 icefront->hvertices = (Hook*)this->hvertices->copy();
202 icefront->helement = (Hook*)this->helement->copy();
203 icefront->hmatpar = (Hook*)this->hmatpar->copy();
[4248]204
[5714]205 /*corresponding fields*/
[14761]206 icefront->nodes = (Node**)icefront->hnodes->deliverp();
207 icefront->vertices = (Vertex**)icefront->hvertices->deliverp();
208 icefront->element = (Element*)icefront->helement->delivers();
209 icefront->matpar = (Matpar*)icefront->hmatpar->delivers();
[5714]210
[4248]211 return icefront;
212
213}
214/*}}}*/
215
216/*Load virtual functions definitions:*/
[12365]217/*FUNCTION Icefront::Configure {{{*/
[4248]218void Icefront::Configure(Elements* elementsin,Loads* loadsin,Nodes* nodesin,Vertices* verticesin,Materials* materialsin,Parameters* parametersin){
219
220 /*Take care of hooking up all objects for this element, ie links the objects in the hooks to their respective
221 * datasets, using internal ids and offsets hidden in hooks: */
[14975]222 hnodes->configure((DataSet*)nodesin);
223 hvertices->configure((DataSet*)verticesin);
224 helement->configure((DataSet*)elementsin);
225 hmatpar->configure((DataSet*)materialsin);
[4248]226
[5714]227 /*Initialize hooked fields*/
[14761]228 this->nodes = (Node**)hnodes->deliverp();
229 this->vertices = (Vertex**)hvertices->deliverp();
230 this->element = (Element*)helement->delivers();
231 this->matpar = (Matpar*)hmatpar->delivers();
[5714]232
[4248]233 /*point parameters to real dataset: */
234 this->parameters=parametersin;
235}
236/*}}}*/
[12365]237/*FUNCTION Icefront::SetCurrentConfiguration {{{*/
[4575]238void Icefront::SetCurrentConfiguration(Elements* elementsin,Loads* loadsin,Nodes* nodesin,Vertices* verticesin,Materials* materialsin,Parameters* parametersin){
239}
240/*}}}*/
[12365]241/*FUNCTION Icefront::CreateKMatrix {{{*/
[13216]242void Icefront::CreateKMatrix(Matrix<IssmDouble>* Kff, Matrix<IssmDouble>* Kfs){
[3683]243
244 /*No stiffness loads applied, do nothing: */
245 return;
246
247}
248/*}}}*/
[12365]249/*FUNCTION Icefront::CreatePVector {{{*/
[13216]250void Icefront::CreatePVector(Vector<IssmDouble>* pf){
[3683]251
[5714]252 /*Checks in debugging mode*/
[6412]253 _assert_(nodes);
254 _assert_(element);
255 _assert_(matpar);
[4043]256
257 /*Retrieve parameters: */
[5935]258 ElementVector* pe=NULL;
[5714]259 int analysis_type;
[4043]260 this->parameters->FindParam(&analysis_type,AnalysisTypeEnum);
261
[3683]262 /*Just branch to the correct element icefront vector generator, according to the type of analysis we are carrying out: */
[5935]263 switch(analysis_type){
[9785]264 #ifdef _HAVE_DIAGNOSTIC_
[5935]265 case DiagnosticHorizAnalysisEnum:
266 pe=CreatePVectorDiagnosticHoriz();
267 break;
[9785]268 #endif
269 #ifdef _HAVE_CONTROL_
[5935]270 case AdjointHorizAnalysisEnum:
271 pe=CreatePVectorAdjointHoriz();
272 break;
[9785]273 #endif
[5935]274 default:
[13036]275 _error_("analysis " << analysis_type << " (" << EnumToStringx(analysis_type) << ") not supported yet");
[3683]276 }
[5935]277
278 /*Add to global Vector*/
279 if(pe){
[8800]280 pe->AddToGlobal(pf);
[5935]281 delete pe;
[5425]282 }
[3683]283}
284/*}}}*/
[12365]285/*FUNCTION Icefront::CreateJacobianMatrix{{{*/
[13216]286void Icefront::CreateJacobianMatrix(Matrix<IssmDouble>* Jff){
[11332]287 this->CreateKMatrix(Jff,NULL);
288}
[12365]289/*}}}*/
[13915]290/*FUNCTION Icefront::GetNodesSidList{{{*/
291void Icefront::GetNodesSidList(int* sidlist){
292
293 int type;
[14688]294 inputs->GetInputValue(&type,IceFrontTypeEnum);
[13915]295 _assert_(sidlist);
296 _assert_(nodes);
297
298 switch(type){
299 case MacAyeal2dIceFrontEnum:
300 case MacAyeal3dIceFrontEnum:
301 for(int i=0;i<NUMVERTICESSEG;i++) sidlist[i]=nodes[i]->Sid();
302 return;
303#ifdef _HAVE_3D_
304 case PattynIceFrontEnum:
305 case StokesIceFrontEnum:
306 for(int i=0;i<NUMVERTICESQUA;i++) sidlist[i]=nodes[i]->Sid();
307 return;
308#endif
309 default:
310 _error_("Icefront type " << EnumToStringx(type) << " not supported yet");
311 }
312}
313/*}}}*/
314/*FUNCTION Icefront::GetNumberOfNodes{{{*/
315int Icefront::GetNumberOfNodes(void){
316
317 int type;
[14688]318 inputs->GetInputValue(&type,IceFrontTypeEnum);
[13915]319
320 switch(type){
321 case MacAyeal2dIceFrontEnum:
322 return NUMVERTICESSEG;
323#ifdef _HAVE_3D_
324 case MacAyeal3dIceFrontEnum:
325 return NUMVERTICESSEG;
326 case PattynIceFrontEnum:
327 return NUMVERTICESQUA;
328 case StokesIceFrontEnum:
329 return NUMVERTICESQUA;
330#endif
331 default:
332 _error_("Icefront type " << EnumToStringx(type) << " not supported yet");
333 }
334
335}
336/*}}}*/
[13925]337/*FUNCTION Icefront::IsPenalty{{{*/
338bool Icefront::IsPenalty(void){
339 return false;
340}
341/*}}}*/
[12365]342/*FUNCTION Icefront::PenaltyCreateKMatrix {{{*/
[13216]343void Icefront::PenaltyCreateKMatrix(Matrix<IssmDouble>* Kff, Matrix<IssmDouble>* Kfs, IssmDouble kmax){
[4248]344 /*do nothing: */
[5939]345 return;
[4248]346}
347/*}}}*/
[12365]348/*FUNCTION Icefront::PenaltyCreatePVector{{{*/
[13216]349void Icefront::PenaltyCreatePVector(Vector<IssmDouble>* pf,IssmDouble kmax){
[4248]350 /*do nothing: */
[5939]351 return;
[4248]352}
353/*}}}*/
[12365]354/*FUNCTION Icefront::PenaltyCreateJacobianMatrix{{{*/
[13216]355void Icefront::PenaltyCreateJacobianMatrix(Matrix<IssmDouble>* Jff,IssmDouble kmax){
[11332]356 this->PenaltyCreateKMatrix(Jff,NULL,kmax);
357}
[12365]358/*}}}*/
[13915]359/*FUNCTION Icefront::SetwiseNodeConnectivity{{{*/
360void Icefront::SetwiseNodeConnectivity(int* pd_nz,int* po_nz,Node* node,bool* flags,int set1_enum,int set2_enum){
361
362 /*Output */
363 int d_nz = 0;
364 int o_nz = 0;
365
366 /*Loop over all nodes*/
367 for(int i=0;i<this->GetNumberOfNodes();i++){
368
369 if(!flags[this->nodes[i]->Sid()]){
370
371 /*flag current node so that no other element processes it*/
372 flags[this->nodes[i]->Sid()]=true;
373
374 /*if node is clone, we have an off-diagonal non-zero, else it is a diagonal non-zero*/
375 switch(set2_enum){
376 case FsetEnum:
377 if(nodes[i]->indexing.fsize){
378 if(this->nodes[i]->IsClone())
379 o_nz += 1;
380 else
381 d_nz += 1;
382 }
383 break;
384 case GsetEnum:
385 if(nodes[i]->indexing.gsize){
386 if(this->nodes[i]->IsClone())
387 o_nz += 1;
388 else
389 d_nz += 1;
390 }
391 break;
392 case SsetEnum:
393 if(nodes[i]->indexing.ssize){
394 if(this->nodes[i]->IsClone())
395 o_nz += 1;
396 else
397 d_nz += 1;
398 }
399 break;
400 default: _error_("not supported");
401 }
402 }
403 }
404
405 /*Assign output pointers: */
406 *pd_nz=d_nz;
407 *po_nz=o_nz;
408}
409/*}}}*/
[12365]410/*FUNCTION Icefront::InAnalysis{{{*/
[4248]411bool Icefront::InAnalysis(int in_analysis_type){
412 if (in_analysis_type==this->analysis_type)return true;
413 else return false;
414}
415/*}}}*/
416
417/*Update virtual functions definitions:*/
[12472]418/*FUNCTION Icefront::InputUpdateFromVector(IssmDouble* vector, int name, int type) {{{*/
419void Icefront::InputUpdateFromVector(IssmDouble* vector, int name, int type){
[4248]420 /*Nothing updated yet*/
421}
422/*}}}*/
[12365]423/*FUNCTION Icefront::InputUpdateFromVector(int* vector, int name, int type) {{{*/
[4248]424void Icefront::InputUpdateFromVector(int* vector, int name, int type){
425 /*Nothing updated yet*/
426}
427/*}}}*/
[12365]428/*FUNCTION Icefront::InputUpdateFromVector(bool* vector, int name, int type) {{{*/
[4248]429void Icefront::InputUpdateFromVector(bool* vector, int name, int type){
430 /*Nothing updated yet*/
431}
432/*}}}*/
[12472]433/*FUNCTION Icefront::InputUpdateFromMatrixDakota(IssmDouble* matrix, int nrows, int ncols, int name, int type) {{{*/
434void Icefront::InputUpdateFromMatrixDakota(IssmDouble* matrix, int nrows, int ncols, int name, int type){
[10576]435 /*Nothing updated yet*/
436}
437/*}}}*/
[12472]438/*FUNCTION Icefront::InputUpdateFromVectorDakota(IssmDouble* vector, int name, int type) {{{*/
439void Icefront::InputUpdateFromVectorDakota(IssmDouble* vector, int name, int type){
[5311]440 /*Nothing updated yet*/
441}
442/*}}}*/
[12365]443/*FUNCTION Icefront::InputUpdateFromVectorDakota(int* vector, int name, int type) {{{*/
[5311]444void Icefront::InputUpdateFromVectorDakota(int* vector, int name, int type){
445 /*Nothing updated yet*/
446}
447/*}}}*/
[12365]448/*FUNCTION Icefront::InputUpdateFromVectorDakota(bool* vector, int name, int type) {{{*/
[5311]449void Icefront::InputUpdateFromVectorDakota(bool* vector, int name, int type){
450 /*Nothing updated yet*/
451}
452/*}}}*/
[12472]453/*FUNCTION Icefront::InputUpdateFromConstant(IssmDouble constant, int name) {{{*/
454void Icefront::InputUpdateFromConstant(IssmDouble constant, int name){
[4248]455 /*Nothing updated yet*/
456}
457/*}}}*/
[12365]458/*FUNCTION Icefront::InputUpdateFromConstant(int constant, int name) {{{*/
[4248]459void Icefront::InputUpdateFromConstant(int constant, int name){
460 /*Nothing updated yet*/
461}
462/*}}}*/
[12365]463/*FUNCTION Icefront::InputUpdateFromConstant(bool constant, int name) {{{*/
[4248]464void Icefront::InputUpdateFromConstant(bool constant, int name){
465 /*Nothing updated yet*/
466}
467/*}}}*/
[12365]468/*FUNCTION Icefront::InputUpdateFromSolution{{{*/
[12472]469void Icefront::InputUpdateFromSolution(IssmDouble* solution){
[4248]470 /*Nothing updated yet*/
471}
472/*}}}*/
473
474/*Icefront numerics: */
[9785]475#ifdef _HAVE_DIAGNOSTIC_
[12365]476/*FUNCTION Icefront::CreatePVectorDiagnosticHoriz {{{*/
[5935]477ElementVector* Icefront::CreatePVectorDiagnosticHoriz(void){
478
479 int type;
[14688]480 inputs->GetInputValue(&type,IceFrontTypeEnum);
[5935]481
482 switch(type){
483 case MacAyeal2dIceFrontEnum:
484 return CreatePVectorDiagnosticMacAyeal2d();
[11874]485 #ifdef _HAVE_3D_
[5935]486 case MacAyeal3dIceFrontEnum:
487 return CreatePVectorDiagnosticMacAyeal3d();
488 case PattynIceFrontEnum:
489 return CreatePVectorDiagnosticPattyn();
490 case StokesIceFrontEnum:
491 return CreatePVectorDiagnosticStokes();
[9775]492 #endif
[5935]493 default:
[13036]494 _error_("Icefront type " << EnumToStringx(type) << " not supported yet");
[5935]495 }
496}
497/*}}}*/
[12365]498/*FUNCTION Icefront::CreatePVectorDiagnosticMacAyeal2d{{{*/
[5935]499ElementVector* Icefront::CreatePVectorDiagnosticMacAyeal2d(void){
[3683]500
[5719]501 /*Intermediary*/
[15298]502 int ig,index1,index2,fill;
503 IssmDouble Jdet;
504 IssmDouble thickness,bed,pressure,ice_pressure,rho_water,rho_ice,gravity;
505 IssmDouble water_pressure,air_pressure,surface_under_water,base_under_water;
506 IssmDouble xyz_list[NUMVERTICESSEG][3];
507 IssmDouble normal[2];
[5719]508 GaussTria *gauss;
[3683]509
[15298]510 /*return of element is on water*/
[5719]511 Tria* tria=((Tria*)element);
[15298]512 if(tria->IsOnWater()) return NULL;
[3683]513
[15298]514 /*Fetch number of nodes and dof for this finite element*/
515 //int numnodes = this->NumberofNodes();
516 int numnodes = 2;
517 int numdof = numnodes*NDOF2;
518
519 /*Initialize Element vector and vectors*/
[5986]520 ElementVector* pe=new ElementVector(nodes,NUMVERTICESSEG,this->parameters,MacAyealApproximationEnum);
[15298]521 IssmDouble* basis = xNew<IssmDouble>(numnodes);
[5935]522
523 /*Retrieve all inputs and parameters*/
[14763]524 GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICESSEG);
[6412]525 Input* thickness_input=tria->inputs->GetInput(ThicknessEnum); _assert_(thickness_input);
526 Input* bed_input =tria->inputs->GetInput(BedEnum); _assert_(bed_input);
[10135]527 inputs->GetInputValue(&fill,FillEnum);
[5715]528 rho_water=matpar->GetRhoWater();
529 rho_ice =matpar->GetRhoIce();
530 gravity =matpar->GetG();
[5808]531 GetSegmentNormal(&normal[0],xyz_list);
[5715]532
[5935]533 /*Start looping on Gaussian points*/
[5719]534 index1=tria->GetNodeIndex(nodes[0]);
535 index2=tria->GetNodeIndex(nodes[1]);
536 gauss=new GaussTria(index1,index2,3);
[5715]537
[5719]538 for(ig=gauss->begin();ig<gauss->end();ig++){
[5715]539
[5719]540 gauss->GaussPoint(ig);
[5715]541
[10135]542 thickness_input->GetInputValue(&thickness,gauss);
543 bed_input->GetInputValue(&bed,gauss);
[5715]544
[5719]545 switch(fill){
546 case WaterEnum:
[8224]547 surface_under_water=min(0.,thickness+bed); // 0 if the top of the glacier is above water level
548 base_under_water=min(0.,bed); // 0 if the bottom of the glacier is above water level
[5719]549 water_pressure=1.0/2.0*gravity*rho_water*(pow(surface_under_water,2) - pow(base_under_water,2));
550 break;
551 case AirEnum:
552 water_pressure=0;
553 break;
[7306]554 case IceEnum:
555 water_pressure=-1.0/2.0*gravity*rho_ice*pow(thickness,2); // we are facing a wall of ice. use water_pressure to cancel the lithostatic pressure.
556 break;
[5719]557 default:
[13036]558 _error_("fill type " << EnumToStringx(fill) << " not supported yet");
[5715]559 }
[5719]560 ice_pressure=1.0/2.0*gravity*rho_ice*pow(thickness,2);
561 air_pressure=0;
[5715]562 pressure = ice_pressure + water_pressure + air_pressure;
563
[5719]564 tria->GetSegmentJacobianDeterminant(&Jdet,&xyz_list[0][0],gauss);
[15298]565 tria->GetSegmentNodalFunctions(&basis[0],gauss,index1,index2);
[5715]566
[5719]567 for (int i=0;i<numnodes;i++){
[15298]568 pe->values[2*i+0]+= pressure*Jdet*gauss->weight*normal[0]*basis[i];
569 pe->values[2*i+1]+= pressure*Jdet*gauss->weight*normal[1]*basis[i];
[5715]570 }
[5719]571 }
[10381]572
[10367]573 /*Transform load vector*/
[10523]574 TransformLoadVectorCoord(pe,nodes,NUMVERTICESSEG,XYEnum);
[5715]575
[5935]576 /*Clean up and return*/
[15298]577 xDelete<IssmDouble>(basis);
[5719]578 delete gauss;
[5935]579 return pe;
[5715]580}
581/*}}}*/
[10407]582#endif
[10367]583
[9785]584#ifdef _HAVE_CONTROL_
[12365]585/*FUNCTION Icefront::CreatePVectorAdjointHoriz {{{*/
[9785]586ElementVector* Icefront::CreatePVectorAdjointHoriz(void){
587
588 /*No load vector applied to the adjoint*/
589 return NULL;
590}
591/*}}}*/
592#endif
[11874]593#ifdef _HAVE_3D_
[12365]594/*FUNCTION Icefront::CreatePVectorDiagnosticMacAyeal3d{{{*/
[5935]595ElementVector* Icefront::CreatePVectorDiagnosticMacAyeal3d(void){
[5715]596
[13813]597 Icefront *icefront = NULL;
598 Penta *penta = NULL;
599 Tria *tria = NULL;
[5715]600
[5720]601 /*Cast element onto Penta*/
602 penta =(Penta*)this->element;
[5715]603
[5720]604 /*Return if not on bed*/
[5935]605 if(!penta->IsOnBed() || penta->IsOnWater()) return NULL;
[5715]606
[5720]607 /*Spawn Tria and call MacAyeal2d*/
608 tria =(Tria*)penta->SpawnTria(0,1,2);
609 icefront=(Icefront*)this->copy();
610 icefront->element=tria;
[14688]611 icefront->inputs->AddInput(new IntInput(IceFrontTypeEnum,MacAyeal2dIceFrontEnum));
[5935]612 ElementVector* pe=icefront->CreatePVectorDiagnosticMacAyeal2d();
[3683]613
[5935]614 /*clean-up and return*/
[13129]615 delete tria->material;
[5720]616 delete tria;
617 delete icefront;
[5935]618 return pe;
[3683]619}
620/*}}}*/
[12365]621/*FUNCTION Icefront::CreatePVectorDiagnosticPattyn{{{*/
[5935]622ElementVector* Icefront::CreatePVectorDiagnosticPattyn(void){
[3683]623
[5808]624 /*Constants*/
625 const int numdofs = NUMVERTICESQUA *NDOF2;
[3683]626
[5808]627 /*Intermediaries*/
628 int i,j,ig,index1,index2,index3,index4;
629 int fill;
[12472]630 IssmDouble surface,pressure,ice_pressure,rho_water,rho_ice,gravity;
631 IssmDouble water_pressure,air_pressure;
632 IssmDouble Jdet,z_g;
633 IssmDouble xyz_list[NUMVERTICESQUA][3];
634 IssmDouble normal[3];
635 IssmDouble l1l4[4];
[5808]636 GaussPenta *gauss = NULL;
[3683]637
[5935]638 Penta* penta=(Penta*)element;
639
640 /*Initialize Element vector and return if necessary*/
641 if(penta->IsOnWater()) return NULL;
[5986]642 ElementVector* pe=new ElementVector(nodes,NUMVERTICESQUA,this->parameters,PattynApproximationEnum);
[5935]643
644 /*Retrieve all inputs and parameters*/
[14763]645 GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICESQUA);
[6412]646 Input* surface_input =penta->inputs->GetInput(SurfaceEnum); _assert_(surface_input);
[10135]647 inputs->GetInputValue(&fill,FillEnum);
[5808]648 rho_water=matpar->GetRhoWater();
649 rho_ice =matpar->GetRhoIce();
650 gravity =matpar->GetG();
651 GetQuadNormal(&normal[0],xyz_list);
[3683]652
[5808]653 /*Identify which nodes are in the quad: */
654 index1=element->GetNodeIndex(nodes[0]);
655 index2=element->GetNodeIndex(nodes[1]);
656 index3=element->GetNodeIndex(nodes[2]);
657 index4=element->GetNodeIndex(nodes[3]);
[3683]658
[5808]659 /* Start looping on the number of gaussian points: */
[12472]660 IssmDouble zmax=xyz_list[0][2]; for(i=1;i<NUMVERTICESQUA;i++) if(xyz_list[i][2]>zmax) zmax=xyz_list[i][2];
661 IssmDouble zmin=xyz_list[0][2]; for(i=1;i<NUMVERTICESQUA;i++) if(xyz_list[i][2]<zmin) zmin=xyz_list[i][2];
[5808]662 if(zmax>0 && zmin<0) gauss=new GaussPenta(index1,index2,index3,index4,3,10); //refined in vertical because of the sea level discontinuity
663 else gauss=new GaussPenta(index1,index2,index3,index4,3,3);
664 for(ig=gauss->begin();ig<gauss->end();ig++){
[3683]665
[5808]666 gauss->GaussPoint(ig);
[3683]667
[5808]668 penta->GetQuadNodalFunctions(l1l4,gauss,index1,index2,index3,index4);
669 penta->GetQuadJacobianDeterminant(&Jdet,xyz_list,gauss);
670 z_g=penta->GetZcoord(gauss);
[10135]671 surface_input->GetInputValue(&surface,gauss);
[3683]672
[5808]673 switch(fill){
674 case WaterEnum:
[8224]675 water_pressure=rho_water*gravity*min(0.,z_g);//0 if the gaussian point is above water level
[5808]676 break;
677 case AirEnum:
678 water_pressure=0;
679 break;
680 default:
[13036]681 _error_("fill type " << EnumToStringx(fill) << " not supported yet");
[5808]682 }
683 ice_pressure=rho_ice*gravity*(surface-z_g);
684 air_pressure=0;
685 pressure = ice_pressure + water_pressure + air_pressure;
[3683]686
[5935]687 for(i=0;i<NUMVERTICESQUA;i++) for(j=0;j<NDOF2;j++) pe->values[i*NDOF2+j]+=Jdet*gauss->weight*pressure*l1l4[i]*normal[j];
[3683]688 }
689
[10381]690 /*Transform load vector*/
[10523]691 TransformLoadVectorCoord(pe,nodes,NUMVERTICESQUA,XYEnum);
[10381]692
[5935]693 /*Clean up and return*/
[5808]694 delete gauss;
[5935]695 return pe;
[3683]696}
697/*}}}*/
[12365]698/*FUNCTION Icefront::CreatePVectorDiagnosticStokes{{{*/
[5935]699ElementVector* Icefront::CreatePVectorDiagnosticStokes(void){
[3683]700
[5808]701 /*Constants*/
702 const int numdofs = NUMVERTICESQUA *NDOF4;
[3683]703
[5808]704 /*Intermediaries*/
705 int i,j,ig,index1,index2,index3,index4;
706 int fill;
[12472]707 IssmDouble pressure,rho_water,gravity;
708 IssmDouble water_pressure,air_pressure;
709 IssmDouble Jdet,z_g;
710 IssmDouble xyz_list[NUMVERTICESQUA][3];
711 IssmDouble normal[3];
712 IssmDouble l1l4[4];
[5808]713 GaussPenta *gauss = NULL;
[3683]714
[5935]715 Penta* penta=(Penta*)element;
716
717 /*Initialize Element vector and return if necessary*/
718 if(penta->IsOnWater()) return NULL;
[5986]719 ElementVector* pe=new ElementVector(nodes,NUMVERTICESQUA,this->parameters,StokesApproximationEnum);
[5935]720
721 /*Retrieve all inputs and parameters*/
[14763]722 GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICESQUA);
[10135]723 inputs->GetInputValue(&fill,FillEnum);
[5808]724 rho_water=matpar->GetRhoWater();
725 gravity =matpar->GetG();
726 GetQuadNormal(&normal[0],xyz_list);
[3683]727
[5808]728 /*Identify which nodes are in the quad: */
729 index1=element->GetNodeIndex(nodes[0]);
730 index2=element->GetNodeIndex(nodes[1]);
731 index3=element->GetNodeIndex(nodes[2]);
732 index4=element->GetNodeIndex(nodes[3]);
[3683]733
[5808]734 /* Start looping on the number of gaussian points: */
[12472]735 IssmDouble zmax=xyz_list[0][2]; for(i=1;i<NUMVERTICESQUA;i++) if(xyz_list[i][2]>zmax) zmax=xyz_list[i][2];
736 IssmDouble zmin=xyz_list[0][2]; for(i=1;i<NUMVERTICESQUA;i++) if(xyz_list[i][2]<zmin) zmin=xyz_list[i][2];
[5808]737 if(zmax>0 && zmin<0) gauss=new GaussPenta(index1,index2,index3,index4,3,30); //refined in vertical because of the sea level discontinuity
738 else gauss=new GaussPenta(index1,index2,index3,index4,3,3);
739 for(ig=gauss->begin();ig<gauss->end();ig++){
[3683]740
[5808]741 gauss->GaussPoint(ig);
[3683]742
[5808]743 penta->GetQuadNodalFunctions(l1l4,gauss,index1,index2,index3,index4);
744 penta->GetQuadJacobianDeterminant(&Jdet,xyz_list,gauss);
745 z_g=penta->GetZcoord(gauss);
[3683]746
[5808]747 switch(fill){
748 case WaterEnum:
[8224]749 water_pressure=rho_water*gravity*min(0.,z_g);//0 if the gaussian point is above water level
[5808]750 break;
751 case AirEnum:
752 water_pressure=0;
753 break;
754 default:
[13036]755 _error_("fill type " << EnumToStringx(fill) << " not supported yet");
[5808]756 }
757 air_pressure=0;
758 pressure = water_pressure + air_pressure; //no ice pressure fore Stokes
[3683]759
[5808]760 for(i=0;i<NUMVERTICESQUA;i++){
761 for(j=0;j<NDOF4;j++){
[5935]762 if(j<3) pe->values[i*NDOF4+j]+=Jdet*gauss->weight*pressure*l1l4[i]*normal[j];
763 else pe->values[i*NDOF4+j]+=0; //pressure term
[5808]764 }
765 }
766 }
[3683]767
[10381]768 /*Transform load vector*/
[10523]769 TransformLoadVectorCoord(pe,nodes,NUMVERTICESQUA,XYZPEnum);
[10381]770
[5935]771 /*Clean up and return*/
[5808]772 delete gauss;
[5935]773 return pe;
[3683]774}
775/*}}}*/
[9775]776#endif
[12365]777/*FUNCTION Icefront::GetDofList {{{*/
[5772]778void Icefront::GetDofList(int** pdoflist,int approximation_enum,int setenum){
[3683]779
[5096]780 int numberofdofs=0;
781 int count=0;
[3683]782 int type;
[5096]783 int numberofnodes=2;
[3683]784
[5096]785 /*output: */
786 int* doflist=NULL;
787
788 /*recover type: */
[14688]789 inputs->GetInputValue(&type,IceFrontTypeEnum);
[5096]790
791 /*Some checks for debugging*/
[6412]792 _assert_(nodes);
[13622]793
[5096]794 /*How many nodes? :*/
[5715]795 if(type==MacAyeal2dIceFrontEnum || type==MacAyeal3dIceFrontEnum)
796 numberofnodes=2;
797 else
798 numberofnodes=4;
[13622]799
[5096]800 /*Figure out size of doflist: */
[13761]801 for(int i=0;i<numberofnodes;i++){
[5772]802 numberofdofs+=nodes[i]->GetNumberOfDofs(approximation_enum,setenum);
[3683]803 }
[5096]804
805 /*Allocate: */
[12455]806 doflist=xNew<int>(numberofdofs);
[5096]807
808 /*Populate: */
809 count=0;
[13761]810 for(int i=0;i<numberofnodes;i++){
[5772]811 nodes[i]->GetDofList(doflist+count,approximation_enum,setenum);
812 count+=nodes[i]->GetNumberOfDofs(approximation_enum,setenum);
[3683]813 }
814
815 /*Assign output pointers:*/
[5096]816 *pdoflist=doflist;
[3683]817}
818/*}}}*/
[12365]819/*FUNCTION Icefront::GetSegmentNormal {{{*/
[12472]820void Icefront:: GetSegmentNormal(IssmDouble* normal,IssmDouble xyz_list[4][3]){
[3683]821
[4946]822 /*Build unit outward pointing vector*/
[5701]823 const int numnodes=NUMVERTICESSEG;
[12472]824 IssmDouble vector[2];
825 IssmDouble norm;
[3683]826
[4946]827 vector[0]=xyz_list[1][0] - xyz_list[0][0];
828 vector[1]=xyz_list[1][1] - xyz_list[0][1];
[3683]829
[4946]830 norm=sqrt(pow(vector[0],2.0)+pow(vector[1],2.0));
[3683]831
[4946]832 normal[0]= + vector[1]/norm;
833 normal[1]= - vector[0]/norm;
[3683]834}
835/*}}}*/
[12365]836/*FUNCTION Icefront::GetQuadNormal {{{*/
[12472]837void Icefront:: GetQuadNormal(IssmDouble* normal,IssmDouble xyz_list[4][3]){
[5808]838
839 /*Build unit outward pointing vector*/
[12472]840 IssmDouble AB[3];
841 IssmDouble AC[3];
842 IssmDouble norm;
[5808]843
844 AB[0]=xyz_list[1][0] - xyz_list[0][0];
845 AB[1]=xyz_list[1][1] - xyz_list[0][1];
846 AB[2]=xyz_list[1][2] - xyz_list[0][2];
847 AC[0]=xyz_list[2][0] - xyz_list[0][0];
848 AC[1]=xyz_list[2][1] - xyz_list[0][1];
849 AC[2]=xyz_list[2][2] - xyz_list[0][2];
850
851 cross(normal,AB,AC);
852 norm=sqrt(pow(normal[0],2.0)+pow(normal[1],2.0)+pow(normal[2],2.0));
853
854 for(int i=0;i<3;i++) normal[i]=normal[i]/norm;
855}
856/*}}}*/
Note: See TracBrowser for help on using the repository browser.