Skip to content

Commit 0e9db75

Browse files
geojobuenogeojobueno
andauthored
Implementation of dynamic sedimentation following Theunissen2019 algorithm (#151)
* first draft to implement theunissen2019 sedimentation * update main.cpp to print status in case of theunissen sedimentation * fix typo ";" in sp function * fix sedimentation rate update in reader.cpp, caused by the sed MODE * edit in Qs_flux update in each cell * trying to fix PETSC Error - free memory from seq array on processes and destroy seq_array from rank 0 * fix the broadcast from rank 0 after calculate the new seq_array surface * remove the first broadcast before the sedimentation logic --------- Co-authored-by: geojobueno <jo.bueno@hotmail.com>
1 parent 1e8607e commit 0e9db75

5 files changed

Lines changed: 191 additions & 4 deletions

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
/mandyoc
22
__pycache__
33
.pytest_cache
4-
/bin
4+
bin
5+
references
56

67
# Ignore the documentation building folder
78
docs/_build

src/main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ int main(int argc,char **args)
289289
CHKERRQ(ierr);
290290
}
291291

292-
if (dimensions == 2 && sp_mode == SP_SEDIMENTATION_RATE_LIMITED) {
292+
if (dimensions == 2 && ((sp_mode == SP_SEDIMENTATION_RATE_LIMITED)||(sp_mode == SP_THEUNISSEN_SEDIMENTATION))) {
293293
ierr = sp_update_sedimentation_rate(tempo);
294294
PetscPrintf(PETSC_COMM_WORLD,"sedimentation rate = %.3g m^2/yr, active sediment layer = %d\n", sedimentation_rate, active_sediment_layer);
295295
}

src/reader.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1056,7 +1056,7 @@ PetscErrorCode reader(int rank, const char fName[]){
10561056

10571057

10581058
// SP_Mode SP_SEDIMENTATION_RATE_LIMITED
1059-
if (dimensions == 2 && sp_mode == SP_SEDIMENTATION_RATE_LIMITED) {
1059+
if (dimensions == 2 && ((sp_mode == SP_SEDIMENTATION_RATE_LIMITED)||(sp_mode == SP_THEUNISSEN_SEDIMENTATION))) {
10601060
FILE *f_sedimentation_rate;
10611061

10621062
f_sedimentation_rate = fopen("sedimentation_rate.txt", "r");
@@ -1230,6 +1230,9 @@ SP_Mode sp_mode_from_string(const char* str) {
12301230
if (strcmp(str, "sedimentation_rate_limited") == 0) {
12311231
return SP_SEDIMENTATION_RATE_LIMITED;
12321232
}
1233+
if (strcmp(str, "theunissen_sedimentation") == 0) {
1234+
return SP_THEUNISSEN_SEDIMENTATION;
1235+
}
12331236

12341237
fprintf(stderr, "Error: Unknown sp_mode '%s'\nValid modes are:\n", str);
12351238
for (const char** mode = valid_modes; *mode; mode++) {
@@ -1249,6 +1252,8 @@ const char* sp_mode_to_string(SP_Mode mode) {
12491252
return "sedimentation_only";
12501253
case SP_SEDIMENTATION_RATE_LIMITED:
12511254
return "sedimentation_rate_limited";
1255+
case SP_THEUNISSEN_SEDIMENTATION:
1256+
return "theunissen_sedimentation";
12521257
}
12531258

12541259
// If execution reaches here, it's a programming error

src/sp.cpp

Lines changed: 180 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ PetscErrorCode sp_evaluate_surface_processes_2d(PetscReal dt);
7676
PetscErrorCode sp_evaluate_surface_processes_2d_diffusion(PetscReal dt);
7777
PetscErrorCode sp_evaluate_surface_processes_2d_sedimentation_only(PetscReal dt);
7878
PetscErrorCode sp_evaluate_surface_processes_2d_sedimentation_rate_limited(PetscReal dt);
79+
PetscErrorCode sp_evaluate_surface_processes_2d_theunissen(PetscReal dt);
7980
PetscErrorCode sp_update_surface_swarm_particles_properties();
8081
PetscErrorCode sp_update_active_sediment_layer(double time);
8182
PetscErrorCode sp_update_sedimentation_rate(double time);
@@ -90,7 +91,7 @@ PetscInt get_i(PetscReal cx);
9091
PetscInt get_k(PetscReal cz);
9192
PetscReal get_rx(PetscReal cx, PetscInt i);
9293
PetscReal get_rz(PetscReal cz, PetscInt k);
93-
94+
bool verbose_debug=false;
9495

9596
PetscErrorCode sp_create_surface_swarm_2d()
9697
{
@@ -517,6 +518,9 @@ PetscErrorCode sp_evaluate_surface_processes_2d(PetscReal dt)
517518
else if (sp_mode == SP_SEDIMENTATION_RATE_LIMITED) {
518519
ierr = sp_evaluate_surface_processes_2d_sedimentation_rate_limited(dt); CHKERRQ(ierr);
519520
}
521+
else if (sp_mode == SP_THEUNISSEN_SEDIMENTATION){
522+
ierr = sp_evaluate_surface_processes_2d_theunissen(dt); CHKERRQ(ierr);
523+
}
520524

521525
PetscFunctionReturn(0);
522526
}
@@ -866,6 +870,181 @@ PetscErrorCode sp_evaluate_surface_processes_2d_sedimentation_rate_limited(Petsc
866870
PetscFunctionReturn(0);
867871
}
868872

873+
PetscErrorCode sp_evaluate_surface_processes_2d_theunissen(PetscReal dt){
874+
PetscErrorCode ierr;
875+
PetscMPIInt rank;
876+
877+
PetscFunctionBeginUser;
878+
879+
ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
880+
881+
// Variables needed
882+
PetscInt n;
883+
PetscInt i;
884+
PetscInt j;
885+
PetscInt si;
886+
PetscInt bs;
887+
PetscInt nlocal;
888+
PetscInt seq_surface_size;
889+
Vec global_surface;
890+
Vec seq_surface;
891+
VecScatter ctx;
892+
PetscReal *seq_array;
893+
PetscReal *array;
894+
PetscReal Ld=35000.0; // (m) characteristic length scale
895+
896+
// Data to process rank 0
897+
ierr = DMSwarmCreateGlobalVectorFromField(dms_s, DMSwarmPICField_coor, &global_surface); CHKERRQ(ierr);
898+
ierr = VecScatterCreateToZero(global_surface, &ctx, &seq_surface); CHKERRQ(ierr);
899+
ierr = VecScatterBegin(ctx, global_surface, seq_surface, INSERT_VALUES, SCATTER_FORWARD); CHKERRQ(ierr);
900+
ierr = VecScatterEnd(ctx, global_surface, seq_surface, INSERT_VALUES, SCATTER_FORWARD); CHKERRQ(ierr);
901+
ierr = VecScatterDestroy(&ctx); CHKERRQ(ierr);
902+
ierr = DMSwarmDestroyGlobalVectorFromField(dms_s, DMSwarmPICField_coor, &global_surface); CHKERRQ(ierr);
903+
PetscReal hsl = sp_evaluate_adjusted_mean_elevation_with_sea_level();
904+
905+
if (!rank){
906+
ierr = VecGetSize(seq_surface, &seq_surface_size); CHKERRQ(ierr);
907+
ierr = VecGetArray(seq_surface, &seq_array); CHKERRQ(ierr);
908+
n = seq_surface_size/2;
909+
}
910+
911+
// Share data to all ranks
912+
ierr = MPI_Bcast(&seq_surface_size, 1, MPI_INT, 0, PETSC_COMM_WORLD); CHKERRQ(ierr);
913+
if (rank) {
914+
ierr = PetscCalloc1(seq_surface_size, &seq_array); CHKERRQ(ierr);
915+
n = seq_surface_size / 2;
916+
}
917+
// ierr = MPI_Bcast(seq_array, seq_surface_size, MPIU_SCALAR, 0, PETSC_COMM_WORLD); CHKERRQ(ierr);
918+
919+
// Dynamic progradation logic
920+
if (!rank){
921+
PetscReal dx_sed = seq_array[2*1]-seq_array[2*0]; // (m) spatial resolution for topography - constant
922+
PetscReal dep_factor = dx_sed/Ld; // dimensionless deposition factor
923+
PetscReal Qs_total = sedimentation_rate * (dt/seg_per_ano); // (m^2) sediment volume in the time step
924+
PetscReal Qs_flux, Qs_potential, Qs_excess, Qs_real_dep, h_potential, h_dep; // aux variables to calculate Qs in each node and the potential height
925+
PetscReal current_topo, h_accommodation; // topography and accomodation thickness
926+
Qs_flux = Qs_total;
927+
928+
if (verbose_debug==true){
929+
printf("dx_sed = %f\n",dx_sed);
930+
printf("hsl = %f \n", hsl);
931+
printf("dep_factor = %f\n",dep_factor);
932+
printf("sedimentation_rate=%e\n", sedimentation_rate);
933+
printf("Qs_total = %e\n",Qs_total);
934+
printf("dt = %e",dt);
935+
}
936+
printf("[Li] Qs_flux = %e m^2 || ",Qs_flux);
937+
// Future: Turn it on a separated generalized function for both sides deposition (0: L2R; 1: R2L)
938+
// left side progradation
939+
for (j=0; j<n; j++){
940+
Qs_potential = Qs_flux*dep_factor;
941+
h_potential = Qs_potential/dx_sed;
942+
943+
// check if the topography is bellow the sea level and how many sediment is deposited
944+
current_topo = seq_array[2*j+1]; // get the topography
945+
h_accommodation = hsl - current_topo; // accomodation space in the node (must be greather than 0 to deposition)
946+
if (h_accommodation < 0) h_accommodation = 0;
947+
948+
// Sediment Bypass
949+
if (h_potential <= h_accommodation){
950+
h_dep = h_potential;
951+
Qs_real_dep = h_dep*dx_sed;
952+
//Qs_excess = 0;
953+
954+
} else {
955+
h_dep = h_accommodation;
956+
Qs_real_dep = h_dep*dx_sed;
957+
// calculate the amount of sediment bypassed
958+
959+
//Qs_excess = Qs_potential-Qs_real_dep;
960+
}
961+
962+
if (verbose_debug==true){
963+
printf("current_topo = %f\n", current_topo);
964+
printf("h_potential = %f\n", h_potential);
965+
printf("h_dep = %f \n", h_dep);
966+
printf("h_accommodation = %f\n",h_accommodation);
967+
printf("Qs_potential = %e\n",Qs_potential);
968+
printf("Qs_real_dep = %e\n",Qs_real_dep);
969+
printf("dt = %e\n",dt);
970+
}
971+
972+
// Update topography
973+
seq_array[2*j+1] += h_dep;
974+
if (verbose_debug==true){printf("new_topo(%e) = %f\n",seq_array[2*j],seq_array[2*j+1]);}
975+
// Update Qs flux for the next cell
976+
Qs_flux = Qs_flux - Qs_real_dep; //+ Qs_excess; //Qs[i+1] = Qs[i]-Qdep[i]+Qbp[i]
977+
}
978+
printf("[Lf] Qs_flux = %e m^2 \n",Qs_flux);
979+
// printf("[L] Qs_total-Qs_flux = %e");
980+
Qs_flux = Qs_total;
981+
printf("[Ri] Qs_flux = %e m^2 || ",Qs_flux);
982+
// right side
983+
for (j = n-1; j>=0; j--){
984+
Qs_potential = Qs_flux*dep_factor;
985+
h_potential = Qs_potential/dx_sed;
986+
987+
// check if the topography is bellow the sea level and how many sediment is deposited
988+
current_topo = seq_array[2*j+1]; // get the topography
989+
h_accommodation = hsl - current_topo; // accomodation space in the node (must be greather than 0 to deposition)
990+
if (h_accommodation < 0) h_accommodation = 0;
991+
992+
// Sediment Bypass
993+
if (h_potential <= h_accommodation){
994+
h_dep = h_potential;
995+
Qs_real_dep = h_dep*dx_sed;
996+
Qs_excess = 0;
997+
998+
} else {
999+
h_dep = h_accommodation;
1000+
Qs_real_dep = h_dep*dx_sed;
1001+
// calculate the amount of sediment bypassed
1002+
1003+
Qs_excess = Qs_potential-Qs_real_dep;
1004+
}
1005+
1006+
1007+
// Update topography
1008+
seq_array[2*j+1] += h_dep;
1009+
1010+
// Update Qs flux for the next cell
1011+
Qs_flux = Qs_flux - Qs_real_dep; //+ Qs_excess; //Qs[i+1] = Qs[i]-Qdep[i]+Qbp[i]
1012+
}
1013+
printf("[Rf] Qs_flux = %e m^2 \n",Qs_flux);
1014+
}
1015+
1016+
// Broadcast processed data to all ranks
1017+
1018+
// according to gemini, modified to free memory correctly > unecessary broadcast
1019+
// ierr = MPI_Bcast(&seq_surface_size, 1, MPI_INT, 0, PETSC_COMM_WORLD); CHKERRQ(ierr);
1020+
1021+
// if (rank) {
1022+
// ierr = PetscCalloc1(seq_surface_size, &seq_array); CHKERRQ(ierr);
1023+
//}
1024+
ierr = MPI_Bcast(seq_array, seq_surface_size, MPIU_SCALAR, 0, PETSC_COMM_WORLD);
1025+
1026+
ierr = DMDAGetCorners(da_Veloc, &si, NULL, NULL, NULL, NULL, NULL); CHKERRQ(ierr);
1027+
ierr = DMSwarmGetLocalSize(dms_s, &nlocal); CHKERRQ(ierr);
1028+
ierr = DMSwarmGetField(dms_s, DMSwarmPICField_coor, &bs, NULL, (void**)&array); CHKERRQ(ierr);
1029+
1030+
for (j = 0; j < nlocal; j++) {
1031+
array[2*j] = seq_array[si*dms_s_ppe*2+2*j];
1032+
array[2*j+1] = seq_array[si*dms_s_ppe*2+2*j+1];
1033+
}
1034+
1035+
ierr = DMSwarmRestoreField(dms_s, DMSwarmPICField_coor, &bs, NULL, (void **)&array); CHKERRQ(ierr);
1036+
// ierr = VecRestoreArray(seq_surface, &seq_array); CHKERRQ(ierr);
1037+
// Modified to free memory correctly according to gemini
1038+
if (!rank) {
1039+
ierr = VecRestoreArray(seq_surface, &seq_array); CHKERRQ(ierr);
1040+
ierr = VecDestroy(&seq_surface); CHKERRQ(ierr);
1041+
} else {
1042+
ierr = PetscFree(seq_array); CHKERRQ(ierr);
1043+
}
1044+
1045+
PetscFunctionReturn(0);
1046+
}
1047+
8691048
PetscErrorCode sp_update_surface_swarm_particles_properties()
8701049
{
8711050
PetscMPIInt rank;

src/sp_mode.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ typedef enum {
1515
SP_DIFFUSION, // "diffusion"
1616
SP_SEDIMENTATION_ONLY, // "sedimentation_only"
1717
SP_SEDIMENTATION_RATE_LIMITED, // "sedimentation_rate_limited"
18+
SP_THEUNISSEN_SEDIMENTATION, // "theunissen_sedimentation"
1819
} SP_Mode;
1920

2021
// Conversion functions
@@ -26,6 +27,7 @@ static const char* valid_modes[] = {
2627
"\"diffusion\" - Simple diffusion (requires sp_d_c)",
2728
"\"sedimentation_only\" - Only sedimentation below height adjusted by sea level (requires sea_level)",
2829
"\"sedimentation_rate_limited\" - Fixed sedimentation rate on both margins under the sea level",
30+
"\"theunissen_sedimentation\" - Theunissen et al. (2019) dynamic progradation model under the sea level",
2931
NULL // Terminator
3032
};
3133

0 commit comments

Comments
 (0)