Skip to content

Commit f0c25f7

Browse files
committed
Passing oceanDragCoeff and using same vel corrections as rebase 29 June
1 parent 229c8cb commit f0c25f7

8 files changed

Lines changed: 121 additions & 17 deletions

File tree

src/pmpo_MPMesh_assembly.hpp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -342,16 +342,24 @@ void MPMesh::assemblyVtx1(){
342342
p_mesh->fillMeshField<meshFieldIndex>(numVtx, numEntries, 0.0);
343343
auto meshField = p_mesh->getMeshField<meshFieldIndex>();
344344

345+
auto vtxRotLon = p_mesh->getMeshField<MeshF_VtxRotLon>();
346+
345347
//Material Points
346348
auto mpData = p_MPs->getData<mpfIndex>();
347349
auto weight = p_MPs->getData<MPF_Basis_Vals>();
348350
auto mpPositions = p_MPs->getData<MPF_Cur_Pos_XYZ>();
349-
351+
auto curPosRotLatLon = p_MPs->getData<MPF_Cur_Pos_Rot_Lat_Lon>();
352+
auto MPsAppID = p_MPs->getData<MPF_MP_APP_ID>();
350353
//Earth Radius
351354
double radius = 1.0;
352355
if(p_mesh->getGeomType() == geom_spherical_surf)
353356
radius=p_mesh->getSphereRadius();
354357

358+
bool use_correction_term = false;
359+
if constexpr (meshFieldIndex == MeshF_Vel) {
360+
use_correction_term = true;
361+
}
362+
355363
//Reconstruct
356364
auto reconstruct = PS_LAMBDA(const int& elm, const int& mp, const int& mask) {
357365
if(mask) { //if material point is 'active'/'enabled'
@@ -367,9 +375,20 @@ void MPMesh::assemblyVtx1(){
367375
VtxCoeffs_new(vID,0, 2)*CoordDiffs[2] +
368376
VtxCoeffs_new(vID,0, 3)*CoordDiffs[3]);
369377

370-
for (int k=0; k<numEntries; k++){
371-
auto val = factor*mpData(mp,k);
372-
Kokkos::atomic_add(&meshField(vID,k), val);
378+
if (use_correction_term){
379+
double transport[2] = {0.0};
380+
seaice_mpm_coord_parallel_transport(curPosRotLatLon(mp, 1), vtxRotLon(vID), curPosRotLatLon(mp, 0), transport);
381+
const double u = transport[0] * mpData(mp,0) + transport[1] * mpData(mp,1);
382+
const double v = -transport[1] * mpData(mp,0) + transport[0] * mpData(mp,1);
383+
384+
Kokkos::atomic_add(&meshField(vID,0), factor * u);
385+
Kokkos::atomic_add(&meshField(vID,1), factor * v);
386+
}
387+
else{
388+
for (int k=0; k<numEntries; k++){
389+
auto val = factor*mpData(mp,k);
390+
Kokkos::atomic_add(&meshField(vID,k), val);
391+
}
373392
}
374393
}
375394
}

src/pmpo_c.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1207,6 +1207,25 @@ void polympo_getMeshVtxRotLat_f(MPMesh_ptr p_mpmesh, const int nVertices, double
12071207
}
12081208
}
12091209

1210+
void polympo_setMeshVtxRotLon_f(MPMesh_ptr p_mpmesh, const int nVertices, const double* longitude){
1211+
Kokkos::Timer timer;
1212+
//chech validity
1213+
checkMPMeshValid(p_mpmesh);
1214+
auto p_mesh = ((polyMPO::MPMesh*)p_mpmesh)->p_mesh;
1215+
1216+
//check the size
1217+
PMT_ALWAYS_ASSERT(p_mesh->getNumVertices()==nVertices);
1218+
1219+
//copy the host array to the device
1220+
auto coordsArray = p_mesh->getMeshField<polyMPO::MeshF_VtxRotLon>();
1221+
auto h_coordsArray = Kokkos::create_mirror_view(coordsArray);
1222+
for(int i=0; i<nVertices; i++){
1223+
h_coordsArray(i) = longitude[i];
1224+
}
1225+
Kokkos::deep_copy(coordsArray, h_coordsArray);
1226+
pumipic::RecordTime("PolyMPO_setMeshVtxRotLon", timer.seconds());
1227+
}
1228+
12101229
void polympo_setMeshVtxVel_f(MPMesh_ptr p_mpmesh, const int nVertices, const double* uVelIn, const double* vVelIn){
12111230
//check mpMesh is valid
12121231
checkMPMeshValid(p_mpmesh);
@@ -1674,9 +1693,9 @@ void polympo_set_oceanStressCoefficient_f(MPMesh_ptr p_mpmesh, const int nVertic
16741693
Kokkos::deep_copy(oceanStressCoeff, h_oceanStressCoeff);
16751694
}
16761695

1677-
void polympo_calculate_oceanStressCoefficient_f(MPMesh_ptr p_mpmesh){
1696+
void polympo_calculate_oceanStressCoefficient_f(MPMesh_ptr p_mpmesh, const double configIceOceanDragCoeff){
16781697
auto p_mesh = ((polyMPO::MPMesh*)p_mpmesh)->p_mesh;
1679-
p_mesh->calcOceanStressCoeff();
1698+
p_mesh->calcOceanStressCoeff(configIceOceanDragCoeff);
16801699
}
16811700

16821701
void polympo_velocity_grid_solve_f(MPMesh_ptr p_mpmesh){

src/pmpo_c.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ int polympo_getMeshFElmType_f();
8989
void polympo_setMeshVtxCoords_f(MPMesh_ptr p_mpmesh, const int nVertices, const double* xArray, const double* yArray, const double* zArray);
9090
void polympo_getMeshVtxCoords_f(MPMesh_ptr p_mpmesh, const int nVertices, double* xArray, double* yArray, double* zArray);
9191
void polympo_setMeshVtxRotLat_f(MPMesh_ptr p_mpmesh, const int nVertices, const double* latitude);
92+
void polympo_setMeshVtxRotLon_f(MPMesh_ptr p_mpmesh, const int nVertices, const double* longitude);
9293
void polympo_getMeshVtxRotLat_f(MPMesh_ptr p_mpmesh, const int nVertices, double* latitude);
9394
void polympo_setMeshVtxVel_f(MPMesh_ptr p_mpmesh, const int nVertices, const double* uVelocity, const double* vVelocity);
9495
void polympo_getMeshVtxVel_f(MPMesh_ptr p_mpmesh, const int nVertices, double* uVelocity, double* vVelocity);
@@ -119,7 +120,7 @@ void polympo_set_surfaceTiltForce_f(MPMesh_ptr p_mpmesh, const int nVertices, do
119120
void polympo_set_totalMassVertexfVertex_f(MPMesh_ptr p_mpmesh, const int nVertices, double* array);
120121
void polympo_set_oceanStress_f(MPMesh_ptr p_mpmesh, const int nVertices, double* uArray, double* vArray);
121122
void polympo_set_oceanStressCoefficient_f(MPMesh_ptr p_mpmesh, const int nVertices, double* array);
122-
void polympo_calculate_oceanStressCoefficient_f(MPMesh_ptr p_mpmesh);
123+
void polympo_calculate_oceanStressCoefficient_f(MPMesh_ptr p_mpmesh, const double configIceOceanDragCoeff);
123124
void polympo_velocity_grid_solve_f(MPMesh_ptr p_mpmesh);
124125
void polympo_set_boundary_normal_vertex_f(MPMesh_ptr p_mpmesh, const int nComps, const int nVertices, double* uArray, double* vArray);
125126
void polympo_set_free_slip_bc_f(MPMesh_ptr p_mpmesh);

src/pmpo_fortran.f90

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,14 @@ subroutine polympo_getMeshVtxRotLat(mpMesh, nVertices, latitude) &
786786
type(c_ptr), value :: latitude
787787
end subroutine
788788

789+
subroutine polympo_setMeshVtxRotLon(mpMesh, nVertices, longitude) &
790+
bind(C, NAME='polympo_setMeshVtxRotLon_f')
791+
use :: iso_c_binding
792+
type(c_ptr), value :: mpMesh
793+
integer(c_int), value :: nVertices
794+
type(c_ptr), intent(in), value :: longitude
795+
end subroutine
796+
789797
!---------------------------------------------------------------------------
790798
!> @brief set the vertices velocity from a host array
791799
!> @param mpmesh(in/out) MPMesh object
@@ -1111,10 +1119,11 @@ subroutine polympo_set_oceanStressCoefficient(mpMesh, nVertices, array) &
11111119
type(c_ptr), value :: array
11121120
end subroutine
11131121

1114-
subroutine polympo_calculate_oceanStressCoefficient(mpMesh) &
1122+
subroutine polympo_calculate_oceanStressCoefficient(mpMesh, configIceOceanDragCoeff) &
11151123
bind(C, NAME='polympo_calculate_oceanStressCoefficient_f')
11161124
use :: iso_c_binding
11171125
type(c_ptr), value :: mpMesh
1126+
real(c_double), value::configIceOceanDragCoeff
11181127
end subroutine
11191128

11201129
subroutine polympo_velocity_grid_solve(mpMesh) &

src/pmpo_mesh.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ namespace polyMPO{
2020
PMT_ALWAYS_ASSERT(vtxRotLatMapEntry.first == MeshFType_VtxBased);
2121
vtxRotLat_ = MeshFView<MeshF_VtxRotLat>(vtxRotLatMapEntry.second,numVtxs_);
2222

23+
auto vtxRotLonMapEntry = meshFields2TypeAndString.at(MeshF_VtxRotLon);
24+
PMT_ALWAYS_ASSERT(vtxRotLonMapEntry.first == MeshFType_VtxBased);
25+
vtxRotLon_ = MeshFView<MeshF_VtxRotLon>(vtxRotLonMapEntry.second,numVtxs_);
26+
2327
auto vtxVelMapEntry = meshFields2TypeAndString.at(MeshF_Vel);
2428
PMT_ALWAYS_ASSERT(vtxVelMapEntry.first == MeshFType_VtxBased);
2529
vtxVel_ = MeshFView<MeshF_Vel>(vtxVelMapEntry.second,numVtxs_);
@@ -160,18 +164,19 @@ namespace polyMPO{
160164
});
161165
}
162166

163-
void Mesh::calcOceanStressCoeff(){
167+
void Mesh::calcOceanStressCoeff(const double configIceOceanDragCoeff){
164168
int numVerticesOwned = getNumVerticesOwned();
165169
auto iceAreaVtx = getMeshField<polyMPO::MeshF_VtxMass>();
166170
auto oceanStressCoeff = getMeshField<MeshF_OceanStressCoeff>();
167171
auto velocity = getMeshField<MeshF_Vel>();
168172
auto solve_velocity = getMeshField<MeshF_SolveVelocity>();
169173
auto oceanVelocity = getMeshField<MeshF_OceanVelocity>();
174+
auto seaiceDensitySeaWater_ = polyMPO::seaiceDensitySeaWater;
170175

171176
Kokkos::parallel_for("calcOceanStressCoeff", numVerticesOwned, KOKKOS_LAMBDA(const int vtx){
172177
if(solve_velocity(vtx) == 0) return;
173178
auto relVelSq = pow(oceanVelocity(vtx, 0) - velocity(vtx, 0), 2) + pow(oceanVelocity(vtx, 1) - velocity(vtx, 1), 2);
174-
oceanStressCoeff(vtx, 0) = 0.00536 * 1026.0 * iceAreaVtx(vtx, 0) * sqrt(relVelSq);
179+
oceanStressCoeff(vtx, 0) = configIceOceanDragCoeff * seaiceDensitySeaWater_ * iceAreaVtx(vtx, 0) * sqrt(relVelSq);
175180
});
176181
}
177182

src/pmpo_mesh.hpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ enum MeshFieldIndex{
1919
MeshF_Unsupported,
2020
MeshF_VtxCoords,
2121
MeshF_VtxRotLat,
22+
MeshF_VtxRotLon,
2223
MeshF_ElmCenterXYZ,
2324
MeshF_DualTriangleArea,
2425
MeshF_Vel,
@@ -55,6 +56,7 @@ enum MeshFieldType{
5556
template <MeshFieldIndex> struct meshFieldToType;
5657
template <> struct meshFieldToType < MeshF_VtxCoords > { using type = Kokkos::View<vec3d_t*>; };
5758
template <> struct meshFieldToType < MeshF_VtxRotLat > { using type = DoubleView; };
59+
template <> struct meshFieldToType < MeshF_VtxRotLon > { using type = DoubleView; };
5860
template <> struct meshFieldToType < MeshF_ElmCenterXYZ > { using type = Kokkos::View<vec3d_t*>; };
5961
template <> struct meshFieldToType < MeshF_DualTriangleArea > { using type = Kokkos::View<doubleSclr_t*>; };
6062
template <> struct meshFieldToType < MeshF_Vel > { using type = Kokkos::View<vec2d_t*>; };
@@ -88,6 +90,7 @@ const std::map<MeshFieldIndex, std::pair<MeshFieldType, std::string>> meshFields
8890
{MeshF_Unsupported, {MeshFType_Unsupported,"MeshField_Unsupported"}},
8991
{MeshF_VtxCoords, {MeshFType_VtxBased,"MeshField_VerticesCoords"}},
9092
{MeshF_VtxRotLat, {MeshFType_VtxBased,"MeshField_VerticesLatitude"}},
93+
{MeshF_VtxRotLon, {MeshFType_VtxBased,"MeshField_VerticesLongitude"}},
9194
{MeshF_ElmCenterXYZ, {MeshFType_ElmBased,"MeshField_ElementCenterXYZ"}},
9295
{MeshF_DualTriangleArea, {MeshFType_VtxBased,"MeshField_DualTriangleArea"}},
9396
{MeshF_Vel, {MeshFType_VtxBased,"MeshField_Velocity"}},
@@ -144,6 +147,7 @@ class Mesh {
144147
//start of meshFields
145148
MeshFView<MeshF_VtxCoords> vtxCoords_;
146149
MeshFView<MeshF_VtxRotLat> vtxRotLat_;
150+
MeshFView<MeshF_VtxRotLon> vtxRotLon_;
147151
MeshFView<MeshF_ElmCenterXYZ> elmCenterXYZ_;
148152
MeshFView<MeshF_DualTriangleArea> dualTriangleArea_;
149153

@@ -159,7 +163,7 @@ class Mesh {
159163
//GnomonicProjection
160164
MeshFView<MeshF_VtxGnomProj> vtxGnomProj_;
161165
MeshFView<MeshF_ElmCenterGnomProj> elmCenterGnomProj_;
162-
166+
163167
MeshFView<MeshF_TanLatVertexRotatedOverRadius> tanLatVertexRotatedOverRadius_;
164168
MeshFView<MeshF_SolveStress> solveStress_;
165169
MeshFView<MeshF_SolveVelocity> solveVelocity_;
@@ -276,7 +280,7 @@ class Mesh {
276280
return dynamicTimeStep_;
277281
}
278282

279-
void calcOceanStressCoeff();
283+
void calcOceanStressCoeff(const double configIceOceanDragCoeff);
280284
void gridSolveGPU();
281285
void aggregateDeluDyn();
282286
void applyFreeSlipBC();
@@ -298,6 +302,9 @@ auto Mesh::getMeshField(){
298302
else if constexpr (index==MeshF_VtxRotLat){
299303
return vtxRotLat_;
300304
}
305+
else if constexpr (index==MeshF_VtxRotLon){
306+
return vtxRotLon_;
307+
}
301308
else if constexpr (index==MeshF_ElmCenterXYZ){
302309
return elmCenterXYZ_;
303310
}

src/pmpo_utils.hpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ using DoubleView = Kokkos::View<double*>;
4545
using IntView = Kokkos::View<int*>;
4646
using BoolView = Kokkos::View<bool*>;
4747

48+
//CONSTANTS
49+
inline constexpr double seaiceDensitySeaWater = 1026.0;
50+
4851
class Vec2d {
4952
private:
5053
vec2d_t coords_;
@@ -554,6 +557,24 @@ void lat_lon_from_xyz(double& lat, double& lon, Vec3d& xyz, double r){
554557
lat = Kokkos::asin(xyz[2]/r);
555558
}
556559

560+
KOKKOS_INLINE_FUNCTION
561+
double seaice_mpm_wrap_longitude(const double longitude){
562+
const auto PI = 3.141592653589;
563+
const auto TAU = 2*PI;
564+
const double wrapped = longitude - Kokkos::floor((longitude + PI) / TAU) * TAU;
565+
return wrapped;
566+
}
567+
568+
KOKKOS_INLINE_FUNCTION
569+
void seaice_mpm_coord_parallel_transport(const double long_start, const double long_end,
570+
const double latitude, double transport[2]){
571+
double dLon = long_end - long_start;
572+
dLon = seaice_mpm_wrap_longitude(dLon);
573+
const double psi = dLon * Kokkos::sin(latitude);
574+
transport[0] = Kokkos::cos(psi);
575+
transport[1] = Kokkos::sin(psi);
576+
}
577+
557578
}//namespace polyMPO end
558579

559580
#endif

src/pmpo_wachspressBasis.hpp

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,48 @@ void sphericalInterpolation(MPMesh& mpMesh){
1515
auto vtxCoords = p_mesh->getMeshField<polyMPO::MeshF_VtxCoords>();
1616
int numVtxs = p_mesh->getNumVertices();
1717
auto elm2VtxConn = p_mesh->getElm2VtxConn();
18+
auto vtxRotLon = p_mesh->getMeshField<MeshF_VtxRotLon>();
1819

1920
auto p_MPs = mpMesh.p_MPs;
2021
auto MPsPosition = p_MPs->getPositions();
2122
auto MPsBasis = p_MPs->getData<MPF_Basis_Vals>();
23+
auto curPosRotLatLon = p_MPs->getData<MPF_Cur_Pos_Rot_Lat_Lon>();
24+
auto MPsAppID = p_MPs->getData<MPF_MP_APP_ID>();
2225

2326
constexpr MaterialPointSlice mpfIndex = meshFieldIndexToMPSlice<meshFieldIndex>;
2427
auto mpField = p_MPs->getData<mpfIndex>();
2528

2629
const int numEntries = mpSliceToNumEntries<mpfIndex>();
2730
auto meshField = p_mesh->getMeshField<meshFieldIndex>();
2831

32+
bool use_correction_term = false;
33+
if constexpr (meshFieldIndex == MeshF_OnSurfVeloIncr) {
34+
use_correction_term = true;
35+
}
36+
2937
auto interpolation = PS_LAMBDA(const int& elm, const int& mp, const int& mask) {
3038
if(mask) { //if material point is 'active'/'enabled'
3139
int numVtx = elm2VtxConn(elm,0);
32-
for(int entry=0; entry<numEntries; entry++){
33-
double mpValue = 0.0;
34-
for(int i=1; i<= numVtx; i++)
35-
mpValue += meshField(elm2VtxConn(elm,i)-1,entry)*MPsBasis(mp,i-1);
36-
mpField(mp,entry) = mpValue;
40+
41+
if(use_correction_term){
42+
double transport[2] = {0.0};
43+
double mpField_l[2] = {0.0};
44+
for(int i=1; i<=numVtx; i++){
45+
int vID = elm2VtxConn(elm,i)-1;
46+
seaice_mpm_coord_parallel_transport(vtxRotLon(vID), curPosRotLatLon(mp, 1), curPosRotLatLon(mp, 0), transport);
47+
mpField_l[0] += ( transport[0] * meshField(vID, 0) + transport[1] * meshField(vID, 1)) * MPsBasis(mp,i-1);
48+
mpField_l[1] += (-transport[1] * meshField(vID, 0) + transport[0] * meshField(vID, 1)) * MPsBasis(mp,i-1);
49+
}
50+
mpField(mp, 0) = mpField_l[0];
51+
mpField(mp, 1) = mpField_l[1];
52+
}
53+
else{
54+
for(int entry=0; entry<numEntries; entry++){
55+
double mpValue = 0.0;
56+
for(int i=1; i<= numVtx; i++)
57+
mpValue += meshField(elm2VtxConn(elm,i)-1,entry)*MPsBasis(mp,i-1);
58+
mpField(mp,entry) = mpValue;
59+
}
3760
}
3861
}
3962
};

0 commit comments

Comments
 (0)