@@ -76,6 +76,7 @@ PetscErrorCode sp_evaluate_surface_processes_2d(PetscReal dt);
7676PetscErrorCode sp_evaluate_surface_processes_2d_diffusion (PetscReal dt);
7777PetscErrorCode sp_evaluate_surface_processes_2d_sedimentation_only (PetscReal dt);
7878PetscErrorCode sp_evaluate_surface_processes_2d_sedimentation_rate_limited (PetscReal dt);
79+ PetscErrorCode sp_evaluate_surface_processes_2d_theunissen (PetscReal dt);
7980PetscErrorCode sp_update_surface_swarm_particles_properties ();
8081PetscErrorCode sp_update_active_sediment_layer (double time);
8182PetscErrorCode sp_update_sedimentation_rate (double time);
@@ -90,7 +91,7 @@ PetscInt get_i(PetscReal cx);
9091PetscInt get_k (PetscReal cz);
9192PetscReal get_rx (PetscReal cx, PetscInt i);
9293PetscReal get_rz (PetscReal cz, PetscInt k);
93-
94+ bool verbose_debug= false ;
9495
9596PetscErrorCode 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+
8691048PetscErrorCode sp_update_surface_swarm_particles_properties ()
8701049{
8711050 PetscMPIInt rank;
0 commit comments