source: issm/branches/trunk-larour-SLPS2022/src/c/classes/GrdLoads.cpp@ 26956

Last change on this file since 26956 was 26800, checked in by caronlam, 3 years ago

BUG: Sealevelchange core: load weights did not add up correctly; BUG: Sealevel change core viscous stacks were offset in time; partial load area phi was double counted, appearing both in Green functions and loads; NEW: love core optimization, paralelization supported, support for viscous rotational feedback; NEW:Sea level change core: support for viscous rotational feedback; CHG: grd loads now contain the average kg.m-2 over the (sub-)elemental area they apply in, not the average*phi, phi is simply accounted for in the loadarea or Green's function; NEW: nightly runs 2070, 2071, 2072, 2091, 2092 test Spada et al (2011) benchmark cases

File size: 3.6 KB
Line 
1/*
2 * \file GrdLoads.cpp
3 * \brief: Implementation of GrdLoads class
4 */
5
6/*Headers: {{{*/
7#ifdef HAVE_CONFIG_H
8 #include <config.h>
9#else
10#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
11#endif
12
13#include "./GrdLoads.h"
14#include "./SealevelGeometry.h"
15using namespace std;
16/*}}}*/
17
18/*Object constructors and destructor*/
19GrdLoads::GrdLoads(int nel,SealevelGeometry* slgeom){ /*{{{*/
20
21 vloads=new Vector<IssmDouble>(nel);
22 for (int i=0;i<SLGEOM_NUMLOADS;i++) vsubloads[i]=new Vector<IssmDouble>(slgeom->nbar[i]);
23
24 vsealevelloads=new Vector<IssmDouble>(nel);
25 vsealevelloads->Set(0);vsealevelloads->Assemble();
26
27 vsubsealevelloads=new Vector<IssmDouble>(slgeom->nbar[SLGEOM_OCEAN]);
28
29}; /*}}}*/
30GrdLoads::~GrdLoads(){ /*{{{*/
31
32 delete vloads;
33 xDelete<IssmDouble>(loads);
34 for(int i=0;i<SLGEOM_NUMLOADS;i++){
35 delete vsubloads[i];
36 xDelete<IssmDouble>(subloads[i]);
37 }
38 delete vsealevelloads;
39 xDelete<IssmDouble>(sealevelloads);
40 delete vsubsealevelloads;
41 xDelete<IssmDouble>(subsealevelloads);
42}; /*}}}*/
43
44void GrdLoads::BroadcastLoads(void){ /*{{{*/
45
46 /*Initialize barycentre vectors, now that we know their size: */
47 vloads->Assemble();
48 for (int i=0;i<SLGEOM_NUMLOADS;i++){
49 vsubloads[i]->Assemble();
50 }
51
52 loads=vloads->ToMPISerial();
53 for (int i=0;i<SLGEOM_NUMLOADS;i++){
54 subloads[i]=vsubloads[i]->ToMPISerial();
55 }
56
57} /*}}}*/
58void GrdLoads::AssembleSealevelLoads(void){ /*{{{*/
59
60 vsealevelloads->Assemble();
61 vsubsealevelloads->Assemble();
62
63} /*}}}*/
64void GrdLoads::BroadcastSealevelLoads(void){ /*{{{*/
65
66 sealevelloads=vsealevelloads->ToMPISerial();
67 subsealevelloads=vsubsealevelloads->ToMPISerial();
68
69} /*}}}*/
70void GrdLoads::SHDegree2Coefficients(IssmDouble* deg2coeff, FemModel* femmodel, SealevelGeometry* slgeom){
71
72 IssmDouble area,re, S;
73 int ylmindex, intj;
74 IssmDouble deg2coeff_local[5];
75
76 femmodel->parameters->FindParam(&re,SolidearthPlanetRadiusEnum);
77
78 for (int c=0;c<5;c++) deg2coeff_local[c]=0;
79
80 for(Object* & object : femmodel->elements->objects){
81 Element* element = xDynamicCast<Element*>(object);
82 //first, loads on centroids
83 S=0;
84 S+=loads[element->Sid()];
85
86 if(sealevelloads) S+=sealevelloads[element->Sid()];
87 if(S!=0){
88 element->Element::GetInputValue(&area,AreaEnum);
89
90 for (int c=0;c<5;c++){ //degree l=2 has 2*l+1=5 coefficients: 2,0; 2,1cos; 2,1sin; 2,2cos; 2,2sin
91 ylmindex=(4+c)*slgeom->localnel+element->lid; // starting at index=l^2
92 deg2coeff_local[c] += S*area/re/re*slgeom->Ylm[ylmindex];
93 }
94 }
95 //add loads on subelement barycenters
96 for (int i=0;i<SLGEOM_NUMLOADS;i++){
97 if (slgeom->issubelement[i][element->lid]){
98 intj=slgeom->subelementmapping[i][element->lid];
99 S=0;
100 S+=subloads[i][intj];
101 if(i==SLGEOM_OCEAN && sealevelloads) S+=subsealevelloads[intj];
102 if(S!=0){
103 area=slgeom->area_subel[i][intj];
104 for (int c=0;c<5;c++){ //degree l=2 has 2*l+1=5 coefficients
105 ylmindex=(4+c)*slgeom->localnel+element->lid; // starting at index=l^2
106 deg2coeff_local[c] += S*area/re/re*slgeom->Ylm_subel[i][ylmindex];
107 }
108 }
109 }
110 }
111 }
112
113 //sum each degree 2 coefficient across all cpus to get global total
114 ISSM_MPI_Reduce (&deg2coeff_local[0],&deg2coeff[0],1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
115 ISSM_MPI_Bcast(&deg2coeff[0],1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
116 ISSM_MPI_Reduce (&deg2coeff_local[1],&deg2coeff[1],1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
117 ISSM_MPI_Bcast(&deg2coeff[1],1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
118 ISSM_MPI_Reduce (&deg2coeff_local[2],&deg2coeff[2],1,ISSM_MPI_DOUBLE,ISSM_MPI_SUM,0,IssmComm::GetComm() );
119 ISSM_MPI_Bcast(&deg2coeff[2],1,ISSM_MPI_DOUBLE,0,IssmComm::GetComm());
120
121}
Note: See TracBrowser for help on using the repository browser.