#include "./SealevelriseAnalysis.h" #include "../toolkits/toolkits.h" #include "../classes/classes.h" #include "../shared/shared.h" #include "../modules/modules.h" /*Model processing*/ void SealevelriseAnalysis::CreateConstraints(Constraints* constraints,IoModel* iomodel){/*{{{*/ /*No constraints*/ }/*}}}*/ void SealevelriseAnalysis::CreateLoads(Loads* loads, IoModel* iomodel){/*{{{*/ /*No loads*/ }/*}}}*/ void SealevelriseAnalysis::CreateNodes(Nodes* nodes,IoModel* iomodel){/*{{{*/ ::CreateNodes(nodes,iomodel,SealevelriseAnalysisEnum,P1Enum); }/*}}}*/ int SealevelriseAnalysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/ return 1; }/*}}}*/ void SealevelriseAnalysis::UpdateElements(Elements* elements,IoModel* iomodel,int analysis_counter,int analysis_type){/*{{{*/ /*Update elements: */ int counter=0; for(int i=0;inumberofelements;i++){ if(iomodel->my_elements[i]){ Element* element=(Element*)elements->GetObjectByOffset(counter); element->Update(i,iomodel,analysis_counter,analysis_type,P1Enum); counter++; } } /*Create inputs: */ iomodel->FetchDataToInput(elements,MaskIceLevelsetEnum); iomodel->FetchDataToInput(elements,MaskOceanLevelsetEnum); iomodel->FetchDataToInput(elements,MaskLandLevelsetEnum); iomodel->FetchDataToInput(elements,SealevelriseDeltathicknessEnum); }/*}}}*/ void SealevelriseAnalysis::UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum){/*{{{*/ int nl; IssmDouble* love_h=NULL; IssmDouble* love_k=NULL; bool elastic=false; IssmDouble* G_elastic = NULL; IssmDouble* G_elastic_local = NULL; int M,m,lower_row,upper_row; IssmDouble degacc=.01; int numoutputs; char** requestedoutputs = NULL; /*transition vectors: */ IssmDouble **transitions = NULL; int *transitions_M = NULL; int *transitions_N = NULL; int ntransitions; /*some constant parameters: */ parameters->AddObject(iomodel->CopyConstantObject(SealevelriseReltolEnum)); parameters->AddObject(iomodel->CopyConstantObject(SealevelriseAbstolEnum)); parameters->AddObject(iomodel->CopyConstantObject(SealevelriseMaxiterEnum)); parameters->AddObject(iomodel->CopyConstantObject(SealevelriseRigidEnum)); parameters->AddObject(iomodel->CopyConstantObject(SealevelriseElasticEnum)); parameters->AddObject(iomodel->CopyConstantObject(SealevelriseEustaticEnum)); iomodel->FetchData(&elastic,SealevelriseElasticEnum); if(elastic){ /*love numbers: */ iomodel->FetchData(&love_h,&nl,NULL,SealevelriseLoveHEnum); iomodel->FetchData(&love_k,&nl,NULL,SealevelriseLoveKEnum); /*compute elastic green function for a range of angles*/ iomodel->FetchData(°acc,SealevelriseDegaccEnum); M=reCast(180./degacc+1.); G_elastic=xNew(M); /*compute combined legendre + love number (elastic green function:*/ m=DetermineLocalSize(M,IssmComm::GetComm()); GetOwnershipBoundariesFromRange(&lower_row,&upper_row,m,IssmComm::GetComm()); G_elastic_local=xNew(m); for(int i=lower_row;i(i)*degacc * PI / 180.0; G_elastic_local[i-lower_row]= (love_k[nl-1]-love_h[nl-1])/2.0/sin(alpha/2.0); IssmDouble Pn,Pn1,Pn2; for (int n=0;n(IssmComm::GetSize()); int* displs=xNew(IssmComm::GetSize()); //recvcounts: ISSM_MPI_Allgather(&m,1,ISSM_MPI_INT,recvcounts,1,ISSM_MPI_INT,IssmComm::GetComm()); /*displs: */ ISSM_MPI_Allgather(&lower_row,1,ISSM_MPI_INT,displs,1,ISSM_MPI_INT,IssmComm::GetComm()); /*All gather:*/ ISSM_MPI_Allgatherv(G_elastic_local, m, ISSM_MPI_DOUBLE, G_elastic, recvcounts, displs, ISSM_MPI_DOUBLE,IssmComm::GetComm()); /*free ressources: */ xDelete(recvcounts); xDelete(displs); /*}}}*/ /*Avoid singularity at 0: */ G_elastic[0]=G_elastic[1]; parameters->AddObject(new DoubleVecParam(SealevelriseGElasticEnum,G_elastic,M)); /*free ressources: */ xDelete(love_h); xDelete(love_k); xDelete(G_elastic); xDelete(G_elastic_local); } /*Transitions: */ iomodel->FetchData(&transitions,&transitions_M,&transitions_N,&ntransitions,SealevelriseTransitionsEnum); if(transitions){ parameters->AddObject(new DoubleMatArrayParam(SealevelriseTransitionsEnum,transitions,ntransitions,transitions_M,transitions_N)); for(int i=0;i(transition); } xDelete(transitions); xDelete(transitions_M); xDelete(transitions_N); } /*Requested outputs*/ iomodel->FetchData(&requestedoutputs,&numoutputs,SealevelriseRequestedOutputsEnum); parameters->AddObject(new IntParam(SealevelriseNumRequestedOutputsEnum,numoutputs)); if(numoutputs)parameters->AddObject(new StringArrayParam(SealevelriseRequestedOutputsEnum,requestedoutputs,numoutputs)); iomodel->DeleteData(&requestedoutputs,numoutputs,SealevelriseRequestedOutputsEnum); }/*}}}*/ /*Finite Element Analysis*/ void SealevelriseAnalysis::Core(FemModel* femmodel){/*{{{*/ _error_("not implemented"); }/*}}}*/ ElementVector* SealevelriseAnalysis::CreateDVector(Element* element){/*{{{*/ /*Default, return NULL*/ return NULL; }/*}}}*/ ElementMatrix* SealevelriseAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/ _error_("Not implemented"); }/*}}}*/ ElementMatrix* SealevelriseAnalysis::CreateKMatrix(Element* element){/*{{{*/ _error_("not implemented yet"); }/*}}}*/ ElementVector* SealevelriseAnalysis::CreatePVector(Element* element){/*{{{*/ _error_("not implemented yet"); }/*}}}*/ void SealevelriseAnalysis::GetSolutionFromInputs(Vector* solution,Element* element){/*{{{*/ _error_("not implemented yet"); }/*}}}*/ void SealevelriseAnalysis::GradientJ(Vector* gradient,Element* element,int control_type,int control_index){/*{{{*/ _error_("Not implemented yet"); }/*}}}*/ void SealevelriseAnalysis::InputUpdateFromSolution(IssmDouble* solution,Element* element){/*{{{*/ IssmDouble *deltaS = NULL; IssmDouble *S = NULL; int* sidlist = NULL; int numvertices; numvertices= element->GetNumberOfVertices(); sidlist=xNew(numvertices); element->GetVerticesSidList(sidlist); deltaS = xNew(numvertices); for(int i=0;i(numvertices); element->GetInputListOnVertices(S,SealevelEnum,0); /*Add deltaS to S:*/ for (int i=0;iAddInput(SealevelEnum,S,P1Enum); /*Free ressources:*/ xDelete(sidlist); xDelete(deltaS); xDelete(S); }/*}}}*/ void SealevelriseAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/ /*Default, do nothing*/ return; }/*}}}*/