double jac_form_vol(int n, double *wt, Func<double> *u_ext[], Func<double> *u, Func<double> *v, Geom<double> *e, ExtData<double> *ext) { int elem_marker = e->elem_marker; double result = 0; Func<double>* K_sln = u_ext[0]; Func<double>* h_prev_time = ext->fn[0]; for (int i = 0; i < n; i++) { double h_prev_val_i = h_prev_time->val[i] + K_sln->val[i]; double h_prev_dx_i = h_prev_time->dx[i] + K_sln->dx[i]; double h_prev_dy_i = h_prev_time->dy[i] + K_sln->dy[i]; result += wt[i] * ( //C(h_prev_newton->val[i], elem_marker) * u->val[i] * v->val[i] / TAU //+ dCdh(h_prev_newton->val[i], elem_marker) * u->val[i] * h_prev_newton->val[i] * v->val[i] / TAU //- dCdh(h_prev_newton->val[i], elem_marker) * u->val[i] * h_prev_time->val[i] * v->val[i] / TAU - K(h_prev_val_i, elem_marker) * (u->dx[i] * v->dx[i] + u->dy[i] * v->dy[i]) - dKdh(h_prev_val_i, elem_marker) * u->val[i] * (h_prev_dx_i*v->dx[i] + h_prev_dy_i*v->dy[i]) + dKdh(h_prev_val_i, elem_marker) * u->dy[i] * v->val[i] + ddKdhh(h_prev_val_i, elem_marker) * u->val[i] * h_prev_dy_i * v->val[i] ) / C(h_prev_time->val[i], elem_marker); } return result; }
// Jacobian matrix - volumetric part double jac_form_vol_cranic(int n, double *wt, Func<double> *u_ext[], Func<double> *u, Func<double> *v, Geom<double> *e, ExtData<double> *ext) { double x = e->x[0]; double y = e->x[1]; if (is_in_mat_1(x,y)) { K_S = K_S_1; ALPHA = ALPHA_1; THETA_R = THETA_R_1; THETA_S = THETA_R_1; N = N_1; M = M_1; } if (is_in_mat_2(x,y)) { K_S = K_S_2; ALPHA = ALPHA_2; THETA_R = THETA_R_2; THETA_S = THETA_R_2; N = N_2; M = M_2; } if (is_in_mat_3(x,y)) { K_S = K_S_3; ALPHA = ALPHA_3; THETA_R = THETA_R_3; THETA_S = THETA_R_3; N = N_3; M = M_3; } if (is_in_mat_4(x,y)) { K_S = K_S_4; ALPHA = ALPHA_4; THETA_R = THETA_R_4; THETA_S = THETA_R_4; N = N_4; M = M_4; } double result = 0; Func<double>* h_prev_newton = ext->fn[0]; Func<double>* h_prev_time = ext->fn[1]; for (int i = 0; i < n; i++) result += wt[i] * 0.5 * ( // implicit Euler part: C(h_prev_newton->val[i]) * u->val[i] * v->val[i] / TAU + dCdh(h_prev_newton->val[i]) * u->val[i] * h_prev_newton->val[i] * v->val[i] / TAU - dCdh(h_prev_newton->val[i]) * u->val[i] * h_prev_time->val[i] * v->val[i] / TAU + K(h_prev_newton->val[i]) * (u->dx[i] * v->dx[i] + u->dy[i] * v->dy[i]) + dKdh(h_prev_newton->val[i]) * u->val[i] * (h_prev_newton->dx[i]*v->dx[i] + h_prev_newton->dy[i]*v->dy[i]) - dKdh(h_prev_newton->val[i]) * u->dy[i] * v->val[i] - ddKdhh(h_prev_newton->val[i]) * u->val[i] * h_prev_newton->dy[i] * v->val[i] ) + wt[i] * 0.5 * ( // explicit Euler part, C(h_prev_time->val[i]) * u->val[i] * v->val[i] / TAU ); return result; }
// Residual vector - volumetric part double res_form_vol_cranic(int n, double *wt, Func<double> *u_ext[], Func<double> *v, Geom<double> *e, ExtData<double> *ext) { double result = 0; Func<double>* h_prev_newton = ext->fn[0]; Func<double>* h_prev_time = ext->fn[1]; for (int i = 0; i < n; i++) { result += wt[i] * 0.5 * ( // implicit Euler part C(h_prev_newton->val[i]) * (h_prev_newton->val[i] - h_prev_time->val[i]) * v->val[i] / TAU + K(h_prev_newton->val[i]) * (h_prev_newton->dx[i] * v->dx[i] + h_prev_newton->dy[i] * v->dy[i]) - dKdh(h_prev_newton->val[i]) * h_prev_newton->dy[i] * v->val[i] ) + wt[i] * 0.5 * ( // explicit Euler part C(h_prev_time->val[i]) * (h_prev_newton->val[i] - h_prev_time->val[i]) * v->val[i] / TAU + K(h_prev_time->val[i]) * (h_prev_time->dx[i] * v->dx[i] + h_prev_time->dy[i] * v->dy[i]) - dKdh(h_prev_time->val[i]) * h_prev_time->dy[i] * v->val[i] ); } return result; }
// Jacobian matrix - surface part on bdy 6 double jac_form_surf_6_euler(int n, double *wt, Func<double> *u_ext[], Func<double> *u, Func<double> *v, Geom<double> *e, ExtData<double> *ext) { double result = 0; Func<double>* h_prev_newton = ext->fn[0]; for (int i = 0; i < n; i++) { result += wt[i] * dKdh(h_prev_newton->val[i]) * u->val[i] * v->val[i]; } return result; }
// Jacobian matrix - surface part on bdy 6 double jac_form_surf_6_cranic(int n, double *wt, Func<double> *u_ext[], Func<double> *u, Func<double> *v, Geom<double> *e, ExtData<double> *ext) { double result = 0; Func<double>* h_prev_newton = ext->fn[0]; // Just the implicit Euler contributes: for (int i = 0; i < n; i++) { result += wt[i] * 0.5 * dKdh(h_prev_newton->val[i]) * u->val[i] * v->val[i]; } return result; }
double CustomWeakFormRichardsIEPicard::CustomJacobian::value(int n, double *wt, Func<double> *u_ext[], Func<double> *u, Func<double> *v, Geom<double> *e, ExtData<double> *ext) const { double result = 0; Func<double>* h_prev_newton = u_ext[0]; Func<double>* h_prev_time = ext->fn[0]; Func<double>* h_prev_picard = ext->fn[1]; for (int i = 0; i < n; i++) { double h_prev_newton_i = h_prev_newton->val[i] - H_OFFSET; double h_prev_picard_i = h_prev_picard->val[i] - H_OFFSET; double h_prev_time_i = h_prev_time->val[i] - H_OFFSET; result += wt[i] * ( C(h_prev_picard_i) * u->val[i] * v->val[i] + K(h_prev_picard_i) * (u->dx[i] * v->dx[i] + u->dy[i] * v->dy[i]) * time_step - dKdh(h_prev_picard_i) * u->dy[i] * v->val[i] * time_step ); } return result; }