| 1134 | } |
| 1135 | |
| 1136 | GMT_LOCAL int grdflexure_write_transfer_function (struct GMT_CTRL *GMT, struct GRDFLEXURE_CTRL *Ctrl, struct GRDFLEXURE_RHEOLOGY *R, struct GMT_OPTION *options) { |
| 1137 | /* Write a table with six segments (one each for Te = 1, 2, 5, 10, 20, 50, and 100 km). |
| 1138 | * Each segment has leading columns of wavelength and wavenumber corresponding to wavelengths 1:5000 km. |
| 1139 | * The next 12 columns has the chosen transfer function evaluated for times 1k, 2k, 5k, 10k, 20k, 50k, 100k, 200k, 500k, 1M, 2M, and 5M years. |
| 1140 | * Each segment is written to a separate file. Obviously, if no -F or -M are given then all columns are the same since elastic */ |
| 1141 | uint64_t k; |
| 1142 | int t, s, n_times, n_te; |
| 1143 | char file[GMT_LEN64] = {""}; |
| 1144 | static char *FLX_response[7] = {"Airy", "Elastic", "Viscoelastic", "Firmoviscous (1 layer)", "Firmoviscous (2 layer)", "Viscous (1 layer)", "Viscous (2 layer)"}; |
| 1145 | uint64_t dim[4] = {1, 0, 0, 0}; |
| 1146 | double *kr, K[3], te[7] = {1.0, 2.0, 5.0, 10.0, 20.0, 50.0, 100.0}; |
| 1147 | double times[12] = {1.0, 2.0, 5.0, 10.0, 20.0, 50.0, 100.0, 200.0, 500.0, 1000.0, 2000.0, 5000.0}; /* Times in kiloyears */ |
| 1148 | struct GMT_DATASET *D = NULL; |
| 1149 | struct GMT_DATASEGMENT *S = NULL; |
| 1150 | struct GMT_DATASEGMENT_HIDDEN *SH = NULL; |
| 1151 | struct GMT_ARRAY T; |
| 1152 | |
| 1153 | gmt_M_memset (&T, 1, struct GMT_ARRAY); /* Wipe clean the structure */ |
| 1154 | |
| 1155 | R->relative = true; /* Relative times are implicitly given */ |
| 1156 | n_te = (R->mode > FLX_FV2) ? 1 : 7; /* For purely viscous we don't need to loop over plate thickness */ |
| 1157 | gmt_parse_array (GMT, 'T', "1/5000/1", &T, GMT_ARRAY_RANGE | GMT_ARRAY_UNIQUE, 0); /* In km */ |
| 1158 | gmt_create_array (GMT, 'T', &T, NULL, NULL); |
| 1159 | dim[GMT_ROW] = T.n; |
| 1160 | n_times = (Ctrl->F.active || Ctrl->M.active) ? 12 : 1; /* No point repeating 12 identical results for the elastic case */ |
| 1161 | dim[GMT_SEG] = n_te; |
| 1162 | dim[GMT_COL] = 2 + n_times; |
| 1163 | GMT_Report (GMT->parent, GMT_MSG_DEBUG, "Write transfer functions\n"); |
| 1164 | kr = gmt_M_memory (GMT, NULL, T.n, double); |
| 1165 | for (k = 0; k < T.n; k++) kr[k] = 2.0 * M_PI / (T.array[k] * 1000.0); /* Radial wavenumber in 1/m */ |
| 1166 | |
| 1167 | if ((D = GMT_Create_Data (GMT->parent, GMT_IS_DATASET, GMT_IS_LINE, 0, dim, NULL, NULL, 0, 0, NULL)) == NULL) |
| 1168 | return GMT_RUNTIME_ERROR; |
| 1169 | GMT_Set_Comment (GMT->parent, GMT_IS_DATASET, GMT_COMMENT_IS_OPTION | GMT_COMMENT_IS_COMMAND, options, D); |
| 1170 | gmt_set_tableheader (GMT, GMT_OUT, true); |
| 1171 | |
| 1172 | |
| 1173 | for (s = 0; s < n_te; s++) { |
| 1174 | S = D->table[0]->segment[s]; |
| 1175 | Ctrl->E.te[TE_INIT] = (n_te > 1) ? te[s] * 1000 : 0.0; /* Te in meters, zero for viscous only */ |
| 1176 | sprintf (file, "grdflexure_transfer_function_te_%3.3d_km.txt", irint (Ctrl->E.te[TE_INIT] * 0.001)); |
| 1177 | SH = gmt_get_DS_hidden (S); |
| 1178 | SH->file[GMT_OUT] = strdup (file); |
| 1179 | gmt_M_memcpy (S->data[0], T.array, T.n, double); |
| 1180 | gmt_M_memcpy (S->data[1], kr, T.n, double); |
| 1181 | GMT_Report (GMT->parent, GMT_MSG_INFORMATION, "%s transfer function for Te = %g km written to %s\n", FLX_response[R->mode], Ctrl->E.te[TE_INIT] * 0.001, SH->file[GMT_OUT]); |
| 1182 | for (t = 0; t < n_times; t++) { /* For each time step (i.e., at least once) */ |
| 1183 | R->eval_time_yr = times[t] * 1000.0; /* In years */ |
| 1184 | R->setup (GMT, Ctrl, R); /* Set up parameters */ |
| 1185 | R->scale = 1.0; /* We want these to go 0-1 only */ |
| 1186 | for (k = 0; k < T.n; k++) { /* Evaluate transfer functions */ |
| 1187 | K[GMT_FFT_K_IS_KR] = kr[k]; |
| 1188 | S->data[t+2][k] = R->transfer (K, R); |
| 1189 | } |
| 1190 | } |
| 1191 | } |
| 1192 | gmt_free_array (GMT, &T); |
| 1193 | gmt_M_free (GMT, kr); |
no test coverage detected