#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,"md.mask.ice_levelset",MaskIceLevelsetEnum); iomodel->FetchDataToInput(elements,"md.mask.ocean_levelset",MaskOceanLevelsetEnum); iomodel->FetchDataToInput(elements,"md.mask.land_levelset",MaskLandLevelsetEnum); iomodel->FetchDataToInput(elements,"md.slr.deltathickness",SealevelriseDeltathicknessEnum); iomodel->FetchDataToInput(elements,"md.slr.sealevel",SealevelEnum,0); iomodel->FetchDataToInput(elements,"md.slr.steric_rate",SealevelriseStericRateEnum); }/*}}}*/ void SealevelriseAnalysis::UpdateParameters(Parameters* parameters,IoModel* iomodel,int solution_enum,int analysis_enum){/*{{{*/ int nl; IssmDouble* love_h=NULL; IssmDouble* love_k=NULL; IssmDouble* love_l=NULL; bool elastic=false; IssmDouble* G_elastic = NULL; IssmDouble* G_elastic_local = NULL; IssmDouble* U_elastic = NULL; IssmDouble* U_elastic_local = NULL; IssmDouble* H_elastic = NULL; IssmDouble* H_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("md.slr.reltol",SealevelriseReltolEnum)); parameters->AddObject(iomodel->CopyConstantObject("md.slr.abstol",SealevelriseAbstolEnum)); parameters->AddObject(iomodel->CopyConstantObject("md.slr.maxiter",SealevelriseMaxiterEnum)); parameters->AddObject(iomodel->CopyConstantObject("md.slr.rigid",SealevelriseRigidEnum)); parameters->AddObject(iomodel->CopyConstantObject("md.slr.elastic",SealevelriseElasticEnum)); parameters->AddObject(iomodel->CopyConstantObject("md.slr.rotation",SealevelriseRotationEnum)); parameters->AddObject(iomodel->CopyConstantObject("md.slr.tide_love_h",SealevelriseTidalLoveHEnum)); parameters->AddObject(iomodel->CopyConstantObject("md.slr.tide_love_k",SealevelriseTidalLoveKEnum)); parameters->AddObject(iomodel->CopyConstantObject("md.slr.fluid_love",SealevelriseFluidLoveEnum)); parameters->AddObject(iomodel->CopyConstantObject("md.slr.equatorial_moi",SealevelriseEquatorialMoiEnum)); parameters->AddObject(iomodel->CopyConstantObject("md.slr.polar_moi",SealevelrisePolarMoiEnum)); parameters->AddObject(iomodel->CopyConstantObject("md.slr.angular_velocity",SealevelriseAngularVelocityEnum)); parameters->AddObject(iomodel->CopyConstantObject("md.slr.ocean_area_scaling",SealevelriseOceanAreaScalingEnum)); iomodel->FetchData(&elastic,"md.slr.elastic"); if(elastic){ /*love numbers: */ iomodel->FetchData(&love_h,&nl,NULL,"md.slr.love_h"); iomodel->FetchData(&love_k,&nl,NULL,"md.slr.love_k"); iomodel->FetchData(&love_l,&nl,NULL,"md.slr.love_l"); /*compute elastic green function for a range of angles*/ iomodel->FetchData(°acc,"md.slr.degacc"); M=reCast(180./degacc+1.); // AD performance is sensitive to calls to ensurecontiguous. // // Providing "t" will cause ensurecontiguous to be called. #ifdef _HAVE_AD_ G_elastic=xNew(M,"t"); U_elastic=xNew(M,"t"); H_elastic=xNew(M,"t"); #else G_elastic=xNew(M); U_elastic=xNew(M); H_elastic=xNew(M); #endif /*compute combined legendre + love number (elastic green function:*/ m=DetermineLocalSize(M,IssmComm::GetComm()); GetOwnershipBoundariesFromRange(&lower_row,&upper_row,m,IssmComm::GetComm()); // AD performance is sensitive to calls to ensurecontiguous. // // Providing "t" will cause ensurecontiguous to be called. #ifdef _HAVE_AD_ G_elastic_local=xNew(m,"t"); U_elastic_local=xNew(m,"t"); H_elastic_local=xNew(m,"t"); #else G_elastic_local=xNew(m); U_elastic_local=xNew(m); H_elastic_local=xNew(m); #endif 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); U_elastic_local[i-lower_row]= (love_h[nl-1])/2.0/sin(alpha/2.0); H_elastic_local[i-lower_row]= 0; IssmDouble Pn = 0.; IssmDouble Pn1 = 0.; IssmDouble Pn2 = 0.; IssmDouble Pn_p = 0.; IssmDouble Pn_p1 = 0.; IssmDouble Pn_p2 = 0.; 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()); ISSM_MPI_Allgatherv(U_elastic_local, m, ISSM_MPI_DOUBLE, U_elastic, recvcounts, displs, ISSM_MPI_DOUBLE,IssmComm::GetComm()); ISSM_MPI_Allgatherv(H_elastic_local, m, ISSM_MPI_DOUBLE, H_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)); U_elastic[0]=U_elastic[1]; parameters->AddObject(new DoubleVecParam(SealevelriseUElasticEnum,U_elastic,M)); H_elastic[0]=H_elastic[1]; parameters->AddObject(new DoubleVecParam(SealevelriseHElasticEnum,H_elastic,M)); /*free ressources: */ xDelete(love_h); xDelete(love_k); xDelete(love_l); xDelete(G_elastic); xDelete(G_elastic_local); xDelete(U_elastic); xDelete(U_elastic_local); xDelete(H_elastic); xDelete(H_elastic_local); } /*Transitions: */ iomodel->FetchData(&transitions,&transitions_M,&transitions_N,&ntransitions,"md.slr.transitions"); 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->FindConstant(&requestedoutputs,&numoutputs,"md.slr.requested_outputs"); if(numoutputs)parameters->AddObject(new StringArrayParam(SealevelriseRequestedOutputsEnum,requestedoutputs,numoutputs)); iomodel->DeleteData(&requestedoutputs,numoutputs,"md.slr.requested_outputs"); }/*}}}*/ /*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; }/*}}}*/