/*!\file Penpair.c * \brief: implementation of the Penpair object */ /*Headers*/ /*{{{1*/ #ifdef HAVE_CONFIG_H #include #else #error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!" #endif #include #include #include "../objects.h" #include "../../EnumDefinitions/EnumDefinitions.h" #include "../../include/include.h" #include "../../shared/shared.h" /*}}}*/ /*Element macros*/ #define NUMVERTICES 2 /*Penpair constructors and destructor*/ /*FUNCTION Penpair::constructor {{{1*/ Penpair::Penpair(){ this->hnodes=NULL; this->nodes=NULL; this->parameters=NULL; return; } /*}}}1*/ /*FUNCTION Penpair::creation {{{1*/ Penpair::Penpair(int penpair_id, int* penpair_node_ids,int in_analysis_type){ this->id=penpair_id; this->analysis_type=in_analysis_type; this->hnodes=new Hook(penpair_node_ids,2); this->parameters=NULL; this->nodes=NULL; return; } /*}}}1*/ /*FUNCTION Penpair::destructor {{{1*/ Penpair::~Penpair(){ delete hnodes; return; } /*}}}1*/ /*Object virtual functions definitions:*/ /*FUNCTION Penpair::Echo {{{1*/ void Penpair::Echo(void){ int i; printf("Penpair:\n"); printf(" id: %i\n",id); printf(" analysis_type: %s\n",EnumToStringx(analysis_type)); hnodes->Echo(); return; } /*}}}1*/ /*FUNCTION Penpair::DeepEcho {{{1*/ void Penpair::DeepEcho(void){ printf("Penpair:\n"); printf(" id: %i\n",id); printf(" analysis_type: %s\n",EnumToStringx(analysis_type)); hnodes->DeepEcho(); return; } /*}}}1*/ /*FUNCTION Penpair::Id {{{1*/ int Penpair::Id(void){ return id; } /*}}}1*/ /*FUNCTION Penpair::MyRank {{{1*/ int Penpair::MyRank(void){ extern int my_rank; return my_rank; } /*}}}1*/ #ifdef _SERIAL_ /*FUNCTION Penpair::Marshall {{{1*/ void Penpair::Marshall(char** pmarshalled_dataset){ char* marshalled_dataset=NULL; int enum_type=0; /*recover marshalled_dataset: */ marshalled_dataset=*pmarshalled_dataset; /*get enum type of Penpair: */ enum_type=PenpairEnum; /*marshall enum: */ memcpy(marshalled_dataset,&enum_type,sizeof(enum_type));marshalled_dataset+=sizeof(enum_type); /*marshall Penpair data: */ memcpy(marshalled_dataset,&id,sizeof(id));marshalled_dataset+=sizeof(id); memcpy(marshalled_dataset,&analysis_type,sizeof(analysis_type));marshalled_dataset+=sizeof(analysis_type); /*Marshall hooks*/ hnodes->Marshall(&marshalled_dataset); *pmarshalled_dataset=marshalled_dataset; return; } /*}}}1*/ /*FUNCTION Penpair::MarshallSize {{{1*/ int Penpair::MarshallSize(){ return sizeof(id)+ +sizeof(analysis_type) +hnodes->MarshallSize() +sizeof(int); //sizeof(int) for enum type } /*}}}1*/ /*FUNCTION Penpair::Demarshall {{{1*/ void Penpair::Demarshall(char** pmarshalled_dataset){ int i; char* marshalled_dataset=NULL; /*recover marshalled_dataset: */ marshalled_dataset=*pmarshalled_dataset; /*this time, no need to get enum type, the pointer directly points to the beginning of the *object data (thanks to DataSet::Demarshall):*/ memcpy(&id,marshalled_dataset,sizeof(id));marshalled_dataset+=sizeof(id); memcpy(&analysis_type,marshalled_dataset,sizeof(analysis_type));marshalled_dataset+=sizeof(analysis_type); /*demarshall hooks: */ hnodes=new Hook(); hnodes->Demarshall(&marshalled_dataset); /*pointers are garbabe, until configuration is carried out: */ nodes=NULL; parameters=NULL; /*return: */ *pmarshalled_dataset=marshalled_dataset; return; } /*}}}1*/ #endif /*FUNCTION Penpair::ObjectEnum{{{1*/ int Penpair::ObjectEnum(void){ return PenpairEnum; } /*}}}1*/ /*FUNCTION Penpair::copy {{{1*/ Object* Penpair::copy() { Penpair* penpair=NULL; penpair=new Penpair(); /*copy fields: */ penpair->id=this->id; penpair->analysis_type=this->analysis_type; /*now deal with hooks and objects: */ penpair->hnodes=(Hook*)this->hnodes->copy(); penpair->nodes =(Node**)penpair->hnodes->deliverp(); /*point parameters: */ penpair->parameters=this->parameters; return penpair; } /*}}}*/ /*Load virtual functions definitions:*/ /*FUNCTION Penpair::Configure {{{1*/ void Penpair::Configure(Elements* elementsin,Loads* loadsin,Nodes* nodesin,Vertices* verticesin,Materials* materialsin,Parameters* parametersin){ /*Take care of hooking up all objects for this element, ie links the objects in the hooks to their respective * datasets, using internal ids and offsets hidden in hooks: */ hnodes->configure(nodesin); /*Initialize hooked fields*/ this->nodes =(Node**)hnodes->deliverp(); /*point parameters to real dataset: */ this->parameters=parametersin; } /*}}}1*/ /*FUNCTION Penpair::SetCurrentConfiguration {{{1*/ void Penpair::SetCurrentConfiguration(Elements* elementsin,Loads* loadsin,Nodes* nodesin,Vertices* verticesin,Materials* materialsin,Parameters* parametersin){ } /*}}}1*/ /*FUNCTION Penpair::CreateKMatrix {{{1*/ void Penpair::CreateKMatrix(Mat Kff, Mat Kfs){ /*If you code this piece, don't forget that a penalty will be inactive if it is dealing with clone nodes*/ /*No loads applied, do nothing: */ return; } /*}}}1*/ /*FUNCTION Penpair::CreatePVector {{{1*/ void Penpair::CreatePVector(Vec pf){ /*No loads applied, do nothing: */ return; } /*}}}1*/ /*FUNCTION Penpair::CreateJacobianMatrix{{{1*/ void Penpair::CreateJacobianMatrix(Mat Jff){ this->CreateKMatrix(Jff,NULL); } /*}}}1*/ /*FUNCTION Penpair::PenaltyCreateKMatrix {{{1*/ void Penpair::PenaltyCreateKMatrix(Mat Kff, Mat Kfs,double kmax){ /*Retrieve parameters: */ ElementMatrix* Ke=NULL; int analysis_type; this->parameters->FindParam(&analysis_type,AnalysisTypeEnum); switch(analysis_type){ case DiagnosticHorizAnalysisEnum: Ke=PenaltyCreateKMatrixDiagnosticHoriz(kmax); break; case PrognosticAnalysisEnum: Ke=PenaltyCreateKMatrixPrognostic(kmax); break; default: _error_("analysis %i (%s) not supported yet",analysis_type,EnumToStringx(analysis_type)); } /*Add to global Vector*/ if(Ke){ Ke->AddToGlobal(Kff,Kfs); delete Ke; } } /*}}}1*/ /*FUNCTION Penpair::PenaltyCreatePVector {{{1*/ void Penpair::PenaltyCreatePVector(Vec pf,double kmax){ /*No loads applied, do nothing: */ return; } /*}}}1*/ /*FUNCTION Penpair::PenaltyCreateJacobianMatrix{{{1*/ void Penpair::PenaltyCreateJacobianMatrix(Mat Jff,double kmax){ this->PenaltyCreateKMatrix(Jff,NULL,kmax); } /*}}}1*/ /*FUNCTION Penpair::InAnalysis{{{1*/ bool Penpair::InAnalysis(int in_analysis_type){ if (in_analysis_type==this->analysis_type)return true; else return false; } /*}}}*/ /*Update virtual functions definitions:*/ /*FUNCTION Penpair::InputUpdateFromConstant(double constant, int name) {{{1*/ void Penpair::InputUpdateFromConstant(double constant, int name){ /*Nothing updated yet*/ } /*}}}*/ /*FUNCTION Penpair::InputUpdateFromConstant(int constant, int name) {{{1*/ void Penpair::InputUpdateFromConstant(int constant, int name){ /*Nothing updated yet*/ } /*}}}*/ /*FUNCTION Penpair::InputUpdateFromConstant(bool constant, int name) {{{1*/ void Penpair::InputUpdateFromConstant(bool constant, int name){ /*Nothing updated yet*/ } /*}}}*/ /*FUNCTION Penpair::InputUpdateFromVector(double* vector, int name, int type) {{{1*/ void Penpair::InputUpdateFromVector(double* vector, int name, int type){ /*Nothing updated yet*/ } /*}}}*/ /*FUNCTION Penpair::InputUpdateFromVector(int* vector, int name, int type) {{{1*/ void Penpair::InputUpdateFromVector(int* vector, int name, int type){ /*Nothing updated yet*/ } /*}}}*/ /*FUNCTION Penpair::InputUpdateFromVector(bool* vector, int name, int type) {{{1*/ void Penpair::InputUpdateFromVector(bool* vector, int name, int type){ /*Nothing updated yet*/ } /*}}}*/ /*Penpair management:*/ /*FUNCTION Penpair::PenaltyCreateKMatrixDiagnosticHoriz{{{1*/ ElementMatrix* Penpair::PenaltyCreateKMatrixDiagnosticHoriz(double kmax){ int approximation0=nodes[0]->GetApproximation(); int approximation1=nodes[1]->GetApproximation(); switch(approximation0){ case MacAyealApproximationEnum: switch(approximation1){ case MacAyealApproximationEnum: return PenaltyCreateKMatrixDiagnosticMacAyealPattyn(kmax); case PattynApproximationEnum: return PenaltyCreateKMatrixDiagnosticMacAyealPattyn(kmax); default: _error_("not supported yet"); } case PattynApproximationEnum: switch(approximation1){ case MacAyealApproximationEnum: return PenaltyCreateKMatrixDiagnosticMacAyealPattyn(kmax); case PattynApproximationEnum: return PenaltyCreateKMatrixDiagnosticMacAyealPattyn(kmax); default: _error_("not supported yet"); } case StokesApproximationEnum: switch(approximation1){ case StokesApproximationEnum: return PenaltyCreateKMatrixDiagnosticStokes(kmax); case NoneApproximationEnum: return PenaltyCreateKMatrixDiagnosticStokes(kmax); default: _error_("not supported yet"); } case NoneApproximationEnum: switch(approximation1){ case StokesApproximationEnum: return PenaltyCreateKMatrixDiagnosticStokes(kmax); case NoneApproximationEnum: return PenaltyCreateKMatrixDiagnosticStokes(kmax); default: _error_("not supported yet"); } default: _error_("not supported yet"); } } /*}}}1*/ /*FUNCTION Penpair::PenaltyCreateKMatrixDiagnosticMacAyealPattyn {{{1*/ ElementMatrix* Penpair::PenaltyCreateKMatrixDiagnosticMacAyealPattyn(double kmax){ const int numdof=NUMVERTICES*NDOF2; double penalty_offset; /*Initialize Element vector and return if necessary*/ ElementMatrix* Ke=new ElementMatrix(nodes,NUMVERTICES,this->parameters); /*recover parameters: */ parameters->FindParam(&penalty_offset,DiagnosticPenaltyFactorEnum); //Create elementary matrix: add penalty to Ke->values[0*numdof+0]=+kmax*pow((double)10.0,penalty_offset); Ke->values[0*numdof+2]=-kmax*pow((double)10.0,penalty_offset); Ke->values[2*numdof+0]=-kmax*pow((double)10.0,penalty_offset); Ke->values[2*numdof+2]=+kmax*pow((double)10.0,penalty_offset); Ke->values[1*numdof+1]=+kmax*pow((double)10.0,penalty_offset); Ke->values[1*numdof+3]=-kmax*pow((double)10.0,penalty_offset); Ke->values[3*numdof+1]=-kmax*pow((double)10.0,penalty_offset); Ke->values[3*numdof+3]=+kmax*pow((double)10.0,penalty_offset); /*Clean up and return*/ return Ke; } /*}}}1*/ /*FUNCTION Penpair::PenaltyCreateKMatrixDiagnosticStokes {{{1*/ ElementMatrix* Penpair::PenaltyCreateKMatrixDiagnosticStokes(double kmax){ const int numdof=NUMVERTICES*NDOF4; double penalty_offset; /*Initialize Element vector and return if necessary*/ ElementMatrix* Ke=new ElementMatrix(nodes,NUMVERTICES,this->parameters); /*recover parameters: */ parameters->FindParam(&penalty_offset,DiagnosticPenaltyFactorEnum); //Create elementary matrix: add penalty to Ke->values[0*numdof+0]=+kmax*pow((double)10.0,penalty_offset); Ke->values[0*numdof+4]=-kmax*pow((double)10.0,penalty_offset); Ke->values[4*numdof+0]=-kmax*pow((double)10.0,penalty_offset); Ke->values[4*numdof+4]=+kmax*pow((double)10.0,penalty_offset); Ke->values[1*numdof+1]=+kmax*pow((double)10.0,penalty_offset); Ke->values[1*numdof+5]=-kmax*pow((double)10.0,penalty_offset); Ke->values[5*numdof+1]=-kmax*pow((double)10.0,penalty_offset); Ke->values[5*numdof+5]=+kmax*pow((double)10.0,penalty_offset); Ke->values[2*numdof+2]=+kmax*pow((double)10.0,penalty_offset); Ke->values[2*numdof+6]=-kmax*pow((double)10.0,penalty_offset); Ke->values[6*numdof+2]=-kmax*pow((double)10.0,penalty_offset); Ke->values[6*numdof+6]=+kmax*pow((double)10.0,penalty_offset); Ke->values[3*numdof+3]=+kmax*pow((double)10.0,penalty_offset); Ke->values[3*numdof+7]=-kmax*pow((double)10.0,penalty_offset); Ke->values[7*numdof+3]=-kmax*pow((double)10.0,penalty_offset); Ke->values[7*numdof+7]=+kmax*pow((double)10.0,penalty_offset); /*Clean up and return*/ return Ke; } /*}}}1*/ /*FUNCTION Penpair::PenaltyCreateKMatrixPrognostic {{{1*/ ElementMatrix* Penpair::PenaltyCreateKMatrixPrognostic(double kmax){ const int numdof=NUMVERTICES*NDOF1; double penalty_factor; /*Initialize Element vector and return if necessary*/ ElementMatrix* Ke=new ElementMatrix(nodes,NUMVERTICES,this->parameters); /*recover parameters: */ parameters->FindParam(&penalty_factor,PrognosticPenaltyFactorEnum); //Create elementary matrix: add penalty to Ke->values[0*numdof+0]=+kmax*pow((double)10.0,penalty_factor); Ke->values[0*numdof+1]=-kmax*pow((double)10.0,penalty_factor); Ke->values[1*numdof+0]=-kmax*pow((double)10.0,penalty_factor); Ke->values[1*numdof+1]=+kmax*pow((double)10.0,penalty_factor); /*Clean up and return*/ return Ke; } /*}}}1*/