void shell_n_dot_gradp_bc(double func[DIM], double d_func[DIM][MAX_VARIABLE_TYPES + MAX_CONC][MDE], const double time, /* current time */ const double dt, /* current time step size */ double xi[DIM], /* Local stu coordinates */ const Exo_DB *exo) /*********************************************************************** * * shell_n_dot_gradp_bc(): * * Function which sets the pressure gradient at the side to be zero * * func = n .(-grad SH_FP + grad DisjPress) * * * The boundary condition SHELL_FLOW_DEVELOPED_BC employs this function. * * * Input: * * grad SH_FP = Lubrication pressure gradient * grad_DisjPress = Disjoining pressure gradient * * Output: * * func[0] = value of the function mentioned above * d_func[0][varType][lvardof] = * Derivate of func[0] wrt * the variable type, varType, and the local variable * degree of freedom, lvardof, corresponding to that * variable type. * * Author: K. Tjiptowidjojo (4/27/2011) * ********************************************************************/ { int j, ii, var; int *n_dof = NULL; int dof_map[MDE]; double grad_P[DIM]; double grad_DisjPress[DIM], dgrad_DisjPress_dH1[DIM][MDE], dgrad_DisjPress_dH2[DIM][MDE]; double phi_j; double grad_phi_j[DIM], grad_II_phi_j[DIM]; double bound_normal[DIM]; /* Save the boundary normal vector */ for(ii = 0; ii < pd->Num_Dim; ii++) { bound_normal[ii] = fv->snormal[ii]; } /* * Prepare geometry */ n_dof = (int *)array_alloc (1, MAX_VARIABLE_TYPES, sizeof(int)); lubrication_shell_initialize(n_dof, dof_map, -1, xi, exo, 0); /* Calculate pressure gradient */ Inn( fv->grad_sh_fp, grad_P ); /* Calculate disjoining pressure gradient and its sensitivities */ disjoining_pressure_model(fv->sh_fh, fv->grad_sh_fh, grad_DisjPress, dgrad_DisjPress_dH1, dgrad_DisjPress_dH2); if (af->Assemble_LSA_Mass_Matrix) { return; } if (af->Assemble_Jacobian) { var = SHELL_FILMP; if (pd->v[var]) { for ( j=0; j<ei->dof[var]; j++) { for (ii = 0; ii < pd->Num_Dim; ii++) { grad_phi_j[ii] = bf[var]->grad_phi[j][ii]; grad_II_phi_j[ii] = 0.0; } Inn(grad_phi_j, grad_II_phi_j); for (ii=0; ii<pd->Num_Dim; ii++) { d_func[0][var][j] += - grad_II_phi_j[ii] * bound_normal[ii]; } } } var = SHELL_FILMH; if (pd->v[var]) { for ( j=0; j<ei->dof[var]; j++) { phi_j = bf[var]->phi[j]; for (ii = 0; ii < pd->Num_Dim; ii++) { grad_phi_j[ii] = bf[var]->grad_phi[j][ii]; grad_II_phi_j[ii] = 0.0; } Inn(grad_phi_j, grad_II_phi_j); for (ii=0; ii<pd->Num_Dim; ii++) { d_func[0][var][j] += dgrad_DisjPress_dH1[ii][j] * grad_II_phi_j[ii] * bound_normal[ii]; d_func[0][var][j] += dgrad_DisjPress_dH2[ii][j] * phi_j * bound_normal[ii]; } } } } /* end of if Assemble_Jacobian */ /* Calculate the residual contribution */ for (ii = 0; ii < pd->Num_Dim; ii++) { func[0] += (- grad_P[ii] + grad_DisjPress[ii]) * bound_normal[ii]; } /* clean-up */ safe_free((void *) n_dof); } /* END of routine shell_n_dot_gradp_bc */
void shell_n_dot_flow_bc_confined(double func[DIM], double d_func[DIM][MAX_VARIABLE_TYPES + MAX_CONC][MDE], const double flowrate, /* imposed flow rate */ const double time, /* current time */ const double dt, /* current time step size */ double xi[DIM], /* Local stu coordinates */ const Exo_DB *exo) /*********************************************************************** * * shell_n_dot_flow_bc_confined(): * * Function which evaluates the expression specifying the * pressure gradient (or flow rate) at a quadrature point normal to the side * of an element. * * func = - flowrate + n .( H^3 /(12*mu) * (-grad LUB_P) * + 0.5 * (U_bot + U_top) * H ) * * The boundary condition GRAD_LUB_PRESS_BC employs this function. * * * Input: * * flowrate = specified on the bc card as the first float * grad LUB_P = Lubrication pressure gradient * U_top = Velocity of the top wall * U_bot = Velocity of the bottom wall * H = Distance between top and bottom wall * * Output: * * func[0] = value of the function mentioned above * d_func[0][varType][lvardof] = * Derivate of func[0] wrt * the variable type, varType, and the local variable * degree of freedom, lvardof, corresponding to that * variable type. * * * Author: K. Tjiptowidjojo (12/13/2010) * ********************************************************************/ { int j, ii, var; int *n_dof = NULL; int dof_map[MDE]; double grad_phi_j[DIM], grad_II_phi_j[DIM]; double bound_normal[DIM]; /* Save the boundary normal vector */ for(ii = 0; ii < pd->Num_Dim; ii++) { bound_normal[ii] = fv->snormal[ii]; } /* * Prepare geometry */ n_dof = (int *)array_alloc (1, MAX_VARIABLE_TYPES, sizeof(int)); lubrication_shell_initialize(n_dof, dof_map, -1, xi, exo, 0); /* Calculate the flow rate and its sensitivties */ calculate_lub_q_v(R_LUBP, time, dt, xi, exo); if (af->Assemble_LSA_Mass_Matrix) { return; } if (af->Assemble_Jacobian) { var = LUBP; if (pd->v[var]) { for ( j=0; j<ei->dof[var]; j++) { for (ii = 0; ii < pd->Num_Dim; ii++) { grad_phi_j[ii] = bf[var]->grad_phi[j][ii]; grad_II_phi_j[ii] = 0.0; } Inn(grad_phi_j, grad_II_phi_j); for (ii=0; ii<pd->Num_Dim; ii++) { d_func[0][var][j] += LubAux->dq_dp1[ii][j] * grad_II_phi_j[ii] * bound_normal[ii]; } } } } /* end of if Assemble_Jacobian */ /* Calculate the residual contribution */ func[0] = - flowrate; for (ii = 0; ii < pd->Num_Dim; ii++) { func[0] += LubAux->q[ii] * bound_normal[ii]; } /* clean-up */ safe_free((void *) n_dof); } /* END of routine shell_n_dot_flow_bc_confined */
double disjoining_pressure_model (double H, /* Film thickness or interfacial separation */ double grad_H[DIM], /* Film slope */ double grad_DisjPress[DIM], /* Disjoining pressure gradient */ double dgrad_DisjPress_dH1[DIM][MDE], /* Sensitivity of disjoining pressure w.r.t. film thickness */ double dgrad_DisjPress_dH2[DIM][MDE] ) /* Second derivative of disjoining pressure w.r.t. film thickness */ /****************************************************************************** * * A function which computes disjoining pressure inside thin film * This model is used for the lubrication capability * * Kris Tjiptowidjojo (January 26 2010) * * ******************************************************************************/ { int i, j; double DisjPress = 0.0; double grad_II_H[DIM]; double angle; double grad_angle[DIM]; double B = 0; double dB_dangle = 0; double f = 0; double df_dH = 0, d2f_dH2 = 0; double nexp; double mexp; double H_star; double factor; Inn(grad_H, grad_II_H); memset(grad_angle, 0.0, sizeof(double)*DIM); memset(grad_DisjPress, 0.0, sizeof(double)*DIM); memset(dgrad_DisjPress_dH1, 0.0, sizeof(double)*DIM*MDE); memset(dgrad_DisjPress_dH2, 0.0, sizeof(double)*DIM*MDE); /************** CALCULATE DISJOINING PRESSURE AND ITS SENSITIVITIES **************/ if(mp->DisjPressModel == CONSTANT) { B = 0.0; f = 0.0; DisjPress = mp->DisjPress; dB_dangle = 0.0; df_dH = 0.0; d2f_dH2 = 0.0; } else if(mp->DisjPressModel == TWO_TERM) { angle = mp->u_DisjPress_function_constants[0]; nexp = mp->u_DisjPress_function_constants[1]; mexp = mp->u_DisjPress_function_constants[2]; H_star = mp->u_DisjPress_function_constants[3]; factor = mp->u_DisjPress_function_constants[4]; B = (mp->surface_tension/H_star)* (nexp - 1.) * (mexp - 1.) * (1. - cos(angle * M_PIE/180.)) / ( factor * (nexp - 1.) - (mexp - 1.) ); f = pow(H_star/H, nexp) - factor * pow(H_star/H , mexp); DisjPress = B * f; dB_dangle = (mp->surface_tension/H_star)* (nexp - 1.) * (mexp - 1.) * sin(angle * M_PIE/180.) * (M_PIE/180.) / ( factor * (nexp - 1.) - (mexp - 1.) ); df_dH = - nexp * pow(H_star,nexp)/pow(H, nexp + 1.) + factor * mexp * pow(H_star, mexp)/pow(H, mexp + 1.); d2f_dH2 = nexp * (nexp + 1.) * pow(H_star,nexp)/pow(H, nexp + 2.) - factor * mexp * (mexp + 1.) * pow(H_star, mexp)/pow(H, mexp + 2.); } else if(mp->DisjPressModel == TWO_TERM_EXT_CA) { if (!(efv->ev)) { EH(-1,"Model TWO_TERM_EXT_CA requires contact angle input from external file !"); } angle = fv->external_field[0]; Inn(fv->grad_ext_field[0], grad_angle); nexp = mp->u_DisjPress_function_constants[0]; mexp = mp->u_DisjPress_function_constants[1]; H_star = mp->u_DisjPress_function_constants[2]; factor = mp->u_DisjPress_function_constants[3]; B = (mp->surface_tension/H_star)* (nexp - 1.) * (mexp - 1.) * (1. - cos(angle * M_PIE/180.)) / ( factor * (nexp - 1.) - (mexp - 1.) ); f = pow(H_star/H, nexp) - factor * pow(H_star/H , mexp); DisjPress = B * f; dB_dangle = (mp->surface_tension/H_star)* (nexp - 1.) * (mexp - 1.) * sin(angle * M_PIE/180.) * (M_PIE/180.) / ( factor * (nexp - 1.) - (mexp - 1.) ); df_dH = - nexp * pow(H_star,nexp)/pow(H, nexp + 1.) + factor * mexp * pow(H_star, mexp)/pow(H, mexp + 1.); d2f_dH2 = nexp * (nexp + 1.) * pow(H_star,nexp)/pow(H, nexp + 2.) - factor * mexp * (mexp + 1.) * pow(H_star, mexp)/pow(H, mexp + 2.); } else if(mp->DisjPressModel == ONE_TERM) { B = mp->u_DisjPress_function_constants[0]; nexp = mp->u_DisjPress_function_constants[1]; H_star = mp->u_DisjPress_function_constants[2]; f = pow( H_star/H, nexp ); DisjPress = B * f; dB_dangle = 0.0; df_dH = - nexp * pow(H_star,nexp)/pow(H, nexp + 1.); d2f_dH2 = nexp * (nexp + 1.) * pow(H_star,nexp)/pow(H, nexp + 2.); } else { EH(-1,"Not a supported disjoining pressure model"); } /************** CALCULATE DISJOINING PRESSURE GRADIENT AND ITS SENSITIVITIES **************/ for (i = 0; i < DIM; i++) { grad_DisjPress[i] = dB_dangle * f * grad_angle[i] + B * df_dH * grad_II_H[i]; } for (i = 0; i < DIM; i++) { for (j = 0; j < ei->dof[SHELL_FILMH]; j++) { dgrad_DisjPress_dH1[i][j] = B * df_dH; } } for (i = 0; i < DIM; i++) { for (j = 0; j < ei->dof[SHELL_FILMH]; j++) { dgrad_DisjPress_dH2[i][j] = dB_dangle * df_dH * grad_angle[i] + B * d2f_dH2 * grad_II_H[i] ; } } return(DisjPress); }