source: issm/branches/trunk-jpl-damage/src/c/objects/Node.cpp@ 11684

Last change on this file since 11684 was 11684, checked in by cborstad, 13 years ago

merged revisions 11428:11680 from trunk-jpl into branches/trunk-jpl-damage

File size: 28.4 KB
RevLine 
[1]1/*!\file Node.c
2 * \brief: implementation of the Node object
3 */
4
[3417]5/*Include files: {{{1*/
[1]6#ifdef HAVE_CONFIG_H
[9320]7 #include <config.h>
[1]8#else
9#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
10#endif
11
[9320]12#include <stdio.h>
[1]13#include <string.h>
[3681]14#include "./objects.h"
[4236]15#include "../Container/Container.h"
[1]16#include "../EnumDefinitions/EnumDefinitions.h"
17#include "../shared/shared.h"
[3775]18#include "../include/include.h"
[5114]19#include "../modules/modules.h"
[3417]20/*}}}*/
[4546]21
22/*Node constructors and destructors:*/
23/*FUNCTION Node::Node() default constructor {{{1*/
[1]24Node::Node(){
[5254]25 this->inputs=NULL;
26 this->hvertex=NULL;
27 return;
[1]28}
[2907]29/*}}}*/
[10245]30/*FUNCTION Node::Node(int node_id,int node_sid,int vertex_id,int io_index, IoModel* iomodel,int analysis_type) {{{1*/
[4140]31Node::Node(int node_id,int node_sid,int vertex_id,int io_index, IoModel* iomodel,int analysis_type){
[3417]32
[4117]33 /*Intermediary*/
[8245]34 int k,l;
[5772]35 int gsize;
[9356]36 int dim;
[1]37
[9356]38 /*Fetch parameters: */
[9719]39 iomodel->Constant(&dim,MeshDimensionEnum);
[9356]40
[3417]41 /*id: */
[4140]42 this->id=node_id;
43 this->sid=node_sid;
[3984]44 this->analysis_type=analysis_type;
[3417]45
[10367]46 /*Initialize coord_system: Identity matrix by default*/
47 for(k=0;k<3;k++) for(l=0;l<3;l++) this->coord_system[k][l]=0.0;
48 for(k=0;k<3;k++) this->coord_system[k][k]=1.0;
49
[3417]50 /*indexing:*/
[9661]51 DistributeNumDofs(&this->indexing,analysis_type,iomodel->Data(FlowequationVertexEquationEnum)+io_index); //number of dofs per node
[5772]52 gsize=this->indexing.gsize;
[3417]53
[4983]54 /*Hooks*/
[4396]55 this->hvertex=new Hook(&vertex_id,1); //node id is the same as the vertex id, continuous galerkin!
[95]56
[4117]57 //intialize inputs, and add as many inputs per element as requested:
58 this->inputs=new Inputs();
[10367]59 if (iomodel->Data(MeshVertexonbedEnum))
60 this->inputs->AddInput(new BoolInput(MeshVertexonbedEnum,(IssmBool)iomodel->Data(MeshVertexonbedEnum)[io_index]));
61 if (iomodel->Data(MeshVertexonsurfaceEnum))
62 this->inputs->AddInput(new BoolInput(MeshVertexonsurfaceEnum,(IssmBool)iomodel->Data(MeshVertexonsurfaceEnum)[io_index]));
63 if (iomodel->Data(MaskVertexonfloatingiceEnum))
64 this->inputs->AddInput(new BoolInput(MaskVertexonfloatingiceEnum,(IssmBool)iomodel->Data(MaskVertexonfloatingiceEnum)[io_index]));
65 if (iomodel->Data(MaskVertexongroundediceEnum))
66 this->inputs->AddInput(new BoolInput(MaskVertexongroundediceEnum,(IssmBool)iomodel->Data(MaskVertexongroundediceEnum)[io_index]));
67 if (analysis_type==DiagnosticHorizAnalysisEnum)
68 this->inputs->AddInput(new IntInput(ApproximationEnum,(IssmInt)iomodel->Data(FlowequationVertexEquationEnum)[io_index]));
[7515]69
[3451]70 /*set single point constraints: */
71
[7515]72 /*spc all nodes on water*/
[9641]73 if (!iomodel->Data(MaskVertexonwaterEnum)) _error_("iomodel->nodeonwater is NULL");
74 if (iomodel->Data(MaskVertexonwaterEnum)[io_index]){
[7515]75 for(k=1;k<=gsize;k++){
76 this->FreezeDof(k);
77 }
78 }
79
[3451]80 /*Diagnostic Horiz*/
[10367]81 #ifdef _HAVE_DIAGNOSTIC_
[4021]82 if (analysis_type==DiagnosticHorizAnalysisEnum){
[10367]83
84 /*Coordinate system provided, convert to coord_system matrix*/
85 _assert_(iomodel->Data(DiagnosticReferentialEnum));
86 XZvectorsToCoordinateSystem(&this->coord_system[0][0],iomodel->Data(DiagnosticReferentialEnum)+io_index*6);
87
[9356]88 if (dim==3){
[8303]89 /*We have a 3d mesh, we may have collapsed elements, hence dead nodes. Freeze them out: */
[10367]90 _assert_(iomodel->Data(MeshVertexonbedEnum));
91 _assert_(iomodel->Data(FlowequationVertexEquationEnum));
[9729]92 if (iomodel->Data(FlowequationVertexEquationEnum)[io_index]==MacAyealApproximationEnum && !iomodel->Data(MeshVertexonbedEnum)[io_index]){
[5772]93 for(k=1;k<=gsize;k++) this->FreezeDof(k);
[5532]94 }
[9661]95 if (iomodel->Data(FlowequationVertexEquationEnum)[io_index]==MacAyealPattynApproximationEnum && iomodel->Data(FlowequationBordermacayealEnum)[io_index]){
[9729]96 if(!iomodel->Data(MeshVertexonbedEnum)[io_index]){
[5772]97 for(k=1;k<=gsize;k++) this->FreezeDof(k);
[3451]98 }
99 }
[9661]100 if (iomodel->Data(FlowequationVertexEquationEnum)[io_index]==MacAyealStokesApproximationEnum && iomodel->Data(FlowequationBordermacayealEnum)[io_index]){
[9729]101 if(!iomodel->Data(MeshVertexonbedEnum)[io_index]){
[7000]102 for(k=1;k<=2;k++) this->FreezeDof(k);
[6141]103 }
104 }
[3451]105 }
106 /*spc all nodes on hutter*/
[9661]107 if (iomodel->Data(FlowequationVertexEquationEnum)[io_index]==HutterApproximationEnum){
[5772]108 for(k=1;k<=gsize;k++){
[3420]109 this->FreezeDof(k);
[3417]110 }
111 }
112 }
[10367]113 #endif
[3451]114
115 /*Diagnostic Hutter*/
[4021]116 if (analysis_type==DiagnosticHutterAnalysisEnum){
[9661]117 if (!iomodel->Data(FlowequationVertexEquationEnum)) _error_("iomodel->vertices_type is NULL");
[9285]118 /*Constrain all nodes that are not Hutter*/
[9661]119 if (!iomodel->Data(FlowequationVertexEquationEnum)[io_index]==HutterApproximationEnum){
[5772]120 for(k=1;k<=gsize;k++){
[3442]121 this->FreezeDof(k);
[3441]122 }
123 }
124 }
[3451]125
[9218]126 /*Prognostic/ Melting/ Slopecompute/ Balancethickness*/
[3504]127 if (
[4021]128 analysis_type==PrognosticAnalysisEnum ||
129 analysis_type==MeltingAnalysisEnum ||
[4285]130 analysis_type==BedSlopeAnalysisEnum ||
131 analysis_type==SurfaceSlopeAnalysisEnum ||
[8287]132 analysis_type==BalancethicknessAnalysisEnum
[3504]133 ){
[9356]134 if (dim==3){
[8303]135 /*On a 3d mesh, we may have collapsed elements, hence dead nodes. Freeze them out: */
[9729]136 _assert_(iomodel->Data(MeshVertexonbedEnum));
137 if (!iomodel->Data(MeshVertexonbedEnum)[io_index]){
[5772]138 for(k=1;k<=gsize;k++){
[3451]139 this->FreezeDof(k);
140 }
141 }
142 }
143 }
[3632]144
[1]145}
[2907]146/*}}}*/
[4546]147/*FUNCTION Node::~Node(){{{1*/
[1]148Node::~Node(){
[3632]149 delete inputs;
[4401]150 delete hvertex;
[1]151 return;
152}
[2907]153/*}}}*/
[4546]154
155/*Object virtual functions definitions:*/
156/*FUNCTION Node::Echo{{{1*/
[4248]157void Node::Echo(void){
[1]158
[4248]159 printf("Node:\n");
160 printf(" id: %i\n",id);
161 printf(" sid: %i\n",sid);
[8224]162 printf(" analysis_type: %s\n",EnumToStringx(analysis_type));
[4248]163 indexing.Echo();
164 printf(" hvertex: not displayed\n");
165 printf(" inputs: %p\n",inputs);
[3417]166
167
168}
169/*}}}*/
[4546]170/*FUNCTION Node::DeepEcho{{{1*/
[3417]171void Node::DeepEcho(void){
172
173 printf("Node:\n");
174 printf(" id: %i\n",id);
[4140]175 printf(" sid: %i\n",sid);
[8224]176 printf(" analysis_type: %s\n",EnumToStringx(analysis_type));
[3417]177 indexing.DeepEcho();
[3483]178 printf("Vertex:\n");
[4396]179 hvertex->DeepEcho();
[3632]180 printf(" inputs\n");
[3417]181
[5114]182
[3417]183}
184/*}}}*/
[4546]185/*FUNCTION Node::Id{{{1*/
[4248]186int Node::Id(void){ return id; }
187/*}}}*/
[4546]188/*FUNCTION Node::MyRank{{{1*/
[4248]189int Node::MyRank(void){
190 extern int my_rank;
191
192 return my_rank;
193}
194/*}}}*/
[9777]195#ifdef _SERIAL_
[4546]196/*FUNCTION Node::Marshall{{{1*/
[4248]197void Node::Marshall(char** pmarshalled_dataset){
198
199 char* marshalled_dataset=NULL;
200 int enum_type=0;
201 char* marshalled_inputs=NULL;
[5772]202 int marshalled_inputssize;
[4248]203
204 /*recover marshalled_dataset: */
205 marshalled_dataset=*pmarshalled_dataset;
206
207 /*get enum type of Node: */
208 enum_type=NodeEnum;
209
210 /*marshall enum: */
211 memcpy(marshalled_dataset,&enum_type,sizeof(enum_type));marshalled_dataset+=sizeof(enum_type);
212
213 /*marshall Node data: */
214 memcpy(marshalled_dataset,&id,sizeof(id));marshalled_dataset+=sizeof(id);
215 memcpy(marshalled_dataset,&sid,sizeof(sid));marshalled_dataset+=sizeof(sid);
216 memcpy(marshalled_dataset,&analysis_type,sizeof(analysis_type));marshalled_dataset+=sizeof(analysis_type);
[10367]217 memcpy(marshalled_dataset,&coord_system,9*sizeof(double));marshalled_dataset+=9*sizeof(double);
[8245]218
[4248]219 /*marshall objects: */
220 indexing.Marshall(&marshalled_dataset);
[4396]221 hvertex->Marshall(&marshalled_dataset);
[4248]222
223 /*Marshall inputs: */
[5772]224 marshalled_inputssize=inputs->MarshallSize();
[4248]225 marshalled_inputs=inputs->Marshall();
[5772]226 memcpy(marshalled_dataset,marshalled_inputs,marshalled_inputssize*sizeof(char));
227 marshalled_dataset+=marshalled_inputssize;
[4248]228
229 /*Free ressources:*/
230 xfree((void**)&marshalled_inputs);
231
232 *pmarshalled_dataset=marshalled_dataset;
233 return;
234}
235/*}}}*/
[4546]236/*FUNCTION Node::MarshallSize{{{1*/
[4248]237int Node::MarshallSize(){
238
239 return sizeof(id)+
240 sizeof(sid)+
241 indexing.MarshallSize()+
[4396]242 hvertex->MarshallSize()+
[4248]243 inputs->MarshallSize()+
244 sizeof(analysis_type)+
[8245]245 9*sizeof(double)+
[4248]246 sizeof(int); //sizeof(int) for enum type
247}
248/*}}}*/
[4546]249/*FUNCTION Node::Demarshall{{{1*/
[3417]250void Node::Demarshall(char** pmarshalled_dataset){
251
252 char* marshalled_dataset=NULL;
253
254 /*recover marshalled_dataset: */
255 marshalled_dataset=*pmarshalled_dataset;
256
257 /*this time, no need to get enum type, the pointer directly points to the beginning of the
258 *object data (thanks to DataSet::Demarshall):*/
259
260 memcpy(&id,marshalled_dataset,sizeof(id));marshalled_dataset+=sizeof(id);
[4140]261 memcpy(&sid,marshalled_dataset,sizeof(sid));marshalled_dataset+=sizeof(sid);
[3984]262 memcpy(&analysis_type,marshalled_dataset,sizeof(analysis_type));marshalled_dataset+=sizeof(analysis_type);
[10367]263 memcpy(&coord_system,marshalled_dataset,9*sizeof(double));marshalled_dataset+=9*sizeof(double);
[3417]264
265 /*demarshall objects: */
266 indexing.Demarshall(&marshalled_dataset);
[4396]267 hvertex=new Hook(); hvertex->Demarshall(&marshalled_dataset);
[3632]268
269 /*demarshall inputs: */
270 inputs=(Inputs*)DataSetDemarshallRaw(&marshalled_dataset);
271
[3417]272 /*return: */
273 *pmarshalled_dataset=marshalled_dataset;
274 return;
275}
276/*}}}*/
[9777]277#endif
[9883]278/*FUNCTION Node::ObjectEnum{{{1*/
279int Node::ObjectEnum(void){
[3417]280
[4248]281 return NodeEnum;
[3417]282
[4248]283}
284/*}}}*/
[3632]285
[4546]286/*Node management:*/
287/*FUNCTION Node::Configure {{{1*/
[4248]288void Node::Configure(DataSet* nodesin,Vertices* verticesin){
[3417]289
[4248]290 int i;
[3417]291
[4248]292 /*Take care of hooking up all objects for this element, ie links the objects in the hooks to their respective
[5772]293 * datasets, using internal ids and off_sets hidden in hooks: */
[4396]294 hvertex->configure(verticesin);
[4248]295
[3417]296}
[4575]297/*FUNCTION Node::SetCurrentConfiguration {{{1*/
298void Node::SetCurrentConfiguration(DataSet* nodesin,Vertices* verticesin){
299
300}
[4546]301/*FUNCTION Node::GetDof {{{1*/
[5772]302int Node::GetDof(int dofindex,int setenum){
[3446]303
[5772]304 if(setenum==GsetEnum){
[9302]305 _assert_(dofindex>=0 && dofindex<indexing.gsize);
[5772]306 return indexing.gdoflist[dofindex];
307 }
308 else if(setenum==FsetEnum){
[9302]309 _assert_(dofindex>=0 && dofindex<indexing.fsize);
[5772]310 return indexing.fdoflist[dofindex];
311 }
312 else if(setenum==SsetEnum){
[9302]313 _assert_(dofindex>=0 && dofindex<indexing.ssize);
[5772]314 return indexing.sdoflist[dofindex];
315 }
[8224]316 else _error_("%s%s%s"," set of enum type ",EnumToStringx(setenum)," not supported yet!");
[3446]317
318}
319/*}}}*/
[4546]320/*FUNCTION Node::GetDofList1{{{1*/
[3446]321int Node::GetDofList1(void){
322
323 Vertex* vertex=NULL;
324
[4396]325 vertex=(Vertex*)this->hvertex->delivers();
[3446]326
327 return vertex->dof;
328}
329/*}}}*/
[4546]330/*FUNCTION Node::GetDofList{{{1*/
[5772]331void Node::GetDofList(int* outdoflist,int approximation_enum,int setenum){
[3446]332 int i;
[5259]333 int count=0;
[6032]334 int count2=0;
[5772]335
336 if(approximation_enum==NoneApproximationEnum){
337 if(setenum==GsetEnum)for(i=0;i<this->indexing.gsize;i++) outdoflist[i]=indexing.gdoflist[i];
338 if(setenum==FsetEnum)for(i=0;i<this->indexing.fsize;i++) outdoflist[i]=indexing.fdoflist[i];
339 if(setenum==SsetEnum)for(i=0;i<this->indexing.ssize;i++) outdoflist[i]=indexing.sdoflist[i];
340 }
341 else{
[5259]342
[5772]343 if(setenum==GsetEnum){
344 if(indexing.doftype){
345 count=0;
346 for(i=0;i<this->indexing.gsize;i++){
347 if(indexing.doftype[i]==approximation_enum){
348 outdoflist[count]=indexing.gdoflist[i];
349 count++;
350 }
351 }
[6412]352 _assert_(count); //at least one dof should be the approximation requested
[5259]353 }
[5772]354 else for(i=0;i<this->indexing.gsize;i++) outdoflist[i]=indexing.gdoflist[i];
[5259]355 }
[5772]356 else if(setenum==FsetEnum){
357 if(indexing.doftype){
358 count=0;
[6032]359 count2=0;
[5772]360 for(i=0;i<this->indexing.gsize;i++){
[6032]361 if(indexing.f_set[i]){
362 if(indexing.doftype[i]==approximation_enum){
363 outdoflist[count]=indexing.fdoflist[count2];
364 count++;
365 }
366 count2++;
[5772]367 }
368 }
369 }
370 else for(i=0;i<this->indexing.fsize;i++) outdoflist[i]=indexing.fdoflist[i];
371 }
372 else if(setenum==SsetEnum){
373 if(indexing.doftype){
374 count=0;
[6032]375 count2=0;
[5772]376 for(i=0;i<this->indexing.gsize;i++){
[6032]377 if(indexing.s_set[i]){
378 if(indexing.doftype[i]==approximation_enum){
379 outdoflist[count]=indexing.sdoflist[count2];
380 count++;
381 }
382 count2++;
[5772]383 }
384 }
385 }
386 else for(i=0;i<this->indexing.ssize;i++) outdoflist[i]=indexing.sdoflist[i];
387 }
[8224]388 else _error_("%s%s%s"," set of enum type ",EnumToStringx(setenum)," not supported yet!");
[3446]389 }
[5772]390}
391/*}}}*/
[6231]392/*FUNCTION Node::GetSidList{{{1*/
393int Node::GetSidList(void){
394
395 Vertex* vertex=NULL;
396
397 vertex=(Vertex*)this->hvertex->delivers();
398
399 return vertex->sid;
400}
401/*}}}*/
[5843]402/*FUNCTION Node::GetLocalDofList{{{1*/
403void Node::GetLocalDofList(int* outdoflist,int approximation_enum,int setenum){
[5772]404 int i;
405 int count=0;
406 int count2=0;
407
408 if(approximation_enum==NoneApproximationEnum){
409 if(setenum==GsetEnum)for(i=0;i<this->indexing.gsize;i++) outdoflist[i]=i;
410 else if(setenum==FsetEnum){
411 count=0;
[7246]412 for(i=0;i<this->indexing.gsize;i++){
[5772]413 if(indexing.f_set[i]){
414 outdoflist[count]=i;
415 count++;
416 }
417 }
418 }
419 else if(setenum==SsetEnum){
420 count=0;
[7246]421 for(i=0;i<this->indexing.gsize;i++){
[5772]422 if(indexing.s_set[i]){
423 outdoflist[count]=i;
424 count++;
425 }
426 }
427 }
[8224]428 else _error_("%s%s%s"," set of enum type ",EnumToStringx(setenum)," not supported yet!");
[5772]429 }
[5259]430 else{
[5772]431
432 if(setenum==GsetEnum){
433 if(indexing.doftype){
434 count=0;
435 for(i=0;i<this->indexing.gsize;i++){
436 if(indexing.doftype[i]==approximation_enum){
437 outdoflist[count]=count;
438 count++;
439 }
440 }
[6412]441 _assert_(count);
[5772]442 }
443 else for(i=0;i<this->indexing.gsize;i++) outdoflist[i]=i;
[5259]444 }
[5772]445 else if(setenum==FsetEnum){
446
447 if(indexing.doftype){
448 count=0;
449 count2=0;
450 for(i=0;i<this->indexing.gsize;i++){
[6032]451 if(indexing.doftype[i]==approximation_enum){
452 if(indexing.f_set[i]){
453 outdoflist[count]=count2;
454 count++;
455 }
456 count2++;
[5772]457 }
458 }
[6412]459 _assert_(count2);
[5772]460 }
461 else{
462
463 count=0;
464 for(i=0;i<this->indexing.gsize;i++){
465 if(indexing.f_set[i]){
466 outdoflist[count]=i;
467 count++;
468 }
469 }
470 }
471 }
472 else if(setenum==SsetEnum){
473 if(indexing.doftype){
474 count=0;
475 count2=0;
476 for(i=0;i<this->indexing.gsize;i++){
[6032]477 if(indexing.doftype[i]==approximation_enum){
478 if(indexing.s_set[i]){
479 outdoflist[count]=count2;
480 count++;
481 }
482 count2++;
[5772]483 }
484 }
[6412]485 _assert_(count2);
[5772]486 }
487 else{
488 count=0;
489 for(i=0;i<this->indexing.gsize;i++){
490 if(indexing.s_set[i]){
491 outdoflist[count]=i;
492 count++;
493 }
494 }
495 }
496 }
[8224]497 else _error_("%s%s%s"," set of enum type ",EnumToStringx(setenum)," not supported yet!");
[5259]498 }
[3446]499}
500/*}}}*/
[4546]501/*FUNCTION Node::Sid{{{1*/
[4140]502int Node::Sid(void){ return sid; }
503/*}}}*/
[4546]504/*FUNCTION Node::GetVertexId {{{1*/
[3956]505int Node::GetVertexId(void){
506
507 Vertex* vertex=NULL;
508
[4396]509 vertex=(Vertex*)hvertex->delivers();
[3956]510 return vertex->id;
511}
512/*}}}*/
[4546]513/*FUNCTION Node::GetVertexDof {{{1*/
[3417]514int Node::GetVertexDof(void){
515
516 Vertex* vertex=NULL;
517
[4396]518 vertex=(Vertex*)hvertex->delivers();
[3417]519 return vertex->dof;
520}
521/*}}}*/
[10367]522#ifdef _HAVE_DIAGNOSTIC_
523/*FUNCTION Node::GetCoordinateSystem{{{1*/
524void Node::GetCoordinateSystem(double* coord_system_out){
525
526 /*Copy coord_system*/
527 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];
528
529}
530/*}}}*/
531#endif
[4546]532/*FUNCTION Node::SetVertexDof {{{1*/
[3417]533void Node::SetVertexDof(int in_dof){
[1]534
[3417]535 Vertex* vertex=NULL;
[1]536
[4396]537 vertex=(Vertex*)hvertex->delivers();
[3417]538 vertex->dof=in_dof;
[1]539
540}
[2907]541/*}}}*/
[4546]542/*FUNCTION Node::InAnalysis{{{1*/
[4002]543bool Node::InAnalysis(int in_analysis_type){
[4118]544 if (in_analysis_type==this->analysis_type) return true;
[4002]545 else return false;
546}
[3390]547/*}}}*/
[4546]548
549/*Node numerics:*/
550/*FUNCTION Node::ApplyConstraints{{{1*/
[5772]551void Node::ApplyConstraint(int dof,double value){
[1]552
553 int index;
554
[5772]555 /*Dof should be added in the s set, describing which
[1]556 * dofs are constrained to a certain value (dirichlet boundary condition*/
557 DofInSSet(dof-1);
[5772]558 this->indexing.svalues[dof-1]=value;
[1]559}
[2907]560/*}}}*/
[9002]561/*FUNCTION Node::RelaxConstraint{{{1*/
562void Node::RelaxConstraint(int dof){
563
564 /*Dof should be added to the f-set, and taken out of the s-set:*/
565 DofInFSet(dof-1);
566 this->indexing.svalues[dof-1]=NAN;
567}
568/*}}}*/
[4546]569/*FUNCTION Node::CreateVecSets {{{1*/
[5057]570void Node::CreateVecSets(Vec pv_g,Vec pv_f,Vec pv_s){
[1]571
572 double gvalue=1.0; //all nodes are in the g set;
573 double value;
574
575 int i;
576
[5772]577 for(i=0;i<this->indexing.gsize;i++){
[1]578
579 /*g set: */
[5772]580 VecSetValues(pv_g,1,&indexing.gdoflist[i],&gvalue,INSERT_VALUES);
[1]581
582 /*f set: */
[3417]583 value=(double)this->indexing.f_set[i];
[5772]584 VecSetValues(pv_f,1,&indexing.gdoflist[i],&value,INSERT_VALUES);
[1]585
586 /*s set: */
[3417]587 value=(double)this->indexing.s_set[i];
[5772]588 VecSetValues(pv_s,1,&indexing.gdoflist[i],&value,INSERT_VALUES);
[1]589
590 }
591
592
593}
[2907]594/*}}}*/
[5772]595/*FUNCTION Node::CreateNodalConstraints{{{1*/
[11684]596void Node::CreateNodalConstraints(Vector* ys){
[5772]597
598 int i;
599 double* values=NULL;
600 int count;
601
602 /*Recover values for s set and plug them in constraints vector: */
603 if(this->indexing.ssize){
604 values=(double*)xmalloc(this->indexing.ssize*sizeof(double));
605 count=0;
606 for(i=0;i<this->indexing.gsize;i++){
[5792]607 if(this->indexing.s_set[i]){
608 values[count]=this->indexing.svalues[i];
[9285]609 _assert_(!isnan(values[count]));
[5792]610 count++;
611 }
[5772]612 }
[5774]613
[5772]614 /*Add values into constraint vector: */
[11684]615 ys->SetValues(this->indexing.ssize,this->indexing.sdoflist,values,INSERT_VALUES);
[5772]616 }
617
618 /*Free ressources:*/
619 xfree((void**)&values);
620
621
622}
623/*}}}*/
[4546]624/*FUNCTION Node::DofInSSet {{{1*/
[2907]625void Node::DofInSSet(int dof){
[95]626
[2907]627 /*Put dof for this node into the s set (ie, this dof will be constrained
628 * to a fixed value during computations. */
[95]629
[3417]630 this->indexing.f_set[dof]=0; //n splits into f (for which we solve) and s (single point constraints)
631 this->indexing.s_set[dof]=1;
[95]632}
[2907]633/*}}}*/
[9002]634/*FUNCTION Node::DofInFSet {{{1*/
635void Node::DofInFSet(int dof){
636
637 /*Put dof for this node into the f set (ie, this dof will NOT be constrained
638 * to a fixed value during computations. */
639
640 this->indexing.f_set[dof]=1;
641 this->indexing.s_set[dof]=0;
642}
643/*}}}*/
[4546]644/*FUNCTION Node::FreezeDof{{{1*/
[2907]645void Node::FreezeDof(int dof){
646
647 DofInSSet(dof-1); //with 0 displacement for this dof.
648
649}
650/*}}}*/
[5557]651/*FUNCTION Node::GetApproximation {{{1*/
652int Node::GetApproximation(){
653
654 int approximation;
655
656 /*recover parameters: */
[10135]657 inputs->GetInputValue(&approximation,ApproximationEnum);
[5557]658
659 return approximation;
660}
661/*}}}*/
[4546]662/*FUNCTION Node::GetConnectivity {{{1*/
[3947]663int Node::GetConnectivity(){
664
[11001]665 Vertex* vertex=NULL;
666 vertex=(Vertex*)hvertex->delivers();
667 return vertex->connectivity;
[3947]668}
669/*}}}*/
[4546]670/*FUNCTION Node::GetNumberOfDofs{{{1*/
[5772]671int Node::GetNumberOfDofs(int approximation_enum,int setenum){
672
673 /*Get number of degrees of freedom in a node, for a certain set (g,f or s-set)
674 *and for a certain approximation type: */
[2907]675
[5259]676 int i;
677 int numdofs=0;
[2907]678
[5772]679 if(approximation_enum==NoneApproximationEnum){
680 if (setenum==GsetEnum) numdofs=this->indexing.gsize;
681 else if (setenum==FsetEnum) numdofs=this->indexing.fsize;
682 else if (setenum==SsetEnum) numdofs=this->indexing.ssize;
[8224]683 else _error_("%s%s%s"," set of enum type ",EnumToStringx(setenum)," not supported yet!");
[5772]684 }
685 else{
686 if(setenum==GsetEnum){
687 if(this->indexing.doftype){
688 numdofs=0;
689 for(i=0;i<this->indexing.gsize;i++){
690 if(this->indexing.doftype[i]==approximation_enum) numdofs++;
691 }
692 }
693 else numdofs=this->indexing.gsize;
[5259]694 }
[5772]695 else if (setenum==FsetEnum){
696 if(this->indexing.doftype){
697 numdofs=0;
698 for(i=0;i<this->indexing.gsize;i++){
699 if((this->indexing.doftype[i]==approximation_enum) && (this->indexing.f_set[i])) numdofs++;
700 }
701 }
702 else numdofs=this->indexing.fsize;
703 }
704 else if (setenum==SsetEnum){
705 if(this->indexing.doftype){
706 numdofs=0;
707 for(i=0;i<this->indexing.gsize;i++){
708 if((this->indexing.doftype[i]==approximation_enum) && (this->indexing.s_set[i])) numdofs++;
709 }
710 }
711 else numdofs=this->indexing.ssize;
712 }
[8224]713 else _error_("%s%s%s"," set of enum type ",EnumToStringx(setenum)," not supported yet!");
[5259]714 }
715 return numdofs;
[2907]716}
717/*}}}*/
[4546]718/*FUNCTION Node::GetSigma {{{1*/
[3417]719double Node::GetSigma(){
720 Vertex* vertex=NULL;
721
[4396]722 vertex=(Vertex*)hvertex->delivers();
[3417]723 return vertex->sigma;
724}
[2907]725/*}}}*/
[4546]726/*FUNCTION Node::GetX {{{1*/
[3417]727double Node::GetX(){
728 Vertex* vertex=NULL;
729
[4396]730 vertex=(Vertex*)hvertex->delivers();
[3417]731 return vertex->x;
732}
[2907]733/*}}}*/
[4546]734/*FUNCTION Node::GetY {{{1*/
[3417]735double Node::GetY(){
736 Vertex* vertex=NULL;
737
[4396]738 vertex=(Vertex*)hvertex->delivers();
[3417]739 return vertex->y;
740}
[2907]741/*}}}*/
[4546]742/*FUNCTION Node::GetZ {{{1*/
[3417]743double Node::GetZ(){
744 Vertex* vertex=NULL;
745
[4396]746 vertex=(Vertex*)hvertex->delivers();
[3417]747 return vertex->z;
748}
[2907]749/*}}}*/
[4546]750/*FUNCTION Node::IsClone {{{1*/
[2907]751int Node::IsClone(){
752
[3417]753 return indexing.clone;
[2907]754
755}
756/*}}}*/
[4546]757/*FUNCTION Node::IsOnBed {{{1*/
[2907]758int Node::IsOnBed(){
[3632]759
760 bool onbed;
761
762 /*recover parameters: */
[10135]763 inputs->GetInputValue(&onbed,MeshVertexonbedEnum);
[3632]764
765 return onbed;
[2907]766}
767/*}}}*/
[10143]768/*FUNCTION Node::IsGrounded {{{1*/
769int Node::IsGrounded(){
[3632]770
771 bool onsheet;
772
773 /*recover parameters: */
[10135]774 inputs->GetInputValue(&onsheet,MaskVertexongroundediceEnum);
[3632]775
776 return onsheet;
[2907]777}
778/*}}}*/
[10143]779/*FUNCTION Node::IsFloating {{{1*/
780int Node::IsFloating(){
[3632]781
782 bool onshelf;
783
784 /*recover parameters: */
[10135]785 inputs->GetInputValue(&onshelf,MaskVertexonfloatingiceEnum);
[3632]786
787 return onshelf;
[2907]788}
789/*}}}*/
[4546]790/*FUNCTION Node::IsOnSurface {{{1*/
[2907]791int Node::IsOnSurface(){
[3632]792
793 bool onsurface;
794
795 /*recover parameters: */
[10135]796 inputs->GetInputValue(&onsurface,MeshVertexonsurfaceEnum);
[3632]797
798 return onsurface;
[2907]799}
800/*}}}*/
[4546]801/*FUNCTION Node::InputUpdateFromVector(double* vector, int name, int type){{{1*/
[4091]802void Node::InputUpdateFromVector(double* vector, int name, int type){
[3858]803
804 /*Nothing updated yet*/
805}
806/*}}}*/
[4546]807/*FUNCTION Node::InputUpdateFromVector(int* vector, int name, int type){{{1*/
[4091]808void Node::InputUpdateFromVector(int* vector, int name, int type){
[3858]809
810 /*Nothing updated yet*/
811}
812/*}}}*/
[4546]813/*FUNCTION Node::InputUpdateFromVector(bool* vector, int name, int type){{{1*/
[4091]814void Node::InputUpdateFromVector(bool* vector, int name, int type){
[3858]815
816 /*Nothing updated yet*/
817}
818/*}}}*/
[5311]819/*FUNCTION Node::InputUpdateFromVectorDakota(double* vector, int name, int type){{{1*/
820void Node::InputUpdateFromVectorDakota(double* vector, int name, int type){
821
822 /*Nothing updated yet*/
823}
824/*}}}*/
[10576]825/*FUNCTION Node::InputUpdateFromMatrixDakota(double* matrix, int nrows, int ncols, int name, int type){{{1*/
826void Node::InputUpdateFromMatrixDakota(double* matrix, int nrows, int ncols, int name, int type){
827
828 /*Nothing updated yet*/
829}
830/*}}}*/
[5311]831/*FUNCTION Node::InputUpdateFromVectorDakota(int* vector, int name, int type){{{1*/
832void Node::InputUpdateFromVectorDakota(int* vector, int name, int type){
833
834 /*Nothing updated yet*/
835}
836/*}}}*/
837/*FUNCTION Node::InputUpdateFromVectorDakota(bool* vector, int name, int type){{{1*/
838void Node::InputUpdateFromVectorDakota(bool* vector, int name, int type){
839
840 /*Nothing updated yet*/
841}
842/*}}}*/
[4546]843/*FUNCTION Node::InputUpdateFromConstant(double constant, int name){{{1*/
[4079]844void Node::InputUpdateFromConstant(double constant, int name){
[3858]845
846 /*Nothing updated yet*/
847}
848/*}}}*/
[4546]849/*FUNCTION Node::InputUpdateFromConstant(int constant, int name){{{1*/
[4079]850void Node::InputUpdateFromConstant(int constant, int name){
[3858]851
852 /*Nothing updated yet*/
[3834]853}
[3463]854/*}}}*/
[4546]855/*FUNCTION Node::InputUpdateFromConstant(bool constant, int name){{{1*/
[4079]856void Node::InputUpdateFromConstant(bool constant, int name){
[3858]857
858 /*Nothing updated yet*/
859}
[3834]860/*}}}*/
[8800]861/*FUNCTION Node::UpdateSpcs {{{1*/
862void Node::UpdateSpcs(double* ys){
[4546]863
[8800]864 int count=0;
865 int i;
866
867 count=0;
868 for(i=0;i<this->indexing.gsize;i++){
869 if(this->indexing.s_set[i]){
870 this->indexing.svalues[i]=ys[this->indexing.sdoflist[count]];
871 count++;
872 }
873 }
874}
875/*}}}*/
876/*FUNCTION Node::VecMerge {{{1*/
[11684]877void Node::VecMerge(Vector* ug, double* vector_serial,int setenum){
[8800]878
879 double* values=NULL;
880 int* indices=NULL;
881 int count=0;
882 int i;
883
884 if(setenum==FsetEnum){
885 if(this->indexing.fsize){
886 indices=(int*)xmalloc(this->indexing.fsize*sizeof(int));
887 values=(double*)xmalloc(this->indexing.fsize*sizeof(double));
888
889 for(i=0;i<this->indexing.gsize;i++){
890 if(this->indexing.f_set[i]){
[8813]891 _assert_(vector_serial);
[8800]892 values[count]=vector_serial[this->indexing.fdoflist[count]];
893 indices[count]=this->indexing.gdoflist[i];
894 count++;
895 }
896 }
897
898 /*Add values into ug: */
[11684]899 ug->SetValues(this->indexing.fsize,indices,values,INSERT_VALUES);
[8800]900 }
901 }
902 else if(setenum==SsetEnum){
903 if(this->indexing.ssize){
904 indices=(int*)xmalloc(this->indexing.ssize*sizeof(int));
905 values=(double*)xmalloc(this->indexing.ssize*sizeof(double));
906
907 for(i=0;i<this->indexing.gsize;i++){
908 if(this->indexing.s_set[i]){
[8813]909 _assert_(vector_serial);
[8800]910 values[count]=vector_serial[this->indexing.sdoflist[count]];
911 indices[count]=this->indexing.gdoflist[i];
912 count++;
913 }
914 }
915
916 /*Add values into ug: */
[11684]917 ug->SetValues(this->indexing.ssize,indices,values,INSERT_VALUES);
[8800]918 }
919 }
920 else _error_("VecMerge can only merge from the s or f-set onto the g-set!");
921
922 /*Free ressources:*/
923 xfree((void**)&values);
924 xfree((void**)&indices);
925}
926/*}}}*/
927/*FUNCTION Node::VecReduce {{{1*/
[11684]928void Node::VecReduce(Vector* vector, double* ug_serial,int setenum){
[8800]929
930 double* values=NULL;
931 int count=0;
932 int i;
933
934 if(setenum==FsetEnum){
935 if(this->indexing.fsize){
936 values=(double*)xmalloc(this->indexing.fsize*sizeof(double));
937
938 for(i=0;i<this->indexing.gsize;i++){
939 if(this->indexing.f_set[i]){
[8813]940 _assert_(ug_serial);
[8827]941 values[count]=ug_serial[this->indexing.gdoflist[i]];
[8800]942 count++;
943 }
944 }
945
946 /*Add values into ug: */
[11684]947 vector->SetValues(this->indexing.fsize,this->indexing.fdoflist,values,INSERT_VALUES);
[8800]948 }
949 }
950 else if(setenum==SsetEnum){
951 if(this->indexing.ssize){
952 values=(double*)xmalloc(this->indexing.ssize*sizeof(double));
953
954 for(i=0;i<this->indexing.gsize;i++){
955 if(this->indexing.s_set[i]){
[8813]956 _assert_(ug_serial);
[8827]957 values[count]=ug_serial[this->indexing.gdoflist[i]];
[8800]958 count++;
959 }
960 }
961
962 /*Add values into ug: */
[11684]963 vector->SetValues(this->indexing.ssize,this->indexing.sdoflist,values,INSERT_VALUES);
[8800]964 }
965 }
966 else _error_("VecReduce can only merge from the s or f-set onto the g-set!");
967
968 /*Free ressources:*/
969 xfree((void**)&values);
970}
971/*}}}*/
972
[4546]973/* DofObject routines:*/
974/*FUNCTION Node::DistributeDofs{{{1*/
[5772]975void Node::DistributeDofs(int* pdofcount,int setenum){
[3463]976
977 int i;
[2907]978 extern int my_rank;
[3463]979 int dofcount;
[2907]980
[3463]981 dofcount=*pdofcount;
[5774]982
983 /*Initialize: */
984 if(setenum==FsetEnum) this->indexing.InitSet(setenum);
985 if(setenum==SsetEnum) this->indexing.InitSet(setenum);
[3463]986
[5774]987
988 /*For clone nodfs, don't distribute dofs, we will get them from another cpu in UpdateCloneDofs!*/
[3463]989 if(indexing.clone){
990 return;
[2907]991 }
[3463]992
[5772]993 /*This node should distribute dofs for setenum set (eg, f_set or s_set), go ahead: */
994
995 if(setenum==GsetEnum){
996 for(i=0;i<this->indexing.gsize;i++){
997 indexing.gdoflist[i]=dofcount+i;
998 }
999 dofcount+=this->indexing.gsize;
[2907]1000 }
[5772]1001 else if(setenum==FsetEnum){
1002 for(i=0;i<this->indexing.fsize;i++){
1003 indexing.fdoflist[i]=dofcount+i;
1004 }
1005 dofcount+=this->indexing.fsize;
1006 }
1007 else if(setenum==SsetEnum){
1008 for(i=0;i<this->indexing.ssize;i++){
1009 indexing.sdoflist[i]=dofcount+i;
1010 }
1011 dofcount+=this->indexing.ssize;
1012 }
[8224]1013 else _error_("%s%s%s"," set of enum type ",EnumToStringx(setenum)," not supported yet!");
[2907]1014
[5772]1015
[3463]1016 /*Assign output pointers: */
1017 *pdofcount=dofcount;
1018
[2907]1019}
1020/*}}}*/
[5772]1021/*FUNCTION Node::Off_setDofs{{{1*/
1022void Node::OffsetDofs(int dofcount,int setenum){
[3463]1023
1024 int i;
1025 extern int my_rank;
1026
1027 if(indexing.clone){
[5772]1028 /*This node is a clone, don't off_set the dofs!: */
[3463]1029 return;
1030 }
[2907]1031
[5772]1032 /*This node should off_set the dofs, go ahead: */
1033 if(setenum==GsetEnum){
1034 for(i=0;i<this->indexing.gsize;i++) indexing.gdoflist[i]+=dofcount;
[3463]1035 }
[5772]1036 else if(setenum==FsetEnum){
1037 for(i=0;i<this->indexing.fsize;i++) indexing.fdoflist[i]+=dofcount;
1038 }
1039 else if(setenum==SsetEnum){
1040 for(i=0;i<this->indexing.ssize;i++) indexing.sdoflist[i]+=dofcount;
1041 }
[8224]1042 else _error_("%s%s%s"," set of enum type ",EnumToStringx(setenum)," not supported yet!");
[3463]1043}
1044/*}}}*/
[4546]1045/*FUNCTION Node::ShowTrueDofs{{{1*/
[5772]1046void Node::ShowTrueDofs(int* truedofs, int ncols,int setenum){
[3463]1047
[2907]1048 int j;
1049 extern int my_rank;
1050
[3463]1051 /*Are we a clone? : */
[3417]1052 if(indexing.clone)return;
[2907]1053
[3463]1054 /*Ok, we are not a clone, just plug our dofs into truedofs: */
[5772]1055 if(setenum==GsetEnum)for(j=0;j<this->indexing.gsize;j++) *(truedofs+ncols*sid+j)=indexing.gdoflist[j];
1056 else if(setenum==FsetEnum)for(j=0;j<this->indexing.fsize;j++) *(truedofs+ncols*sid+j)=indexing.fdoflist[j];
1057 else if(setenum==SsetEnum)for(j=0;j<this->indexing.ssize;j++) *(truedofs+ncols*sid+j)=indexing.sdoflist[j];
[8224]1058 else _error_("%s%s%s"," set of enum type ",EnumToStringx(setenum)," not supported yet!");
[5772]1059
[2907]1060}
1061/*}}}*/
[4546]1062/*FUNCTION Node::UpdateCloneDofs{{{1*/
[5772]1063void Node::UpdateCloneDofs(int* alltruedofs,int ncols,int setenum){
[2907]1064
1065 int j;
1066 extern int my_rank;
1067
[3463]1068 /*If we are not a clone, don't update, we already have dofs!: */
[3417]1069 if(indexing.clone==0)return;
[2907]1070
[5114]1071
1072 /*Ok, we are a clone node, but we did not create the dofs for this node.
1073 * * Therefore, our doflist is garbage right now. Go pick it up in the alltruedofs: */
[5772]1074 if(setenum==GsetEnum)for(j=0;j<this->indexing.gsize;j++) indexing.gdoflist[j]=*(alltruedofs+ncols*sid+j);
1075 else if(setenum==FsetEnum)for(j=0;j<this->indexing.fsize;j++) indexing.fdoflist[j]=*(alltruedofs+ncols*sid+j);
1076 else if(setenum==SsetEnum)for(j=0;j<this->indexing.ssize;j++) indexing.sdoflist[j]=*(alltruedofs+ncols*sid+j);
[8224]1077 else _error_("%s%s%s"," set of enum type ",EnumToStringx(setenum)," not supported yet!");
[5114]1078
[2907]1079}
1080/*}}}*/
[4546]1081/*FUNCTION Node::SetClone {{{1*/
[3463]1082void Node::SetClone(int* minranks){
1083
[2907]1084 extern int my_rank;
1085
[4180]1086 if (minranks[sid]==my_rank){
[3463]1087 indexing.clone=0;
[2907]1088 }
[3463]1089 else{
1090 /*!there is a cpu with lower rank that has the same node,
1091 therefore, I am a clone*/
1092 indexing.clone=1;
1093 }
[2907]1094
1095}
1096/*}}}*/
Note: See TracBrowser for help on using the repository browser.