/*!\file TriaInput.c * \brief: implementation of the TriaInput object */ #ifdef HAVE_CONFIG_H #include #else #error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!" #endif #include "../classes.h" #include "../../shared/shared.h" #include "./TriaInput.h" /*TriaInput constructors and destructor*/ TriaInput::TriaInput(void){/*{{{*/ this->numberofelements_local = -1; this->numberofvertices_local = -1; this->isserved = false; this->isserved_collapsed= 0; this->M = -1; this->N = -1; this->values = NULL; this->element_values = NULL; }/*}}}*/ TriaInput::TriaInput(int nbe_in,int nbv_in,int interp_in){/*{{{*/ _assert_(nbe_in>0); _assert_(nbe_in<1e11); _assert_(nbv_in>0); _assert_(nbv_in<1e11); this->numberofelements_local = nbe_in; this->numberofvertices_local = nbv_in; this->isserved = false; this->isserved_collapsed = 0; /*Reset takes care of the rest*/ this->Reset(interp_in); }/*}}}*/ TriaInput::~TriaInput(){/*{{{*/ if(this->element_values) xDelete(this->element_values); if(this->values) xDelete(this->values); } /*}}}*/ void TriaInput::Reset(int interp_in){/*{{{*/ /*Clean up*/ if(this->values) xDelete(this->values); if(this->element_values) xDelete(this->element_values); /*Set interpolation*/ this->interpolation = interp_in; /*Create Sizes*/ if(this->interpolation==P1Enum){ this->M = this->numberofvertices_local; this->N = 1; } else{ this->M = this->numberofelements_local; this->N = TriaRef::NumberofNodes(interp_in); } /*Allocate Pointers*/ this->values = xNewZeroInit(this->M*this->N); this->element_values = xNewZeroInit(TriaRef::NumberofNodes(interp_in)); }/*}}}*/ /*Object virtual functions definitions:*/ Input* TriaInput::copy() {/*{{{*/ TriaInput* output = new TriaInput(this->numberofelements_local,this->numberofvertices_local,this->interpolation); xMemCpy(output->values,this->values,this->M*this->N); xMemCpy(output->element_values,this->element_values,TriaRef::NumberofNodes(this->interpolation)); return output; } /*}}}*/ void TriaInput::DeepEcho(void){/*{{{*/ _printf_("TriaInput Echo:\n"); _printf_(" interpolation: "<interpolation)<<"\n"); _printf_(" Size: "<element_values[i]); _printf_("] ("<interpolation)<<")\n"); } printarray(this->values,this->M,this->N); //_printf_(setw(15)<<" TriaInput "<enum_type)<<" "<<(value?"true":"false") << "\n"); } /*}}}*/ void TriaInput::Echo(void){/*{{{*/ _printf_("TriaInput Echo:\n"); _printf_(" interpolation: "<interpolation)<<"\n"); _printf_(" Size: "<interpolation);i++) _printf_(" "<element_values[i]); _printf_("] ("<interpolation)<<")\n"); } } /*}}}*/ int TriaInput::Id(void){/*{{{*/ return -1; }/*}}}*/ void TriaInput::Marshall(MarshallHandle* marshallhandle){ /*{{{*/ int object_enum = TriaInputEnum; marshallhandle->call(object_enum); marshallhandle->call(this->numberofelements_local); marshallhandle->call(this->numberofvertices_local); marshallhandle->call(this->interpolation); marshallhandle->call(this->M); marshallhandle->call(this->N); this->isserved = false; this->isserved_collapsed = 0; if(this->M*this->N){ marshallhandle->call(this->values,this->M*this->N); } else this->values = NULL; if(marshallhandle->OperationNumber() == MARSHALLING_LOAD){ this->element_values = xNewZeroInit(TriaRef::NumberofNodes(this->interpolation)); } } /*}}}*/ int TriaInput::ObjectEnum(void){/*{{{*/ return TriaInputEnum; } /*}}}*/ /*TriaInput management*/ void TriaInput::SetInput(int interp_in,int row,IssmDouble value_in){/*{{{*/ _assert_(this); _assert_(row>=0); _assert_(rowM); _assert_(this->N==1); this->values[row] = value_in; this->isserved = false; } /*}}}*/ void TriaInput::SetInput(int interp_in,int numindices,int* indices,IssmDouble* values_in){/*{{{*/ _assert_(this); if(interp_in==P1Enum && this->interpolation==P1Enum){ _assert_(this->N==1); for(int i=0;i=0); _assert_(rowM); this->values[row] = values_in[i]; } } else if(interp_in==P0Enum && this->interpolation==P0Enum){ _assert_(this->N==1); for(int i=0;i=0); _assert_(rowM); this->values[row] = values_in[i]; } } else if(this->interpolation!=P1Enum && interp_in==P1Enum){ this->Reset(interp_in); for(int i=0;i=0); _assert_(rowM); this->values[row] = values_in[i]; } } else{ _error_("Cannot convert "<interpolation)<<" to "<isserved = false; } /*}}}*/ void TriaInput::SetInput(int interp_in,int row,int numindices,IssmDouble* values_in){/*{{{*/ _assert_(this); if(interp_in==this->interpolation){ _assert_(this->N==numindices); } else{ this->Reset(interp_in); _assert_(this->N==numindices); } for(int i=0;ivalues[row*this->N+i] = values_in[i]; this->isserved = false; } /*}}}*/ void TriaInput::Serve(int numindices,int* indices){/*{{{*/ _assert_(this); _assert_(this->N==1); for(int i=0;i=0); _assert_(rowM); this->element_values[i] = this->values[row]; } /*Set input as served*/ this->isserved = true; this->isserved_collapsed = 0; } /*}}}*/ void TriaInput::Serve(int row,int numindices){/*{{{*/ _assert_(this); _assert_(this->N==numindices); _assert_(rowM); _assert_(row>=0); for(int i=0;ielement_values[i] = this->values[row*this->N+i]; } /*Set input as served*/ this->isserved = true; this->isserved_collapsed = 0; } /*}}}*/ void TriaInput::ServeCollapsed(int row,int id1,int id2){/*{{{*/ _assert_(this); _assert_(this->N>=3); _assert_(rowM); _assert_(row>=0); _assert_(id1>=0 && id1<3); _assert_(id2>=0 && id2<3); this->element_values[0] = this->values[row*this->N+id1]; this->element_values[1] = this->values[row*this->N+id2]; /*Set input as served*/ this->isserved = true; this->isserved_collapsed = 1; }/*}}}*/ void TriaInput::SetServeCollapsed(bool status){/*{{{*/ this->isserved_collapsed = 1; }/*}}}*/ int TriaInput::GetInterpolation(){/*{{{*/ return this->interpolation; }/*}}}*/ void TriaInput::GetInputAverage(IssmDouble* pvalue){/*{{{*/ _assert_(this); _assert_(this->isserved); int numnodes = this->NumberofNodes(this->interpolation); if(this->isserved_collapsed) numnodes = 2; IssmDouble numnodesd = reCast(numnodes); IssmDouble value = 0.; for(int i=0;ielement_values[i]; value = value/numnodesd; *pvalue=value; }/*}}}*/ IssmDouble TriaInput::GetInputMin(void){/*{{{*/ _assert_(this); _assert_(this->isserved); int numnodes = this->NumberofNodes(this->interpolation); if(this->isserved_collapsed) numnodes = 2; IssmDouble min=this->element_values[0]; for(int i=1;ielement_values[i]element_values[i]; } return min; }/*}}}*/ IssmDouble TriaInput::GetInputMax(void){/*{{{*/ _assert_(this); _assert_(this->isserved); int numnodes = this->NumberofNodes(this->interpolation); if(this->isserved_collapsed) numnodes = 2; IssmDouble max=this->element_values[0]; for(int i=1;ielement_values[i]>max) max=this->element_values[i]; } return max; }/*}}}*/ IssmDouble TriaInput::GetInputMaxAbs(void){/*{{{*/ _assert_(this); _assert_(this->isserved); int numnodes = this->NumberofNodes(this->interpolation); if(this->isserved_collapsed) numnodes = 2; IssmDouble maxabs=fabs(this->element_values[0]); for(int i=1;ielement_values[i])>maxabs) maxabs=fabs(this->element_values[i]); } return maxabs; }/*}}}*/ void TriaInput::GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, Gauss* gauss){/*{{{*/ _assert_(this); _assert_(this->isserved); if(this->isserved_collapsed){ _assert_(gauss->Enum()==GaussSegEnum); if(this->interpolation==P0Enum){ derivativevalues[0] = 0.; } else{ SegRef temp; temp.GetInputDerivativeValue(derivativevalues,this->element_values,xyz_list,(GaussSeg*)gauss,P1Enum); } } else{ _assert_(gauss->Enum()==GaussTriaEnum); TriaRef::GetInputDerivativeValue(derivativevalues,this->element_values,xyz_list,(GaussTria*)gauss,this->interpolation); } }/*}}}*/ void TriaInput::GetInputValue(IssmDouble* pvalue,Gauss* gauss){/*{{{*/ _assert_(this); _assert_(this->isserved); if(this->isserved_collapsed){ _assert_(gauss->Enum()==GaussSegEnum); if(this->interpolation==P0Enum){ *pvalue = this->element_values[0]; } else{ SegRef temp; temp.GetInputValue(pvalue,this->element_values,(GaussSeg*)gauss,P1Enum); } } else{ _assert_(gauss->Enum()==GaussTriaEnum); TriaRef::GetInputValue(pvalue,this->element_values,(GaussTria*)gauss,this->interpolation); } }/*}}}*/ int TriaInput::GetResultArraySize(void){/*{{{*/ return 1; } /*}}}*/ int TriaInput::GetResultInterpolation(void){/*{{{*/ if(this->interpolation==P0Enum || this->interpolation==P0DGEnum){ return P0Enum; } return P1Enum; }/*}}}*/ int TriaInput::GetResultNumberOfNodes(void){/*{{{*/ return TriaRef::NumberofNodes(this->interpolation); } /*}}}*/ void TriaInput::Scale(IssmDouble alpha){/*{{{*/ for(int i=0;iM*this->N;i++) this->values[i] = alpha*this->values[i]; for(int i=0;iinterpolation);i++) this->element_values[i] = alpha*this->element_values[i]; } /*}}}*/ void TriaInput::Pow(IssmDouble alpha){/*{{{*/ for(int i=0;iM*this->N;i++) this->values[i] = pow(this->values[i],alpha); for(int i=0;iinterpolation);i++) this->element_values[i] = pow(this->element_values[i],alpha); } /*}}}*/ void TriaInput::AXPY(Input* xinput,IssmDouble alpha){/*{{{*/ /*xinput is of the same type, so cast it: */ if(xinput->ObjectEnum()!=TriaInputEnum) _error_("Operation not permitted because xinput is of type " << EnumToStringx(xinput->ObjectEnum())); TriaInput* xtriainput=xDynamicCast(xinput); if(xtriainput->GetInterpolation()!=this->interpolation) _error_("Operation not permitted because xinput is of type " << EnumToStringx(xinput->ObjectEnum())); /*Carry out the AXPY operation depending on type:*/ for(int i=0;iM*this->N;i++) this->values[i] = alpha*xtriainput->values[i] + this->values[i]; for(int i=0;iinterpolation);i++) this->element_values[i] = alpha*xtriainput->element_values[i] + this->element_values[i]; } /*}}}*/ void TriaInput::Shift(IssmDouble alpha){/*{{{*/ /*Carry out the shift operation:*/ for(int i=0;iM*this->N;i++) this->values[i] +=alpha; for(int i=0;iinterpolation);i++) this->element_values[i] += alpha; } /*}}}*/ void TriaInput::PointWiseMult(Input* xinput){/*{{{*/ /*xinput is of the same type, so cast it: */ if(xinput->ObjectEnum()!=TriaInputEnum) _error_("Operation not permitted because xinput is of type " << EnumToStringx(xinput->ObjectEnum())); TriaInput* xtriainput=xDynamicCast(xinput); if(xtriainput->GetInterpolation()!=this->interpolation) _error_("Operation not permitted because xinput is of type " << EnumToStringx(xinput->ObjectEnum())); /* we need to check that the vector sizes are identical*/ if(xtriainput->M!=this->M||xtriainput->N!=this->N) _error_("Operation not permitted because the inputs have different sizes"); /*Carry out the AXPY operation depending on type:*/ for(int i=0;iM*this->N;i++) this->values[i] = xtriainput->values[i] * this->values[i]; for(int i=0;iinterpolation);i++) this->element_values[i] = xtriainput->element_values[i] * this->element_values[i]; } /*}}}*/ /*Object functions*/