proteus  1.8.1
C/C++/Fortran libraries
RANS3PF2D.h
Go to the documentation of this file.
1 #ifndef RANS3PF2D_H
2 #define RANS3PF2D_H
3 #include <cmath>
4 #include <valarray>
5 #include <iostream>
6 #include <vector>
7 #include <set>
8 #include <cstring>
9 #include "CompKernel.h"
10 #include "ModelFactory.h"
11 #include "SedClosure.h"
12 #include "equivalent_polynomials.h"
13 #include "ArgumentsDict.h"
14 const double DM=0.0;//1-mesh conservation and divergence, 0 - weak div(v) only
15 const double DM2=0.0;//1-point-wise mesh volume strong-residual, 0 - div(v) only
16 const double DM3=1.0;//1-point-wise divergence, 0-point-wise rate of volume change
17 #define DRAG_FAC 1.0
18 #define TURB_FORCE_FAC 0.0
19 #define CUT_CELL_INTEGRATION 0
20 double sgn(double val) {
21  return double((0.0 < val) - (val < 0.0));
22 }
24 // ***** TODO ***** //
26 // *fix the following w.r.t. not dividing momentum eqn by rho
27 // * updateSolidParticleTerms
28 // *Double check the following w.r.t. not dividing momentum eqn by rho
29 // * updateDarcyForchheimerTerms_Ergun
30 // * updateTurbulenceClosure
31 // * check pdeResidual_p. In particular check the term with q_dvos_dt
32 // * double check exteriorNumericalAdvectiveFlux. I multiply from outside porosity*rho
33 // * MOVING MESH. Double check.
34 // * Turbulence: double check eddy_viscosity within evaluateCoefficients
35 // ***** END OF TODO *****
36 
37 #define CELL_BASED_EV_COEFF 1
38 #define POWER_SMOOTHNESS_INDICATOR 2
39 #define EPS_FOR_GAMMA_INDICATOR 1E-10
40 #define C_FOR_GAMMA_INDICATOR 0.25 // increase gamma to make the indicator more agressive (less dissipative)
41 #define USE_GAMMA_INDICATOR 0
42 #define ANISOTROPIC_DIFFUSION 0
43 
44 inline void baryCoords(const double r0[2],
45  const double r1[2],
46  const double r2[2],
47  const double r[2],
48  double* lambda)
49 {
50  double detT = (r1[1] - r2[1])*(r0[0] - r2[0]) + (r2[0] - r1[0])*(r0[1] - r2[1]);
51  lambda[0] = ((r1[1] - r2[1])*(r[0] - r2[0]) + (r2[0] - r1[0])*(r[1] - r2[1]))/detT;
52  lambda[1] = ((r2[1] - r0[1])*(r[0] - r2[0]) + (r0[0] - r2[0])*(r[1] - r2[1]))/detT;
53  lambda[2] = 1.0 - lambda[0] - lambda[1];
54 }
55 
56 namespace proteus
57 {
58  template<int nSpace, int nP, int nQ, int nEBQ>
60 
62  {
63  public:
64  std::valarray<double> TransportMatrix, TransposeTransportMatrix;
65  std::valarray<double> uStar_psi, vStar_psi, wStar_psi;
66  std::valarray<double> uStar_hi, vStar_hi, wStar_hi, den_hi;
67  std::valarray<double> uStar_min_hiHe, vStar_min_hiHe, wStar_min_hiHe;
68  std::valarray<double> uStar_gamma, vStar_gamma, wStar_gamma;
69  virtual ~cppRANS3PF2D_base() {}
70  virtual void setSedClosure(double aDarcy,
71  double betaForch,
72  double grain,
73  double packFraction,
74  double packMargin,
75  double maxFraction,
76  double frFraction,
77  double sigmaC,
78  double C3e,
79  double C4e,
80  double eR,
81  double fContact,
82  double mContact,
83  double nContact,
84  double angFriction,
85  double vos_limiter,
86  double mu_fr_limiter
87  ) {}
88  virtual void calculateResidual(arguments_dict& args,
89  bool useExact
90  )=0;
91 
92  virtual void calculateJacobian(arguments_dict& args,
93  bool useExact)=0;
94  virtual void calculateVelocityAverage(arguments_dict& args) = 0;
95  virtual void getBoundaryDOFs(arguments_dict& args)=0;
96  };
97 
98  template<class CompKernelType,
99  int nSpace,
100  int nQuadraturePoints_element,
101  int nDOF_mesh_trial_element,
102  int nDOF_trial_element,
103  int nDOF_test_element,
104  int nQuadraturePoints_elementBoundary>
106  {
107  public:
110  double C_sbm, beta_sbm;
114  CompKernelType ck;
118  nSpace2(4),
119  closure(150.0,
120  0.0,
121  0.0102,
122  0.2,
123  0.01,
124  0.635,
125  0.57,
126  1.1,
127  1.2,
128  1.0,
129  0.8,
130  0.02,
131  2.0,
132  5.0,
133  M_PI/6., 0.05, 1.00),
134  nDOF_test_X_trial_element(nDOF_test_element*nDOF_trial_element),
135  ck(),
136  C_sbm(10.0),
137  beta_sbm(0.0)
138  {/* std::cout<<"Constructing cppRANS3PF2D<CompKernelTemplate<"
139  <<0<<","
140  <<0<<","
141  <<0<<","
142  <<0<<">,"*/
143  /* <<nSpaceIn<<","
144  <<nQuadraturePoints_elementIn<<","
145  <<nDOF_mesh_trial_elementIn<<","
146  <<nDOF_trial_elementIn<<","
147  <<nDOF_test_elementIn<<","
148  <<nQuadraturePoints_elementBoundaryIn<<">());"*/
149  /* <<std::endl<<std::flush; */
150  }
151 
152  void setSedClosure(double aDarcy,
153  double betaForch,
154  double grain,
155  double packFraction,
156  double packMargin,
157  double maxFraction,
158  double frFraction,
159  double sigmaC,
160  double C3e,
161  double C4e,
162  double eR,
163  double fContact,
164  double mContact,
165  double nContact,
166  double angFriction,
167  double vos_limiter,
168  double mu_fr_limiter)
169  {
170  closure = cppHsuSedStress<2>(aDarcy,
171  betaForch,
172  grain,
173  packFraction,
174  packMargin,
175  maxFraction,
176  frFraction,
177  sigmaC,
178  C3e,
179  C4e,
180  eR,
181  fContact,
182  mContact,
183  nContact,
184  angFriction,
185  vos_limiter,
186  mu_fr_limiter);
187  }
188 
189  inline double Dot(const double vec1[nSpace],
190  const double vec2[nSpace])
191  {
192  double dot = 0;
193  for (int I=0; I<nSpace; I++)
194  dot += vec1[I]*vec2[I];
195  return dot;
196  }
197 
198  inline void calculateTangentialGradient(const double normal[nSpace],
199  const double vel_grad[nSpace],
200  double vel_tgrad[nSpace])
201  {
202  double normal_dot_vel_grad = Dot(normal,vel_grad);
203  for (int I=0; I<nSpace; I++)
204  vel_tgrad[I] = vel_grad[I] - normal_dot_vel_grad*normal[I];
205  }
206 
207  inline
208  void evaluateCoefficients(const double eps_rho,
209  const double eps_mu,
210  const double eps_s,
211  const double sigma,
212  const double rho_0,
213  double nu_0,
214  const double rho_1,
215  double nu_1,
216  const double h_e,
217  const double smagorinskyConstant,
218  const int turbulenceClosureModel,
219  const double g[nSpace],
220  const double useVF,
221  const double& vf,
222  const double& phi,
223  const double n[nSpace],
224  const double distance_to_omega_solid,
225  const double& kappa,
226  const double porosity,//VRANS specific
227  const double& p,
228  const double grad_p[nSpace],
229  const double grad_u[nSpace],
230  const double grad_v[nSpace],
231  const double grad_w[nSpace],
232  const double& u,
233  const double& v,
234  const double& w,
235  const double& uStar,
236  const double& vStar,
237  const double& wStar,
238  double& eddy_viscosity,
239  double& mom_u_acc,
240  double& dmom_u_acc_u,
241  double& mom_v_acc,
242  double& dmom_v_acc_v,
243  double& mom_w_acc,
244  double& dmom_w_acc_w,
245  double mass_adv[nSpace],
246  double dmass_adv_u[nSpace],
247  double dmass_adv_v[nSpace],
248  double dmass_adv_w[nSpace],
249  double mom_u_adv[nSpace],
250  double dmom_u_adv_u[nSpace],
251  double dmom_u_adv_v[nSpace],
252  double dmom_u_adv_w[nSpace],
253  double mom_v_adv[nSpace],
254  double dmom_v_adv_u[nSpace],
255  double dmom_v_adv_v[nSpace],
256  double dmom_v_adv_w[nSpace],
257  double mom_w_adv[nSpace],
258  double dmom_w_adv_u[nSpace],
259  double dmom_w_adv_v[nSpace],
260  double dmom_w_adv_w[nSpace],
261  double mom_uu_diff_ten[nSpace],
262  double mom_vv_diff_ten[nSpace],
263  double mom_ww_diff_ten[nSpace],
264  double mom_uv_diff_ten[1],
265  double mom_uw_diff_ten[1],
266  double mom_vu_diff_ten[1],
267  double mom_vw_diff_ten[1],
268  double mom_wu_diff_ten[1],
269  double mom_wv_diff_ten[1],
270  double& mom_u_source,
271  double& mom_v_source,
272  double& mom_w_source,
273  double& mom_u_ham,
274  double dmom_u_ham_grad_p[nSpace],
275  double dmom_u_ham_grad_u[nSpace],
276  double& mom_v_ham,
277  double dmom_v_ham_grad_p[nSpace],
278  double dmom_v_ham_grad_v[nSpace],
279  double& mom_w_ham,
280  double dmom_w_ham_grad_p[nSpace],
281  double dmom_w_ham_grad_w[nSpace],
282  double& rhoSave,
283  double& nuSave,
284  int KILL_PRESSURE_TERM,
285  int MULTIPLY_EXTERNAL_FORCE_BY_DENSITY,
286  double forcex,
287  double forcey,
288  double forcez,
289  int MATERIAL_PARAMETERS_AS_FUNCTION,
290  double density_as_function,
291  double dynamic_viscosity_as_function,
292  int USE_SBM,
293  double x, double y, double z,
294  int use_ball_as_particle,
295  double* ball_center,
296  double* ball_radius,
297  double* ball_velocity,
298  double* ball_angular_velocity,
299  // int by parts pressure
300  int INT_BY_PARTS_PRESSURE)
301  {
302  double rho,nu,mu,H_rho,ImH_rho,d_rho,H_mu,ImH_mu,d_mu,norm_n,nu_t0=0.0,nu_t1=0.0,nu_t;
303  H_rho = (1.0-useVF)*gf.H(eps_rho,phi) + useVF*fmin(1.0,fmax(0.0,vf));
304  ImH_rho = (1.0-useVF)*gf.ImH(eps_rho,phi) + useVF*(1.0-fmin(1.0,fmax(0.0,vf)));
305  d_rho = (1.0-useVF)*gf.D(eps_rho,phi);
306  H_mu = (1.0-useVF)*gf.H(eps_mu,phi) + useVF*fmin(1.0,fmax(0.0,vf));
307  ImH_mu = (1.0-useVF)*gf.ImH(eps_mu,phi) + useVF*(1.0-fmin(1.0,fmax(0.0,vf)));
308  d_mu = (1.0-useVF)*gf.D(eps_mu,phi);
309 
310  //calculate eddy viscosity
311  switch (turbulenceClosureModel)
312  {
313  double norm_S;
314  case 1:
315  {
316  norm_S = sqrt(2.0*(grad_u[0]*grad_u[0] + grad_v[1]*grad_v[1] + //grad_w[2]*grad_w[2] +
317  0.5*(grad_u[1]+grad_v[0])*(grad_u[1]+grad_v[0])));
318 
319  nu_t0 = smagorinskyConstant*smagorinskyConstant*h_e*h_e*norm_S;
320  nu_t1 = smagorinskyConstant*smagorinskyConstant*h_e*h_e*norm_S;
321  }
322  case 2:
323  {
324  double re_0,cs_0=0.0,re_1,cs_1=0.0;
325  norm_S = sqrt(2.0*(grad_u[0]*grad_u[0] + grad_v[1]*grad_v[1] +//grad_w[2]*grad_w[2] +
326  0.5*(grad_u[1]+grad_v[0])*(grad_u[1]+grad_v[0])));
327  re_0 = h_e*h_e*norm_S/nu_0;
328  if (re_0 > 1.0)
329  cs_0=0.027*pow(10.0,-3.23*pow(re_0,-0.92));
330  nu_t0 = cs_0*h_e*h_e*norm_S;
331  re_1 = h_e*h_e*norm_S/nu_1;
332  if (re_1 > 1.0)
333  cs_1=0.027*pow(10.0,-3.23*pow(re_1,-0.92));
334  nu_t1 = cs_1*h_e*h_e*norm_S;
335  }
336  }
337 
338  if (MATERIAL_PARAMETERS_AS_FUNCTION==0)
339  {
340  rho = rho_0*ImH_rho+rho_1*H_rho;
341  nu_t= nu_t0*ImH_mu+nu_t1*H_mu;
342  nu = nu_0*ImH_mu+nu_1*H_mu;
343  nu += nu_t;
344  mu = rho_0*nu_0*ImH_mu+rho_1*nu_1*H_mu;
345  }
346  else // set the material parameters by a function. To check convergence
347  {
348  rho = density_as_function;
349  nu_t= 0;
350  mu = dynamic_viscosity_as_function;
351  nu = mu/rho;
352  }
353 
354  rhoSave = rho;
355  nuSave = nu;
356 
357  eddy_viscosity = nu_t*rho; // mql. CHECK. Most changes about not divide by rho are here
358  // mass (volume accumulation)
359  //..hardwired
360 
361  double phi_s_effect = (distance_to_omega_solid > 0.0) ? 1.0 : 1e-10;
362 
363  if(USE_SBM>0)
364  phi_s_effect = 1.0;
365  //u momentum accumulation
366  mom_u_acc=u;//trick for non-conservative form
367  dmom_u_acc_u=phi_s_effect * rho*porosity;
368 
369  //v momentum accumulation
370  mom_v_acc=v;
371  dmom_v_acc_v=phi_s_effect * rho*porosity;
372 
373  /* //w momentum accumulation */
374  /* mom_w_acc=phi_s_effect*w; */
375  /* dmom_w_acc_w=phi_s_effect*rho*porosity; */
376 
377  //mass advective flux
378  mass_adv[0]=phi_s_effect * porosity*u;
379  mass_adv[1]=phi_s_effect * porosity*v;
380  /* mass_adv[2]=phi_s_effect * porosity*w; */
381 
382  dmass_adv_u[0]=phi_s_effect * porosity;
383  dmass_adv_u[1]=0.0;
384  /* dmass_adv_u[2]=0.0; */
385 
386  dmass_adv_v[0]=0.0;
387  dmass_adv_v[1]=phi_s_effect * porosity;
388  /* dmass_adv_v[2]=0.0; */
389 
390  /* dmass_adv_w[0]=0.0; */
391  /* dmass_adv_w[1]=0.0; */
392  /* dmass_adv_w[2]=phi_s_effect * porosity; */
393 
394  //advection switched to non-conservative form but could be used for mesh motion...
395  //u momentum advective flux
396  mom_u_adv[0]=0.0;
397  mom_u_adv[1]=0.0;
398  /* mom_u_adv[2]=0.0; */
399 
400  dmom_u_adv_u[0]=0.0;
401  dmom_u_adv_u[1]=0.0;
402  /* dmom_u_adv_u[2]=0.0; */
403 
404  dmom_u_adv_v[0]=0.0;
405  dmom_u_adv_v[1]=0.0;
406  /* dmom_u_adv_v[2]=0.0; */
407 
408  /* dmom_u_adv_w[0]=0.0; */
409  /* dmom_u_adv_w[1]=0.0; */
410  /* dmom_u_adv_w[2]=0.0; */
411 
412  //v momentum advective_flux
413  mom_v_adv[0]=0.0;
414  mom_v_adv[1]=0.0;
415  /* mom_v_adv[2]=0.0; */
416 
417  dmom_v_adv_u[0]=0.0;
418  dmom_v_adv_u[1]=0.0;
419  /* dmom_v_adv_u[2]=0.0; */
420 
421  /* dmom_v_adv_w[0]=0.0; */
422  /* dmom_v_adv_w[1]=0.0; */
423  /* dmom_v_adv_w[2]=0.0; */
424 
425  dmom_v_adv_v[0]=0.0;
426  dmom_v_adv_v[1]=0.0;
427  /* dmom_v_adv_v[2]=0.0; */
428 
429  /* //w momentum advective_flux */
430  /* mom_w_adv[0]=0.0; */
431  /* mom_w_adv[1]=0.0; */
432  /* mom_w_adv[2]=0.0; */
433 
434  /* dmom_w_adv_u[0]=0.0; */
435  /* dmom_w_adv_u[1]=0.0; */
436  /* dmom_w_adv_u[2]=0.0; */
437 
438  /* dmom_w_adv_v[0]=0.0; */
439  /* dmom_w_adv_v[1]=0.0; */
440  /* dmom_w_adv_v[2]=0.0; */
441 
442  /* dmom_w_adv_w[0]=0.0; */
443  /* dmom_w_adv_w[1]=0.0; */
444  /* dmom_w_adv_w[2]=0.0; */
445 
446  //u momentum diffusion tensor
447  mom_uu_diff_ten[0] = phi_s_effect * porosity*2.0*mu;
448  mom_uu_diff_ten[1] = phi_s_effect * porosity*mu;
449  /* mom_uu_diff_ten[2] = phi_s_effect * porosity*mu; */
450 
451  mom_uv_diff_ten[0]=phi_s_effect * porosity*mu;
452 
453  /* mom_uw_diff_ten[0]=phi_s_effect * porosity*mu; */
454 
455  //v momentum diffusion tensor
456  mom_vv_diff_ten[0] = phi_s_effect * porosity*mu;
457  mom_vv_diff_ten[1] = phi_s_effect * porosity*2.0*mu;
458  /* mom_vv_diff_ten[2] = phi_s_effect * porosity*mu; */
459 
460  mom_vu_diff_ten[0]=phi_s_effect * porosity*mu;
461 
462  /* mom_vw_diff_ten[0]=phi_s_effect * porosity*mu; */
463 
464  /* //w momentum diffusion tensor */
465  /* mom_ww_diff_ten[0] = phi_s_effect * porosity*mu; */
466  /* mom_ww_diff_ten[1] = phi_s_effect * porosity*mu; */
467  /* mom_ww_diff_ten[2] = phi_s_effect * porosity*2.0*mu; */
468 
469  /* mom_wu_diff_ten[0]=phi_s_effect * porosity*mu; */
470 
471  /* mom_wv_diff_ten[0]=phi_s_effect * orosity*mu; */
472 
473  //momentum sources
474  norm_n = sqrt(n[0]*n[0]+n[1]*n[1]);//+n[2]*n[2]);
475  mom_u_source = -phi_s_effect * porosity*rho*g[0];// - porosity*d_mu*sigma*kappa*n[0]/(rho*(norm_n+1.0e-8));
476  mom_v_source = -phi_s_effect * porosity*rho*g[1];// - porosity*d_mu*sigma*kappa*n[1]/(rho*(norm_n+1.0e-8));
477  /* mom_w_source = -porosity*rho*g[2];// - porosity*d_mu*sigma*kappa*n[2]/(rho*(norm_n+1.0e-8)); */
478 
479  // mql: add general force term
480  mom_u_source -= (MULTIPLY_EXTERNAL_FORCE_BY_DENSITY == 1 ? porosity*rho : 1.0)*forcex;
481  mom_v_source -= (MULTIPLY_EXTERNAL_FORCE_BY_DENSITY == 1 ? porosity*rho : 1.0)*forcey;
482  /* mom_w_source -= forcez; */
483 
484  //u momentum Hamiltonian (pressure)
485  double aux_pressure = (KILL_PRESSURE_TERM==1 ? 0. : 1.)*(INT_BY_PARTS_PRESSURE==1 ? 0. : 1.);
486  mom_u_ham = phi_s_effect * porosity*grad_p[0]*aux_pressure;
487  dmom_u_ham_grad_p[0]=phi_s_effect * porosity*aux_pressure;
488  dmom_u_ham_grad_p[1]=0.0;
489  /* dmom_u_ham_grad_p[2]=0.0; */
490 
491  //v momentum Hamiltonian (pressure)
492  mom_v_ham = phi_s_effect * porosity*grad_p[1]*aux_pressure;
493  dmom_v_ham_grad_p[0]=0.0;
494  dmom_v_ham_grad_p[1]=phi_s_effect * porosity*aux_pressure;
495  /* dmom_v_ham_grad_p[2]=0.0; */
496 
497  /* //w momentum Hamiltonian (pressure) */
498  /* mom_w_ham = porosity*grad_p[2]; */
499  /* dmom_w_ham_grad_p[0]=0.0; */
500  /* dmom_w_ham_grad_p[1]=0.0; */
501  /* dmom_w_ham_grad_p[2]=porosity; */
502 
503  //u momentum Hamiltonian (advection)
504  mom_u_ham += phi_s_effect * porosity*rho*(uStar*grad_u[0]+vStar*grad_u[1]);
505  dmom_u_ham_grad_u[0]=phi_s_effect * porosity*rho*uStar;
506  dmom_u_ham_grad_u[1]=phi_s_effect * porosity*rho*vStar;
507  /* dmom_u_ham_grad_u[2]=porosity*rho*wStar; */
508 
509  //v momentum Hamiltonian (advection)
510  mom_v_ham += phi_s_effect * porosity*rho*(uStar*grad_v[0]+vStar*grad_v[1]);
511  dmom_v_ham_grad_v[0]=phi_s_effect * porosity*rho*uStar;
512  dmom_v_ham_grad_v[1]=phi_s_effect * porosity*rho*vStar;
513  /* dmom_v_ham_grad_v[2]=porosity*rho*wStar; */
514 
515  /* //w momentum Hamiltonian (advection) */
516  /* mom_w_ham += porosity*rho*(uStar*grad_w[0]+vStar*grad_w[1]+wStar*grad_w[2]); */
517  /* dmom_w_ham_grad_w[0]=porosity*rho*uStar; */
518  /* dmom_w_ham_grad_w[1]=porosity*rho*vStar; */
519  /* dmom_w_ham_grad_w[2]=porosity*rho*wStar; */
520  }
521 
522  //VRANS specific
523  inline
524  void updateDarcyForchheimerTerms_Ergun(/* const double linearDragFactor, */
525  /* const double nonlinearDragFactor, */
526  /* const double porosity, */
527  /* const double meanGrainSize, */
528  const double alpha,
529  const double beta,
530  const double eps_rho,
531  const double eps_mu,
532  const double rho_0,
533  const double nu_0,
534  const double rho_1,
535  const double nu_1,
536  double nu_t,
537  const double useVF,
538  const double vf,
539  const double phi,
540  const double u,
541  const double v,
542  const double w,
543  const double uStar,
544  const double vStar,
545  const double wStar,
546  const double eps_s,
547  const double phi_s,
548  const double u_s,
549  const double v_s,
550  const double w_s,
551  const double uStar_s,
552  const double vStar_s,
553  const double wStar_s,
554  double& mom_u_source,
555  double& mom_v_source,
556  double& mom_w_source,
557  double dmom_u_source[nSpace],
558  double dmom_v_source[nSpace],
559  double dmom_w_source[nSpace],
560  double gradC_x,
561  double gradC_y,
562  double gradC_z)
563  {
564  double rho, mu,nu,H_mu,ImH_mu,uc,duc_du,duc_dv,duc_dw,viscosity,H_s;
565  H_mu = (1.0-useVF)*gf.H(eps_mu,phi)+useVF*fmin(1.0,fmax(0.0,vf));
566  ImH_mu = (1.0-useVF)*gf.ImH(eps_mu,phi)+useVF*(1.0-fmin(1.0,fmax(0.0,vf)));
567  nu = nu_0*ImH_mu+nu_1*H_mu;
568  rho = rho_0*ImH_mu+rho_1*H_mu;
569  mu = rho_0*nu_0*ImH_mu+rho_1*nu_1*H_mu;
570  viscosity = nu;
571  uc = sqrt(u*u+v*v*+w*w);
572  duc_du = u/(uc+1.0e-12);
573  duc_dv = v/(uc+1.0e-12);
574  duc_dw = w/(uc+1.0e-12);
575  double fluid_velocity[2]={uStar,vStar}, solid_velocity[2]={uStar_s,vStar_s};
576  double new_beta = closure.betaCoeff(1.0-phi_s,
577  rho,
578  fluid_velocity,
579  solid_velocity,
580  viscosity)*DRAG_FAC;
581  //new_beta = 254800.0;//hack fall velocity of 0.1 with no pressure gradient
582  double beta2 = 156976.4;//hack, fall velocity of 0.1 with hydrostatic water
583 
584  mom_u_source += (1.0 - phi_s) * new_beta * (u - u_s) - TURB_FORCE_FAC*new_beta*nu_t*gradC_x/closure.sigmaC_ +
585  (1.0 - phi_s)*(1.0-DRAG_FAC)*beta2*(u-u_s);
586  mom_v_source += (1.0 - phi_s) * new_beta * (v - v_s) - TURB_FORCE_FAC*new_beta*nu_t*gradC_y/closure.sigmaC_ +
587  (1.0 - phi_s)*(1.0-DRAG_FAC)*beta2*(v-v_s);
588 
589  /* mom_w_source += phi_s*new_beta*(w-w_s); */
590 
591  dmom_u_source[0] = (1.0 - phi_s) * new_beta + (1.0 - phi_s)*(1.0-DRAG_FAC)*beta2;
592  dmom_u_source[1] = 0.0;
593  /* dmom_u_source[2] = 0.0; */
594 
595  dmom_v_source[0] = 0.0;
596  dmom_v_source[1] = (1.0 - phi_s) * new_beta + (1.0 - phi_s)*(1.0-DRAG_FAC)*beta2;
597  /*dmom_v_source[2] = 0.0; */
598 
599  dmom_w_source[0] = 0.0;
600  dmom_w_source[1] = 0.0;
601  /*dmom_w_source[2] = (1.0 - phi_s) * new_beta; */
602  }
603 
604  inline void updateSolidParticleTerms(bool element_owned,
605  const double particle_nitsche,
606  const double dV,
607  const int nParticles,
608  const int sd_offset,
609  double *particle_signed_distances,
610  double *particle_signed_distance_normals,
611  double *particle_velocities,
612  double *particle_centroids,
613  int use_ball_as_particle,
614  double* ball_center,
615  double* ball_radius,
616  double* ball_velocity,
617  double* ball_angular_velocity,
618  const double porosity, //VRANS specific
619  const double penalty,
620  const double alpha,
621  const double beta,
622  const double eps_rho,
623  const double eps_mu,
624  const double rho_0,
625  const double nu_0,
626  const double rho_1,
627  const double nu_1,
628  const double useVF,
629  const double vf,
630  const double phi,
631  const double x,
632  const double y,
633  const double z,
634  const double p,
635  const double u,
636  const double v,
637  const double w,
638  const double uStar,
639  const double vStar,
640  const double wStar,
641  const double eps_s,
642  const double grad_u[nSpace],
643  const double grad_v[nSpace],
644  const double grad_w[nSpace],
645  double &mom_u_source,
646  double &mom_v_source,
647  double &mom_w_source,
648  double dmom_u_source[nSpace],
649  double dmom_v_source[nSpace],
650  double dmom_w_source[nSpace],
651  double mom_u_adv[nSpace],
652  double mom_v_adv[nSpace],
653  double mom_w_adv[nSpace],
654  double dmom_u_adv_u[nSpace],
655  double dmom_v_adv_v[nSpace],
656  double dmom_w_adv_w[nSpace],
657  double &mom_u_ham,
658  double dmom_u_ham_grad_u[nSpace],
659  double &mom_v_ham,
660  double dmom_v_ham_grad_v[nSpace],
661  double &mom_w_ham,
662  double dmom_w_ham_grad_w[nSpace],
663  double *particle_netForces,
664  double *particle_netMoments,
665  double *particle_surfaceArea)
666  {
667  double C, rho, mu, nu, H_mu, ImH_mu, uc, duc_du, duc_dv, duc_dw, H_s, D_s, phi_s, u_s, v_s, w_s;
668  double force_x, force_y, r_x, r_y, force_p_x, force_p_y, force_stress_x, force_stress_y;
669  double phi_s_normal[2]={0.0};
670  double fluid_outward_normal[2];
671  double vel[2];
672  double center[2];
673  H_mu = (1.0 - useVF) * gf.H(eps_mu, phi) + useVF * fmin(1.0, fmax(0.0, vf));
674  ImH_mu = (1.0 - useVF) * gf.ImH(eps_mu, phi) + useVF * (1.0-fmin(1.0, fmax(0.0, vf)));
675  nu = nu_0 * ImH_mu + nu_1 * H_mu;
676  rho = rho_0 * ImH_mu + rho_1 * H_mu;
677  mu = rho_0 * nu_0 * ImH_mu + rho_1 * nu_1 * H_mu;
678  C = 0.0;
679  for (int i = 0; i < nParticles; i++)
680  {
681  double* vel_pointer= &particle_velocities[i*sd_offset*nSpace];
682  if(use_ball_as_particle==1)
683  {
684  get_distance_to_ith_ball(nParticles,ball_center,ball_radius,i,x,y,z,phi_s);
685  get_normal_to_ith_ball(nParticles,ball_center,ball_radius,i,x,y,z,phi_s_normal[0],phi_s_normal[1]);
686  get_velocity_to_ith_ball(nParticles,ball_center,ball_radius,
687  ball_velocity,ball_angular_velocity,
688  i,x,y,z,
689  vel[0],vel[1]);
690  center[0] = ball_center[3*i+0];
691  center[1] = ball_center[3*i+1];
692  u_s = vel[0];
693  v_s = vel[1];
694  }
695  else
696  {
697  phi_s = particle_signed_distances[i * sd_offset];
698  phi_s_normal[0] = particle_signed_distance_normals[i * sd_offset * 3 + 0];
699  phi_s_normal[1] = particle_signed_distance_normals[i * sd_offset * 3 + 1];
700  vel[0] = particle_velocities[i * sd_offset * 3 + 0];
701  vel[1] = particle_velocities[i * sd_offset * 3 + 1];
702  u_s = vel_pointer[0];
703  v_s = vel_pointer[1];
704  center[0] = particle_centroids[3*i+0];
705  center[1] = particle_centroids[3*i+1];
706 
707  }
708  fluid_outward_normal[0] = -phi_s_normal[0];
709  fluid_outward_normal[1] = -phi_s_normal[1];
710 
711  w_s = 0;
712  H_s = gf_s.H(eps_s, phi_s);
713  D_s = gf_s.D(eps_s, phi_s);
714  double rel_vel_norm = sqrt((uStar - u_s) * (uStar - u_s) +
715  (vStar - v_s) * (vStar - v_s) +
716  (wStar - w_s) * (wStar - w_s));
717 
718  // double C_surf = (phi_s > 0.0) ? 0.0 : nu * penalty;
719  //double C_vol = (phi_s > 0.0) ? 0.0 : (alpha + beta * rel_vel_norm);
720  double C_surf = mu * penalty;
721  double C_vol = (alpha + beta * rel_vel_norm);
722 
723  C = (D_s * C_surf + gf_s.ImH(eps_s, phi_s) * C_vol);
724  force_x = dV * D_s * (p * fluid_outward_normal[0]
725  - porosity*mu*(fluid_outward_normal[0] * 2* grad_u[0] +
726  fluid_outward_normal[1] * (grad_u[1]+grad_v[0]))
727  +C_surf*(u-u_s)*rho
728  );
729  force_y = dV * D_s * (p * fluid_outward_normal[1]
730  - porosity*mu * (fluid_outward_normal[0] * (grad_u[1]+grad_v[0]) +
731  fluid_outward_normal[1] * 2* grad_v[1])
732  +C_surf*(v-v_s)*rho
733  );
734  force_p_x = dV * D_s * p * fluid_outward_normal[0];
735  force_p_y = dV * D_s * p * fluid_outward_normal[1];
736  force_stress_x = dV * D_s * (-porosity*mu * (fluid_outward_normal[0] * 2* grad_u[0] +
737  fluid_outward_normal[1] * (grad_u[1]+grad_v[0]))
738  +C_surf*(u-u_s)*rho
739  );
740  force_stress_y = dV * D_s * (-porosity*mu * (fluid_outward_normal[0] * (grad_u[1]+grad_v[0]) +
741  fluid_outward_normal[1] * 2* grad_v[1])
742  +C_surf*(v-v_s)*rho
743  );
744  //always 3D for particle centroids
745  r_x = x - center[0];
746  r_y = y - center[1];
747 
748  if (element_owned)
749  {
750  particle_surfaceArea[i] += dV * D_s;
751  particle_netForces[i * 3 + 0] += force_x;
752  particle_netForces[i * 3 + 1] += force_y;
753  particle_netForces[(i+ nParticles)*3+0]+= force_p_x;
754  particle_netForces[(i+2*nParticles)*3+0]+= force_stress_x;
755  particle_netForces[(i+ nParticles)*3+1]+= force_p_y;
756  particle_netForces[(i+2*nParticles)*3+1]+= force_stress_y;
757  particle_netMoments[i * 3 + 2] += (r_x * force_y - r_y * force_x);
758  }
759 
760  // These should be done inside to make sure the correct velocity of different particles are used
761  mom_u_source += C * (u - u_s);
762  mom_v_source += C * (v - v_s);
763 
764  dmom_u_source[0] += C;
765  dmom_v_source[1] += C;
766 
767  //Nitsche terms
768  mom_u_ham -= D_s * porosity * mu * (fluid_outward_normal[0] * grad_u[0] + fluid_outward_normal[1] * grad_u[1]);
769  dmom_u_ham_grad_u[0] -= D_s * porosity * mu * fluid_outward_normal[0];
770  dmom_u_ham_grad_u[1] -= D_s * porosity * mu * fluid_outward_normal[1];
771 
772  mom_v_ham -= D_s * porosity * mu * (fluid_outward_normal[0] * grad_v[0] + fluid_outward_normal[1] * grad_v[1]);
773  dmom_v_ham_grad_v[0] -= D_s * porosity * mu * fluid_outward_normal[0];
774  dmom_v_ham_grad_v[1] -= D_s * porosity * mu * fluid_outward_normal[1];
775 
776  mom_u_adv[0] += D_s * porosity * mu * fluid_outward_normal[0] * (u - u_s);
777  mom_u_adv[1] += D_s * porosity * mu * fluid_outward_normal[1] * (u - u_s);
778  dmom_u_adv_u[0] += D_s * porosity * mu * fluid_outward_normal[0];
779  dmom_u_adv_u[1] += D_s * porosity * mu * fluid_outward_normal[1];
780 
781  mom_v_adv[0] += D_s * porosity * mu * fluid_outward_normal[0] * (v - v_s);
782  mom_v_adv[1] += D_s * porosity * mu * fluid_outward_normal[1] * (v - v_s);
783  dmom_v_adv_v[0] += D_s * porosity * mu * fluid_outward_normal[0];
784  dmom_v_adv_v[1] += D_s * porosity * mu * fluid_outward_normal[1];
785  }
786  }
787  inline void compute_force_around_solid(bool element_owned,
788  const double dV,
789  const int nParticles,
790  const int sd_offset,
791  double *particle_signed_distances,
792  double *particle_signed_distance_normals,
793  double *particle_velocities,
794  double *particle_centroids,
795  int use_ball_as_particle,
796  double* ball_center,
797  double* ball_radius,
798  double* ball_velocity,
799  double* ball_angular_velocity,
800  const double penalty,
801  const double alpha,
802  const double beta,
803  const double eps_rho,
804  const double eps_mu,
805  const double rho_0,
806  const double nu_0,
807  const double rho_1,
808  const double nu_1,
809  const double useVF,
810  const double vf,
811  const double phi,
812  const double x,
813  const double y,
814  const double z,
815  const double p,
816  const double u,
817  const double v,
818  const double w,
819  const double uStar,
820  const double vStar,
821  const double wStar,
822  const double eps_s,
823  const double grad_u[nSpace],
824  const double grad_v[nSpace],
825  const double grad_w[nSpace],
826  double* particle_netForces,
827  double* particle_netMoments)
828  {
829  double C, rho, mu, nu, H_mu, ImH_mu, uc, duc_du, duc_dv, duc_dw, H_s, D_s, phi_s, u_s, v_s, w_s, force_x, force_y, r_x, r_y;
830  double phi_s_normal[2];
831  double fluid_outward_normal[2];
832  double vel[2];
833  double center[2];
834  H_mu = (1.0 - useVF) * gf.H(eps_mu, phi) + useVF * fmin(1.0, fmax(0.0, vf));
835  ImH_mu = (1.0 - useVF) * gf.ImH(eps_mu, phi) + useVF * (1.0-fmin(1.0, fmax(0.0, vf)));
836  nu = nu_0 * ImH_mu + nu_1 * H_mu;
837  rho = rho_0 * ImH_mu + rho_1 * H_mu;
838  mu = rho_0 * nu_0 * ImH_mu + rho_1 * nu_1 * H_mu;
839  C = 0.0;
840  for (int i = 0; i < nParticles; i++)
841  {
842  if(use_ball_as_particle==1)
843  {
844  get_distance_to_ith_ball(nParticles,ball_center,ball_radius,i,x,y,z,phi_s);
845  get_normal_to_ith_ball(nParticles,ball_center,ball_radius,i,x,y,z,phi_s_normal[0],phi_s_normal[1]);
846  get_velocity_to_ith_ball(nParticles,ball_center,ball_radius,
847  ball_velocity,ball_angular_velocity,
848  i,x,y,z,
849  vel[0],vel[1]);
850  center[0] = ball_center[3*i+0];
851  center[1] = ball_center[3*i+1];
852  }
853  else
854  {
855  phi_s = particle_signed_distances[i * sd_offset];
856  phi_s_normal[0] = particle_signed_distance_normals[i * sd_offset * 3 + 0];
857  phi_s_normal[1] = particle_signed_distance_normals[i * sd_offset * 3 + 1];
858  vel[0] = particle_velocities[i * sd_offset * 3 + 0];
859  vel[1] = particle_velocities[i * sd_offset * 3 + 1];
860  center[0] = particle_centroids[3*i+0];
861  center[1] = particle_centroids[3*i+1];
862 
863  }
864  fluid_outward_normal[0] = -phi_s_normal[0];
865  fluid_outward_normal[1] = -phi_s_normal[1];
866  u_s = vel[0];
867  v_s = vel[1];
868  w_s = 0;
869  H_s = gf_s.H(eps_s, phi_s);
870  D_s = gf_s.D(eps_s, phi_s);
871  double rel_vel_norm = sqrt((uStar - u_s) * (uStar - u_s) +(vStar - v_s) * (vStar - v_s) + (wStar - w_s) * (wStar - w_s));
872  double C_surf = (phi_s > 0.0) ? 0.0 : nu * penalty;
873  double C_vol = (phi_s > 0.0) ? 0.0 : (alpha + beta * rel_vel_norm);
874 
875  C = (D_s * C_surf + gf_s.ImH(eps_s, phi_s) * C_vol);
876  force_x = dV * D_s * (p * fluid_outward_normal[0]
877  -mu * (fluid_outward_normal[0] * 2* grad_u[0] + fluid_outward_normal[1] * (grad_u[1]+grad_v[0]))
878  );
879  //+dV*D_s*C_surf*rel_vel_norm*(u-u_s)*rho
880  //+dV * (1.0 - H_s) * C_vol * (u - u_s) * rho;
881  force_y = dV * D_s * (p * fluid_outward_normal[1]
882  -mu * (fluid_outward_normal[0] * (grad_u[1]+grad_v[0]) + fluid_outward_normal[1] * 2* grad_v[1])
883  );
884  //+dV*D_s*C_surf*rel_vel_norm*(v-v_s)*rho
885  //+dV * (1.0 - H_s) * C_vol * (v - v_s) * rho;
886 
887  //always 3D for particle centroids
888  r_x = x - center[0];
889  r_y = y - center[1];
890 
891  if (element_owned)
892  {
893  particle_netForces[i * 3 + 0] += force_x;
894  particle_netForces[i * 3 + 1] += force_y;
895  particle_netMoments[i * 3 + 2] += (r_x * force_y - r_y * force_x);
896  }
897  }
898  }
899  inline
900  void calculateCFL(const double& hFactor,
901  const double& elementDiameter,
902  const double& dm,
903  const double df[nSpace],
904  double& cfl)
905  {
906  double h,density,nrm_df=0.0;
907  h = hFactor*elementDiameter;
908  density = dm;
909  for(int I=0;I<nSpace;I++)
910  nrm_df+=df[I]*df[I];
911  nrm_df = sqrt(nrm_df);
912  if (density > 1.0e-8)
913  cfl = nrm_df/(h*density);//this is really cfl/dt, but that's what we want to know, the step controller expect this
914  else
915  cfl = nrm_df/h;
916  //cfl = nrm_df/(h*density);//this is really cfl/dt, but that's what we want to know, the step controller expect this
917  }
918 
919  inline void updateTurbulenceClosure(const int turbulenceClosureModel,
920  const double eps_rho,
921  const double eps_mu,
922  const double rho_0,
923  const double nu_0,
924  const double rho_1,
925  const double nu_1,
926  const double useVF,
927  const double vf,
928  const double phi,
929  const double porosity,
930  const double eddy_visc_coef_0,
931  const double turb_var_0, //k for k-eps or k-omega
932  const double turb_var_1, //epsilon for k-epsilon, omega for k-omega
933  const double turb_grad_0[nSpace], //grad k for k-eps,k-omega
934  double &eddy_viscosity,
935  double mom_uu_diff_ten[nSpace],
936  double mom_vv_diff_ten[nSpace],
937  double mom_ww_diff_ten[nSpace],
938  double mom_uv_diff_ten[1],
939  double mom_uw_diff_ten[1],
940  double mom_vu_diff_ten[1],
941  double mom_vw_diff_ten[1],
942  double mom_wu_diff_ten[1],
943  double mom_wv_diff_ten[1],
944  double &mom_u_source,
945  double &mom_v_source,
946  double &mom_w_source)
947  {
948  /****
949  eddy_visc_coef
950  <= 2 LES (do nothing)
951  == 3 k-epsilon
952 
953  */
954  assert (turbulenceClosureModel >=3);
955  double rho,nu,H_mu,ImH_mu,nu_t=0.0,nu_t_keps =0.0, nu_t_komega=0.0;
956  double isKEpsilon = 1.0;
957  if (turbulenceClosureModel == 4)
958  isKEpsilon = 0.0;
959  H_mu = (1.0-useVF)*gf.H(eps_mu,phi)+useVF*fmin(1.0,fmax(0.0,vf));
960  ImH_mu = (1.0-useVF)*gf.ImH(eps_mu,phi)+useVF*(1.0-fmin(1.0,fmax(0.0,vf)));
961  nu = nu_0*ImH_mu+nu_1*H_mu;
962  rho = rho_0*ImH_mu+rho_1*H_mu;
963 
964  const double twoThirds = 2.0/3.0; const double div_zero = 1.0e-2*fmin(nu_0,nu_1);
965  mom_u_source += twoThirds*turb_grad_0[0];
966  mom_v_source += twoThirds*turb_grad_0[1];
967  /* mom_w_source += twoThirds*turb_grad_0[2]; */
968 
969  //--- closure model specific ---
970  //k-epsilon
971  nu_t_keps = eddy_visc_coef_0*turb_var_0*turb_var_0/(fabs(turb_var_1) + div_zero);
972  //k-omega
973  nu_t_komega = turb_var_0/(fabs(turb_var_1) + div_zero);
974  //
975  nu_t = isKEpsilon*nu_t_keps + (1.0-isKEpsilon)*nu_t_komega;
976  //mwf debug
977  //if (nu_t > 1.e6*nu)
978  //{
979  // std::cout<<"RANS3PF2D WARNING isKEpsilon = "<<isKEpsilon<<" nu_t = " <<nu_t<<" nu= "<<nu<<" k= "<<turb_var_0<<" turb_var_1= "<<turb_var_1<<std::endl;
980  //}
981 
982  nu_t = fmax(nu_t,1.0e-4*nu); //limit according to Lew, Buscaglia etal 01
983  //mwf hack
984  nu_t = fmin(nu_t,1.0e6*nu);
985 
986  eddy_viscosity = nu_t*rho; // mql. CHECK.
987  //u momentum diffusion tensor
988  mom_uu_diff_ten[0] += porosity*2.0*eddy_viscosity;
989  mom_uu_diff_ten[1] += porosity*eddy_viscosity;
990  /* mom_uu_diff_ten[2] += porosity*eddy_viscosity; */
991 
992  mom_uv_diff_ten[0]+=porosity*eddy_viscosity;
993 
994  /* mom_uw_diff_ten[0]+=porosity*eddy_viscosity; */
995 
996  //v momentum diffusion tensor
997  mom_vv_diff_ten[0] += porosity*eddy_viscosity;
998  mom_vv_diff_ten[1] += porosity*2.0*eddy_viscosity;
999  /* mom_vv_diff_ten[2] += porosity*eddy_viscosity; */
1000 
1001  mom_vu_diff_ten[0]+=porosity*eddy_viscosity;
1002 
1003  /* mom_vw_diff_ten[0]+=porosity*eddy_viscosity; */
1004 
1005  /* //w momentum diffusion tensor */
1006  /* mom_ww_diff_ten[0] += porosity*eddy_viscosity; */
1007  /* mom_ww_diff_ten[1] += porosity*eddy_viscosity; */
1008  /* mom_ww_diff_ten[2] += porosity*2.0*eddy_viscosity; */
1009 
1010  /* mom_wu_diff_ten[0]+=porosity*eddy_viscosity; */
1011 
1012  /* mom_wv_diff_ten[0]+=eddy_viscosity; */
1013  }
1014 
1015  inline void calculateSubgridError_tau(const double &hFactor,
1016  const double &elementDiameter,
1017  const double &dmt,
1018  const double &dm,
1019  const double df[nSpace],
1020  const double &a,
1021  const double &pfac,
1022  double &tau_v,
1023  double &tau_p,
1024  double &cfl)
1025  {
1026  double h, oneByAbsdt, density, viscosity, nrm_df;
1027  h = hFactor * elementDiameter;
1028  density = dm;
1029  viscosity = a;
1030  nrm_df = 0.0;
1031  for (int I = 0; I < nSpace; I++)
1032  nrm_df += df[I] * df[I];
1033  nrm_df = sqrt(nrm_df);
1034  if (density > 1.0e-8)
1035  cfl = nrm_df/(h*density);//this is really cfl/dt, but that's what we want to know, the step controller expect this
1036  else
1037  cfl = nrm_df/h;
1038  oneByAbsdt = fabs(dmt);
1039  tau_v = 1.0/(4.0*viscosity/(h*h) + 2.0*nrm_df/h + oneByAbsdt);
1040  tau_p = (4.0*viscosity + 2.0*nrm_df*h + oneByAbsdt*h*h)/pfac;
1041  }
1042 
1043  inline void calculateSubgridError_tau(const double &Ct_sge,
1044  const double &Cd_sge,
1045  const double G[nSpace * nSpace],
1046  const double &G_dd_G,
1047  const double &tr_G,
1048  const double &A0,
1049  const double Ai[nSpace],
1050  const double &Kij,
1051  const double &pfac,
1052  double &tau_v,
1053  double &tau_p,
1054  double &q_cfl)
1055  {
1056  double v_d_Gv = 0.0;
1057  for (int I = 0; I < nSpace; I++)
1058  for (int J = 0; J < nSpace; J++)
1059  v_d_Gv += Ai[I] * G[I * nSpace + J] * Ai[J];
1060  tau_v = 1.0 / sqrt(Ct_sge * A0 * A0 + v_d_Gv + Cd_sge * Kij * Kij * G_dd_G + 1.0e-12);
1061  tau_p = 1.0 / (pfac * tr_G * tau_v);
1062  }
1063 
1064  inline void calculateSubgridError_tauRes(const double &tau_p,
1065  const double &tau_v,
1066  const double &pdeResidualP,
1067  const double &pdeResidualU,
1068  const double &pdeResidualV,
1069  const double &pdeResidualW,
1070  double &subgridErrorP,
1071  double &subgridErrorU,
1072  double &subgridErrorV,
1073  double &subgridErrorW)
1074  {
1075  /* GLS pressure */
1076  subgridErrorP = -tau_p * pdeResidualP;
1077  /* GLS momentum */
1078  subgridErrorU = -tau_v * pdeResidualU;
1079  subgridErrorV = -tau_v * pdeResidualV;
1080  /* subgridErrorW = -tau_v*pdeResidualW; */
1081  }
1082 
1083  inline void calculateSubgridErrorDerivatives_tauRes(const double &tau_p,
1084  const double &tau_v,
1085  const double dpdeResidualP_du[nDOF_trial_element],
1086  const double dpdeResidualP_dv[nDOF_trial_element],
1087  const double dpdeResidualP_dw[nDOF_trial_element],
1088  const double dpdeResidualU_dp[nDOF_trial_element],
1089  const double dpdeResidualU_du[nDOF_trial_element],
1090  const double dpdeResidualV_dp[nDOF_trial_element],
1091  const double dpdeResidualV_dv[nDOF_trial_element],
1092  const double dpdeResidualW_dp[nDOF_trial_element],
1093  const double dpdeResidualW_dw[nDOF_trial_element],
1094  double dsubgridErrorP_du[nDOF_trial_element],
1095  double dsubgridErrorP_dv[nDOF_trial_element],
1096  double dsubgridErrorP_dw[nDOF_trial_element],
1097  double dsubgridErrorU_dp[nDOF_trial_element],
1098  double dsubgridErrorU_du[nDOF_trial_element],
1099  double dsubgridErrorV_dp[nDOF_trial_element],
1100  double dsubgridErrorV_dv[nDOF_trial_element],
1101  double dsubgridErrorW_dp[nDOF_trial_element],
1102  double dsubgridErrorW_dw[nDOF_trial_element])
1103  {
1104  for (int j = 0; j < nDOF_trial_element; j++)
1105  {
1106  /* GLS pressure */
1107  dsubgridErrorP_du[j] = -tau_p * dpdeResidualP_du[j];
1108  dsubgridErrorP_dv[j] = -tau_p * dpdeResidualP_dv[j];
1109  /* dsubgridErrorP_dw[j] = -tau_p*dpdeResidualP_dw[j]; */
1110  /* GLS momentum*/
1111  /* u */
1112  dsubgridErrorU_dp[j] = -tau_v * dpdeResidualU_dp[j];
1113  dsubgridErrorU_du[j] = -tau_v * dpdeResidualU_du[j];
1114  /* v */
1115  dsubgridErrorV_dp[j] = -tau_v * dpdeResidualV_dp[j];
1116  dsubgridErrorV_dv[j] = -tau_v * dpdeResidualV_dv[j];
1117  /* /\* w *\/ */
1118  /* dsubgridErrorW_dp[j] = -tau_v*dpdeResidualW_dp[j]; */
1119  /* dsubgridErrorW_dw[j] = -tau_v*dpdeResidualW_dw[j]; */
1120  }
1121  }
1122 
1123  inline
1124  void exteriorNumericalAdvectiveFlux(const int& isDOFBoundary_p,
1125  const int& isDOFBoundary_u,
1126  const int& isDOFBoundary_v,
1127  const int& isDOFBoundary_w,
1128  const int& isFluxBoundary_p,
1129  const int& isFluxBoundary_u,
1130  const int& isFluxBoundary_v,
1131  const int& isFluxBoundary_w,
1132  const double& oneByRho,
1133  const double& bc_oneByRho,
1134  const double n[nSpace],
1135  const double& porosity,
1136  const double& bc_p,
1137  const double& bc_u,
1138  const double& bc_v,
1139  const double& bc_w,
1140  const double bc_f_mass[nSpace],
1141  const double bc_f_umom[nSpace],
1142  const double bc_f_vmom[nSpace],
1143  const double bc_f_wmom[nSpace],
1144  const double& bc_flux_mass,
1145  const double& bc_flux_umom,
1146  const double& bc_flux_vmom,
1147  const double& bc_flux_wmom,
1148  const double& p,
1149  const double& u,
1150  const double& v,
1151  const double& w,
1152  const double f_mass[nSpace],
1153  const double f_umom[nSpace],
1154  const double f_vmom[nSpace],
1155  const double f_wmom[nSpace],
1156  const double df_mass_du[nSpace],
1157  const double df_mass_dv[nSpace],
1158  const double df_mass_dw[nSpace],
1159  const double df_umom_dp[nSpace],
1160  const double df_umom_du[nSpace],
1161  const double df_umom_dv[nSpace],
1162  const double df_umom_dw[nSpace],
1163  const double df_vmom_dp[nSpace],
1164  const double df_vmom_du[nSpace],
1165  const double df_vmom_dv[nSpace],
1166  const double df_vmom_dw[nSpace],
1167  const double df_wmom_dp[nSpace],
1168  const double df_wmom_du[nSpace],
1169  const double df_wmom_dv[nSpace],
1170  const double df_wmom_dw[nSpace],
1171  double& flux_mass,
1172  double& flux_umom,
1173  double& flux_vmom,
1174  double& flux_wmom,
1175  double* velocity_star,
1176  double* velocity)
1177  {
1178  double flowSpeedNormal;
1179  flux_mass = 0.0;
1180  flux_umom = 0.0;
1181  flux_vmom = 0.0;
1182  /* flux_wmom = 0.0; */
1183  flowSpeedNormal=porosity*(n[0]*velocity_star[0] +
1184  n[1]*velocity_star[1]);
1185  velocity[0] = u;
1186  velocity[1] = v;
1187  /* velocity[2] = w; */
1188  if (isDOFBoundary_u != 1)
1189  {
1190  flux_mass += n[0]*f_mass[0];
1191  if (flowSpeedNormal < 0.0)
1192  {
1193  flux_umom+=flowSpeedNormal*(0.0 - u);
1194  }
1195  }
1196  else
1197  {
1198  flux_mass += n[0]*f_mass[0];
1199  if (flowSpeedNormal < 0.0)
1200  {
1201  flux_umom+=flowSpeedNormal*(bc_u - u);
1202  velocity[0] = bc_u;
1203  }
1204  }
1205  if (isDOFBoundary_v != 1)
1206  {
1207  flux_mass+=n[1]*f_mass[1];
1208  if (flowSpeedNormal < 0.0)
1209  {
1210  flux_vmom+=flowSpeedNormal*(0.0 - v);
1211  }
1212  }
1213  else
1214  {
1215  flux_mass+=n[1]*f_mass[1];
1216  if (flowSpeedNormal < 0.0)
1217  {
1218  flux_vmom+=flowSpeedNormal*(bc_v - v);
1219  velocity[1] = bc_v;
1220  }
1221  }
1222  /* if (isDOFBoundary_w != 1) */
1223  /* { */
1224  /* flux_mass+=n[2]*f_mass[2]; */
1225  /* } */
1226  /* else */
1227  /* { */
1228  /* flux_mass +=n[2]*f_mass[2]; */
1229  /* if (flowSpeedNormal < 0.0) */
1230  /* { */
1231  /* flux_wmom+=flowSpeedNormal*(bc_w - w); */
1232  /* } */
1233  /* } */
1234  /* if (isDOFBoundary_w != 1) */
1235  /* { */
1236  /* flux_mass+=n[2]*f_mass[2]; */
1237  /* } */
1238  /* else */
1239  /* { */
1240  /* flux_mass +=n[2]*f_mass[2]; */
1241  /* if (flowSpeedNormal < 0.0) */
1242  /* flux_wmom+=bc_speed*(bc_w - w); */
1243  /* } */
1244  if (isFluxBoundary_u == 1)
1245  {
1246  flux_umom = bc_flux_umom;
1247  velocity[0] = bc_flux_umom/porosity;
1248  }
1249  if (isFluxBoundary_v == 1)
1250  {
1251  flux_vmom = bc_flux_vmom;
1252  velocity[1] = bc_flux_umom/porosity;
1253  }
1254  /* if (isFluxBoundary_w == 1) */
1255  /* { */
1256  /* flux_wmom = bc_flux_wmom; */
1257  /* } */
1258  }
1259 
1260  inline
1261  void exteriorNumericalAdvectiveFluxDerivatives(const int& isDOFBoundary_p,
1262  const int& isDOFBoundary_u,
1263  const int& isDOFBoundary_v,
1264  const int& isDOFBoundary_w,
1265  const int& isFluxBoundary_p,
1266  const int& isFluxBoundary_u,
1267  const int& isFluxBoundary_v,
1268  const int& isFluxBoundary_w,
1269  const double& oneByRho,
1270  const double n[nSpace],
1271  const double& porosity, //mql. CHECK. Multiply by rho outside
1272  const double& bc_p,
1273  const double& bc_u,
1274  const double& bc_v,
1275  const double& bc_w,
1276  const double bc_f_mass[nSpace],
1277  const double bc_f_umom[nSpace],
1278  const double bc_f_vmom[nSpace],
1279  const double bc_f_wmom[nSpace],
1280  const double& bc_flux_mass,
1281  const double& bc_flux_umom,
1282  const double& bc_flux_vmom,
1283  const double& bc_flux_wmom,
1284  const double& p,
1285  const double& u,
1286  const double& v,
1287  const double& w,
1288  const double f_mass[nSpace],
1289  const double f_umom[nSpace],
1290  const double f_vmom[nSpace],
1291  const double f_wmom[nSpace],
1292  const double df_mass_du[nSpace],
1293  const double df_mass_dv[nSpace],
1294  const double df_mass_dw[nSpace],
1295  const double df_umom_dp[nSpace],
1296  const double df_umom_du[nSpace],
1297  const double df_umom_dv[nSpace],
1298  const double df_umom_dw[nSpace],
1299  const double df_vmom_dp[nSpace],
1300  const double df_vmom_du[nSpace],
1301  const double df_vmom_dv[nSpace],
1302  const double df_vmom_dw[nSpace],
1303  const double df_wmom_dp[nSpace],
1304  const double df_wmom_du[nSpace],
1305  const double df_wmom_dv[nSpace],
1306  const double df_wmom_dw[nSpace],
1307  double& dflux_mass_du,
1308  double& dflux_mass_dv,
1309  double& dflux_mass_dw,
1310  double& dflux_umom_dp,
1311  double& dflux_umom_du,
1312  double& dflux_umom_dv,
1313  double& dflux_umom_dw,
1314  double& dflux_vmom_dp,
1315  double& dflux_vmom_du,
1316  double& dflux_vmom_dv,
1317  double& dflux_vmom_dw,
1318  double& dflux_wmom_dp,
1319  double& dflux_wmom_du,
1320  double& dflux_wmom_dv,
1321  double& dflux_wmom_dw,
1322  double* velocity_star)
1323  {
1324  double flowSpeedNormal;
1325  dflux_mass_du = 0.0;
1326  dflux_mass_dv = 0.0;
1327  /* dflux_mass_dw = 0.0; */
1328 
1329  dflux_umom_dp = 0.0;
1330  dflux_umom_du = 0.0;
1331  dflux_umom_dv = 0.0;
1332  /* dflux_umom_dw = 0.0; */
1333 
1334  dflux_vmom_dp = 0.0;
1335  dflux_vmom_du = 0.0;
1336  dflux_vmom_dv = 0.0;
1337  /* dflux_vmom_dw = 0.0; */
1338 
1339  dflux_wmom_dp = 0.0;
1340  dflux_wmom_du = 0.0;
1341  dflux_wmom_dv = 0.0;
1342  /* dflux_wmom_dw = 0.0; */
1343  flowSpeedNormal=porosity*(n[0]*velocity_star[0] +
1344  n[1]*velocity_star[1]);
1345  if (isDOFBoundary_u != 1)
1346  {
1347  dflux_mass_du += n[0]*df_mass_du[0];
1348  if (flowSpeedNormal < 0.0)
1349  dflux_umom_du -= flowSpeedNormal;
1350  }
1351  else
1352  {
1353  dflux_mass_du += n[0]*df_mass_du[0];
1354  if (flowSpeedNormal < 0.0)
1355  dflux_umom_du -= flowSpeedNormal;
1356  }
1357  if (isDOFBoundary_v != 1)
1358  {
1359  dflux_mass_dv += n[1]*df_mass_dv[1];
1360  if (flowSpeedNormal < 0.0)
1361  dflux_vmom_dv -= flowSpeedNormal;
1362  }
1363  else
1364  {
1365  dflux_mass_dv += n[1]*df_mass_dv[1];
1366  if (flowSpeedNormal < 0.0)
1367  dflux_vmom_dv -= flowSpeedNormal;
1368  }
1369  /* if (isDOFBoundary_w != 1) */
1370  /* { */
1371  /* dflux_mass_dw+=n[2]*df_mass_dw[2]; */
1372  /* } */
1373  /* else */
1374  /* { */
1375  /* dflux_mass_dw += n[2]*df_mass_dw[2]; */
1376  /* if (flowSpeedNormal < 0.0) */
1377  /* dflux_wmom_dw -= flowSpeedNormal; */
1378  /* } */
1379  /* if (isDOFBoundary_w != 1) */
1380  /* { */
1381  /* dflux_mass_dw+=n[2]*df_mass_dw[2]; */
1382  /* } */
1383  /* else */
1384  /* { */
1385  /* dflux_mass_dw += n[2]*df_mass_dw[2]; */
1386  /* if (flowSpeedNormal < 0.0) */
1387  /* dflux_wmom_dw += bc_speed; */
1388  /* } */
1389  /* if (isDOFBoundary_p == 1) */
1390  /* { */
1391  /* dflux_umom_dp= -n[0]*oneByRho; */
1392  /* dflux_vmom_dp= -n[1]*oneByRho; */
1393  /* /\* dflux_wmom_dp= -n[2]*oneByRho; *\/ */
1394  /* } */
1395  /* if (isFluxBoundary_p == 1) */
1396  /* { */
1397  /* dflux_mass_du = 0.0; */
1398  /* dflux_mass_dv = 0.0; */
1399  /* /\* dflux_mass_dw = 0.0; *\/ */
1400  /* } */
1401  if (isFluxBoundary_u == 1)
1402  {
1403  dflux_umom_dp = 0.0;
1404  dflux_umom_du = 0.0;
1405  dflux_umom_dv = 0.0;
1406  /* dflux_umom_dw = 0.0; */
1407  }
1408  if (isFluxBoundary_v == 1)
1409  {
1410  dflux_vmom_dp = 0.0;
1411  dflux_vmom_du = 0.0;
1412  dflux_vmom_dv = 0.0;
1413  /* dflux_vmom_dw = 0.0; */
1414  }
1415  /* if (isFluxBoundary_w == 1) */
1416  /* { */
1417  /* dflux_wmom_dp = 0.0; */
1418  /* dflux_wmom_du = 0.0; */
1419  /* dflux_wmom_dv = 0.0; */
1420  /* dflux_wmom_dw = 0.0; */
1421  /* } */
1422  }
1423 
1424  inline
1425  void exteriorNumericalDiffusiveFlux(const double& eps,
1426  const double& phi,
1427  int* rowptr,
1428  int* colind,
1429  const int& isDOFBoundary,
1430  const int& isFluxBoundary,
1431  const double n[nSpace],
1432  double* bc_a,
1433  const double& bc_u,
1434  const double& bc_flux,
1435  double* a,
1436  const double grad_potential[nSpace],
1437  const double& u,
1438  const double& penalty,
1439  double& flux)
1440  {
1441  double diffusiveVelocityComponent_I,penaltyFlux,max_a;
1442  if(isFluxBoundary == 1)
1443  {
1444  flux = bc_flux;
1445  }
1446  else if(isDOFBoundary == 1)
1447  {
1448  flux = 0.0;
1449  max_a=0.0;
1450  for(int I=0;I<nSpace;I++)
1451  {
1452  diffusiveVelocityComponent_I=0.0;
1453  for(int m=rowptr[I];m<rowptr[I+1];m++)
1454  {
1455  diffusiveVelocityComponent_I -= a[m]*grad_potential[colind[m]];
1456  max_a = fmax(max_a,a[m]);
1457  }
1458  flux+= diffusiveVelocityComponent_I*n[I];
1459  }
1460  penaltyFlux = max_a*penalty*(u-bc_u);
1461  flux += penaltyFlux;
1462  //contact line slip
1463  //flux*=(gf.D(eps,0) - gf.D(eps,phi))/gf.D(eps,0);
1464  }
1465  else
1466  {
1467  std::cerr<<"RANS3PF2D: warning, diffusion term with no boundary condition set, setting diffusive flux to 0.0"<<std::endl;
1468  flux = 0.0;
1469  }
1470  }
1471 
1472  inline
1473  double ExteriorNumericalDiffusiveFluxJacobian(const double& eps,
1474  const double& phi,
1475  int* rowptr,
1476  int* colind,
1477  const int& isDOFBoundary,
1478  const int& isFluxBoundary,
1479  const double n[nSpace],
1480  double* a,
1481  const double& v,
1482  const double grad_v[nSpace],
1483  const double& penalty)
1484  {
1485  double dvel_I,tmp=0.0,max_a=0.0;
1486  if(isFluxBoundary==0 && isDOFBoundary==1)
1487  {
1488  for(int I=0;I<nSpace;I++)
1489  {
1490  dvel_I=0.0;
1491  for(int m=rowptr[I];m<rowptr[I+1];m++)
1492  {
1493  dvel_I -= a[m]*grad_v[colind[m]];
1494  max_a = fmax(max_a,a[m]);
1495  }
1496  tmp += dvel_I*n[I];
1497  }
1498  tmp +=max_a*penalty*v;
1499  //contact line slip
1500  //tmp*=(gf.D(eps,0) - gf.D(eps,phi))/gf.D(eps,0);
1501  }
1502  return tmp;
1503  }
1504 
1505  void get_symmetric_gradient_dot_vec(const double *grad_u, const double *grad_v, const double *n,double res[2])
1506  {
1507 // res[0] = 2.0*grad_u[0]*n[0]+(grad_u[1]+grad_v[0])*n[1];
1508 // res[1] = (grad_v[0]+grad_u[1])*n[0]+ 2*grad_v[1]*n[1];
1509  res[0] = grad_u[0]*n[0]+grad_u[1]*n[1];
1510  res[1] = grad_v[0]*n[0]+grad_v[1]*n[1];
1511  }
1512  double get_cross_product(const double *u, const double *v)
1513  {
1514  return u[0]*v[1]-u[1]*v[0];
1515  }
1516  double get_dot_product(const double *u, const double *v)
1517  {
1518  return u[0]*v[0]+u[1]*v[1];
1519  }
1520  int get_distance_to_ball(int n_balls,double* ball_center, double* ball_radius, double x, double y, double z, double& distance)
1521  {
1522  distance = 1e10;
1523  int index = -1;
1524  double d_ball_i;
1525  for (int i=0; i<n_balls; ++i)
1526  {
1527  d_ball_i = std::sqrt((ball_center[i*3+0]-x)*(ball_center[i*3+0]-x)
1528  +(ball_center[i*3+1]-y)*(ball_center[i*3+1]-y)
1529 // +(ball_center[i*3+2]-z)*(ball_center[i*3+2]-z)
1530  ) - ball_radius[i];
1531  if(d_ball_i<distance)
1532  {
1533  distance = d_ball_i;
1534  index = i;
1535  }
1536  }
1537  return index;
1538  }
1539  void get_distance_to_ith_ball(int n_balls,double* ball_center, double* ball_radius,
1540  int I,
1541  double x, double y, double z,
1542  double& distance)
1543  {
1544  distance = std::sqrt((ball_center[I*3+0]-x)*(ball_center[I*3+0]-x)
1545  + (ball_center[I*3+1]-y)*(ball_center[I*3+1]-y)
1546 // + (ball_center[I*3+2]-z)*(ball_center[I*3+2]-z)
1547  ) - ball_radius[I];
1548  }
1549  void get_normal_to_ith_ball(int n_balls,double* ball_center, double* ball_radius,
1550  int I,
1551  double x, double y, double z,
1552  double& nx, double& ny)
1553  {
1554  double distance = std::sqrt((ball_center[I*3+0]-x)*(ball_center[I*3+0]-x)
1555  + (ball_center[I*3+1]-y)*(ball_center[I*3+1]-y)
1556 // + (ball_center[I*3+2]-z)*(ball_center[I*3+2]-z)
1557  );
1558  nx = (x - ball_center[I*3+0])/(distance+1e-10);
1559  ny = (y - ball_center[I*3+1])/(distance+1e-10);
1560  }
1561  void get_velocity_to_ith_ball(int n_balls,double* ball_center, double* ball_radius,
1562  double* ball_velocity, double* ball_angular_velocity,
1563  int I,
1564  double x, double y, double z,
1565  double& vx, double& vy)
1566  {
1567  vx = ball_velocity[3*I + 0] - ball_angular_velocity[3*I + 2]*(y-ball_center[3*I + 1]);
1568  vy = ball_velocity[3*I + 1] + ball_angular_velocity[3*I + 2]*(x-ball_center[3*I + 0]);
1569  }
1570 
1572  bool useExact)
1573  {
1574  xt::pyarray<double>& mesh_trial_ref = args.array<double>("mesh_trial_ref");
1575  xt::pyarray<double>& mesh_grad_trial_ref = args.array<double>("mesh_grad_trial_ref");
1576  xt::pyarray<double>& mesh_dof = args.array<double>("mesh_dof");
1577  xt::pyarray<double>& mesh_velocity_dof = args.array<double>("mesh_velocity_dof");
1578  double MOVING_DOMAIN = args.scalar<double>("MOVING_DOMAIN");
1579  double PSTAB = args.scalar<double>("PSTAB");
1580  xt::pyarray<int>& mesh_l2g = args.array<int>("mesh_l2g");
1581  xt::pyarray<double>& x_ref = args.array<double>("x_ref");
1582  xt::pyarray<double>& dV_ref = args.array<double>("dV_ref");
1583  int nDOF_per_element_pressure = args.scalar<int>("nDOF_per_element_pressure");
1584  xt::pyarray<double>& p_trial_ref = args.array<double>("p_trial_ref");
1585  xt::pyarray<double>& p_grad_trial_ref = args.array<double>("p_grad_trial_ref");
1586  xt::pyarray<double>& p_test_ref = args.array<double>("p_test_ref");
1587  xt::pyarray<double>& p_grad_test_ref = args.array<double>("p_grad_test_ref");
1588  xt::pyarray<double>& q_p = args.array<double>("q_p");
1589  xt::pyarray<double>& q_grad_p = args.array<double>("q_grad_p");
1590  xt::pyarray<double>& ebqe_p = args.array<double>("ebqe_p");
1591  xt::pyarray<double>& ebqe_grad_p = args.array<double>("ebqe_grad_p");
1592  xt::pyarray<double>& vel_trial_ref = args.array<double>("vel_trial_ref");
1593  xt::pyarray<double>& vel_grad_trial_ref = args.array<double>("vel_grad_trial_ref");
1594  xt::pyarray<double>& vel_hess_trial_ref = args.array<double>("vel_hess_trial_ref");
1595  xt::pyarray<double>& vel_test_ref = args.array<double>("vel_test_ref");
1596  xt::pyarray<double>& vel_grad_test_ref = args.array<double>("vel_grad_test_ref");
1597  xt::pyarray<double>& mesh_trial_trace_ref = args.array<double>("mesh_trial_trace_ref");
1598  xt::pyarray<double>& mesh_grad_trial_trace_ref = args.array<double>("mesh_grad_trial_trace_ref");
1599  xt::pyarray<double>& dS_ref = args.array<double>("dS_ref");
1600  xt::pyarray<double>& p_trial_trace_ref = args.array<double>("p_trial_trace_ref");
1601  xt::pyarray<double>& p_grad_trial_trace_ref = args.array<double>("p_grad_trial_trace_ref");
1602  xt::pyarray<double>& p_test_trace_ref = args.array<double>("p_test_trace_ref");
1603  xt::pyarray<double>& p_grad_test_trace_ref = args.array<double>("p_grad_test_trace_ref");
1604  xt::pyarray<double>& vel_trial_trace_ref = args.array<double>("vel_trial_trace_ref");
1605  xt::pyarray<double>& vel_grad_trial_trace_ref = args.array<double>("vel_grad_trial_trace_ref");
1606  xt::pyarray<double>& vel_test_trace_ref = args.array<double>("vel_test_trace_ref");
1607  xt::pyarray<double>& vel_grad_test_trace_ref = args.array<double>("vel_grad_test_trace_ref");
1608  xt::pyarray<double>& normal_ref = args.array<double>("normal_ref");
1609  xt::pyarray<double>& boundaryJac_ref = args.array<double>("boundaryJac_ref");
1610  double eb_adjoint_sigma = args.scalar<double>("eb_adjoint_sigma");
1611  xt::pyarray<double>& elementDiameter = args.array<double>("elementDiameter");
1612  xt::pyarray<double>& nodeDiametersArray = args.array<double>("nodeDiametersArray");
1613  double hFactor = args.scalar<double>("hFactor");
1614  int nElements_global = args.scalar<int>("nElements_global");
1615  int nElements_owned = args.scalar<int>("nElements_owned");
1616  int nElementBoundaries_global = args.scalar<int>("nElementBoundaries_global");
1617  int nElementBoundaries_owned = args.scalar<int>("nElementBoundaries_owned");
1618  int nNodes_owned = args.scalar<int>("nNodes_owned");
1619  double useRBLES = args.scalar<double>("useRBLES");
1620  double useMetrics = args.scalar<double>("useMetrics");
1621  double alphaBDF = args.scalar<double>("alphaBDF");
1622  double epsFact_rho = args.scalar<double>("epsFact_rho");
1623  double epsFact_mu = args.scalar<double>("epsFact_mu");
1624  double sigma = args.scalar<double>("sigma");
1625  double rho_0 = args.scalar<double>("rho_0");
1626  double nu_0 = args.scalar<double>("nu_0");
1627  double rho_1 = args.scalar<double>("rho_1");
1628  double nu_1 = args.scalar<double>("nu_1");
1629  double smagorinskyConstant = args.scalar<double>("smagorinskyConstant");
1630  int turbulenceClosureModel = args.scalar<int>("turbulenceClosureModel");
1631  double Ct_sge = args.scalar<double>("Ct_sge");
1632  double Cd_sge = args.scalar<double>("Cd_sge");
1633  double C_dc = args.scalar<double>("C_dc");
1634  double C_b = args.scalar<double>("C_b");
1635  const xt::pyarray<double>& eps_solid = args.array<double>("eps_solid");
1636  const xt::pyarray<double>& ebq_global_phi_solid = args.array<double>("ebq_global_phi_solid");
1637  const xt::pyarray<double>& ebq_global_grad_phi_solid = args.array<double>("ebq_global_grad_phi_solid");
1638  const xt::pyarray<double>& ebq_particle_velocity_solid = args.array<double>("ebq_particle_velocity_solid");
1639  xt::pyarray<double>& phi_solid_nodes = args.array<double>("phi_solid_nodes");
1640  xt::pyarray<double>& phi_solid = args.array<double>("phi_solid");
1641  const xt::pyarray<double>& q_velocity_solid = args.array<double>("q_velocity_solid");
1642  const xt::pyarray<double>& q_velocityStar_solid = args.array<double>("q_velocityStar_solid");
1643  const xt::pyarray<double>& q_vos = args.array<double>("q_vos");
1644  const xt::pyarray<double>& q_dvos_dt = args.array<double>("q_dvos_dt");
1645  const xt::pyarray<double>& q_grad_vos = args.array<double>("q_grad_vos");
1646  const xt::pyarray<double>& q_dragAlpha = args.array<double>("q_dragAlpha");
1647  const xt::pyarray<double>& q_dragBeta = args.array<double>("q_dragBeta");
1648  const xt::pyarray<double>& q_mass_source = args.array<double>("q_mass_source");
1649  const xt::pyarray<double>& q_turb_var_0 = args.array<double>("q_turb_var_0");
1650  const xt::pyarray<double>& q_turb_var_1 = args.array<double>("q_turb_var_1");
1651  const xt::pyarray<double>& q_turb_var_grad_0 = args.array<double>("q_turb_var_grad_0");
1652  xt::pyarray<double>& q_eddy_viscosity = args.array<double>("q_eddy_viscosity");
1653  xt::pyarray<int>& p_l2g = args.array<int>("p_l2g");
1654  xt::pyarray<int>& vel_l2g = args.array<int>("vel_l2g");
1655  xt::pyarray<double>& p_dof = args.array<double>("p_dof");
1656  xt::pyarray<double>& u_dof = args.array<double>("u_dof");
1657  xt::pyarray<double>& v_dof = args.array<double>("v_dof");
1658  xt::pyarray<double>& w_dof = args.array<double>("w_dof");
1659  xt::pyarray<double>& u_dof_old = args.array<double>("u_dof_old");
1660  xt::pyarray<double>& v_dof_old = args.array<double>("v_dof_old");
1661  xt::pyarray<double>& w_dof_old = args.array<double>("w_dof_old");
1662  xt::pyarray<double>& u_dof_old_old = args.array<double>("u_dof_old_old");
1663  xt::pyarray<double>& v_dof_old_old = args.array<double>("v_dof_old_old");
1664  xt::pyarray<double>& w_dof_old_old = args.array<double>("w_dof_old_old");
1665  xt::pyarray<double>& uStar_dof = args.array<double>("uStar_dof");
1666  xt::pyarray<double>& vStar_dof = args.array<double>("vStar_dof");
1667  xt::pyarray<double>& wStar_dof = args.array<double>("wStar_dof");
1668  xt::pyarray<double>& g = args.array<double>("g");
1669  const double useVF = args.scalar<double>("useVF");
1670  xt::pyarray<double>& vf = args.array<double>("vf");
1671  xt::pyarray<double>& phi = args.array<double>("phi");
1672  xt::pyarray<double>& phi_dof = args.array<double>("phi_dof");
1673  xt::pyarray<double>& normal_phi = args.array<double>("normal_phi");
1674  xt::pyarray<double>& kappa_phi = args.array<double>("kappa_phi");
1675  xt::pyarray<double>& q_mom_u_acc = args.array<double>("q_mom_u_acc");
1676  xt::pyarray<double>& q_mom_v_acc = args.array<double>("q_mom_v_acc");
1677  xt::pyarray<double>& q_mom_w_acc = args.array<double>("q_mom_w_acc");
1678  xt::pyarray<double>& q_mass_adv = args.array<double>("q_mass_adv");
1679  xt::pyarray<double>& q_mom_u_acc_beta_bdf = args.array<double>("q_mom_u_acc_beta_bdf");
1680  xt::pyarray<double>& q_mom_v_acc_beta_bdf = args.array<double>("q_mom_v_acc_beta_bdf");
1681  xt::pyarray<double>& q_mom_w_acc_beta_bdf = args.array<double>("q_mom_w_acc_beta_bdf");
1682  xt::pyarray<double>& q_dV = args.array<double>("q_dV");
1683  xt::pyarray<double>& q_dV_last = args.array<double>("q_dV_last");
1684  xt::pyarray<double>& q_velocity_sge = args.array<double>("q_velocity_sge");
1685  xt::pyarray<double>& ebqe_velocity_star = args.array<double>("ebqe_velocity_star");
1686  xt::pyarray<double>& q_cfl = args.array<double>("q_cfl");
1687  xt::pyarray<double>& q_numDiff_u = args.array<double>("q_numDiff_u");
1688  xt::pyarray<double>& q_numDiff_v = args.array<double>("q_numDiff_v");
1689  xt::pyarray<double>& q_numDiff_w = args.array<double>("q_numDiff_w");
1690  xt::pyarray<double>& q_numDiff_u_last = args.array<double>("q_numDiff_u_last");
1691  xt::pyarray<double>& q_numDiff_v_last = args.array<double>("q_numDiff_v_last");
1692  xt::pyarray<double>& q_numDiff_w_last = args.array<double>("q_numDiff_w_last");
1693  xt::pyarray<int>& sdInfo_u_u_rowptr = args.array<int>("sdInfo_u_u_rowptr");
1694  xt::pyarray<int>& sdInfo_u_u_colind = args.array<int>("sdInfo_u_u_colind");
1695  xt::pyarray<int>& sdInfo_u_v_rowptr = args.array<int>("sdInfo_u_v_rowptr");
1696  xt::pyarray<int>& sdInfo_u_v_colind = args.array<int>("sdInfo_u_v_colind");
1697  xt::pyarray<int>& sdInfo_u_w_rowptr = args.array<int>("sdInfo_u_w_rowptr");
1698  xt::pyarray<int>& sdInfo_u_w_colind = args.array<int>("sdInfo_u_w_colind");
1699  xt::pyarray<int>& sdInfo_v_v_rowptr = args.array<int>("sdInfo_v_v_rowptr");
1700  xt::pyarray<int>& sdInfo_v_v_colind = args.array<int>("sdInfo_v_v_colind");
1701  xt::pyarray<int>& sdInfo_v_u_rowptr = args.array<int>("sdInfo_v_u_rowptr");
1702  xt::pyarray<int>& sdInfo_v_u_colind = args.array<int>("sdInfo_v_u_colind");
1703  xt::pyarray<int>& sdInfo_v_w_rowptr = args.array<int>("sdInfo_v_w_rowptr");
1704  xt::pyarray<int>& sdInfo_v_w_colind = args.array<int>("sdInfo_v_w_colind");
1705  xt::pyarray<int>& sdInfo_w_w_rowptr = args.array<int>("sdInfo_w_w_rowptr");
1706  xt::pyarray<int>& sdInfo_w_w_colind = args.array<int>("sdInfo_w_w_colind");
1707  xt::pyarray<int>& sdInfo_w_u_rowptr = args.array<int>("sdInfo_w_u_rowptr");
1708  xt::pyarray<int>& sdInfo_w_u_colind = args.array<int>("sdInfo_w_u_colind");
1709  xt::pyarray<int>& sdInfo_w_v_rowptr = args.array<int>("sdInfo_w_v_rowptr");
1710  xt::pyarray<int>& sdInfo_w_v_colind = args.array<int>("sdInfo_w_v_colind");
1711  int offset_p = args.scalar<int>("offset_p");
1712  int offset_u = args.scalar<int>("offset_u");
1713  int offset_v = args.scalar<int>("offset_v");
1714  int offset_w = args.scalar<int>("offset_w");
1715  int stride_p = args.scalar<int>("stride_p");
1716  int stride_u = args.scalar<int>("stride_u");
1717  int stride_v = args.scalar<int>("stride_v");
1718  int stride_w = args.scalar<int>("stride_w");
1719  xt::pyarray<double>& globalResidual = args.array<double>("globalResidual");
1720  int nExteriorElementBoundaries_global = args.scalar<int>("nExteriorElementBoundaries_global");
1721  xt::pyarray<int>& exteriorElementBoundariesArray = args.array<int>("exteriorElementBoundariesArray");
1722  xt::pyarray<int>& elementBoundariesArray = args.array<int>("elementBoundariesArray");
1723  xt::pyarray<int>& elementBoundaryElementsArray = args.array<int>("elementBoundaryElementsArray");
1724  xt::pyarray<int>& elementBoundaryLocalElementBoundariesArray = args.array<int>("elementBoundaryLocalElementBoundariesArray");
1725  xt::pyarray<double>& ebqe_vf_ext = args.array<double>("ebqe_vf_ext");
1726  xt::pyarray<double>& bc_ebqe_vf_ext = args.array<double>("bc_ebqe_vf_ext");
1727  xt::pyarray<double>& ebqe_phi_ext = args.array<double>("ebqe_phi_ext");
1728  xt::pyarray<double>& bc_ebqe_phi_ext = args.array<double>("bc_ebqe_phi_ext");
1729  xt::pyarray<double>& ebqe_normal_phi_ext = args.array<double>("ebqe_normal_phi_ext");
1730  xt::pyarray<double>& ebqe_kappa_phi_ext = args.array<double>("ebqe_kappa_phi_ext");
1731  const xt::pyarray<double>& ebqe_vos_ext = args.array<double>("ebqe_vos_ext");
1732  const xt::pyarray<double>& ebqe_turb_var_0 = args.array<double>("ebqe_turb_var_0");
1733  const xt::pyarray<double>& ebqe_turb_var_1 = args.array<double>("ebqe_turb_var_1");
1734  xt::pyarray<int>& isDOFBoundary_p = args.array<int>("isDOFBoundary_p");
1735  xt::pyarray<int>& isDOFBoundary_u = args.array<int>("isDOFBoundary_u");
1736  xt::pyarray<int>& isDOFBoundary_v = args.array<int>("isDOFBoundary_v");
1737  xt::pyarray<int>& isDOFBoundary_w = args.array<int>("isDOFBoundary_w");
1738  xt::pyarray<int>& isAdvectiveFluxBoundary_p = args.array<int>("isAdvectiveFluxBoundary_p");
1739  xt::pyarray<int>& isAdvectiveFluxBoundary_u = args.array<int>("isAdvectiveFluxBoundary_u");
1740  xt::pyarray<int>& isAdvectiveFluxBoundary_v = args.array<int>("isAdvectiveFluxBoundary_v");
1741  xt::pyarray<int>& isAdvectiveFluxBoundary_w = args.array<int>("isAdvectiveFluxBoundary_w");
1742  xt::pyarray<int>& isDiffusiveFluxBoundary_u = args.array<int>("isDiffusiveFluxBoundary_u");
1743  xt::pyarray<int>& isDiffusiveFluxBoundary_v = args.array<int>("isDiffusiveFluxBoundary_v");
1744  xt::pyarray<int>& isDiffusiveFluxBoundary_w = args.array<int>("isDiffusiveFluxBoundary_w");
1745  xt::pyarray<double>& ebqe_bc_p_ext = args.array<double>("ebqe_bc_p_ext");
1746  xt::pyarray<double>& ebqe_bc_flux_mass_ext = args.array<double>("ebqe_bc_flux_mass_ext");
1747  xt::pyarray<double>& ebqe_bc_flux_mom_u_adv_ext = args.array<double>("ebqe_bc_flux_mom_u_adv_ext");
1748  xt::pyarray<double>& ebqe_bc_flux_mom_v_adv_ext = args.array<double>("ebqe_bc_flux_mom_v_adv_ext");
1749  xt::pyarray<double>& ebqe_bc_flux_mom_w_adv_ext = args.array<double>("ebqe_bc_flux_mom_w_adv_ext");
1750  xt::pyarray<double>& ebqe_bc_u_ext = args.array<double>("ebqe_bc_u_ext");
1751  xt::pyarray<double>& ebqe_bc_flux_u_diff_ext = args.array<double>("ebqe_bc_flux_u_diff_ext");
1752  xt::pyarray<double>& ebqe_penalty_ext = args.array<double>("ebqe_penalty_ext");
1753  xt::pyarray<double>& ebqe_bc_v_ext = args.array<double>("ebqe_bc_v_ext");
1754  xt::pyarray<double>& ebqe_bc_flux_v_diff_ext = args.array<double>("ebqe_bc_flux_v_diff_ext");
1755  xt::pyarray<double>& ebqe_bc_w_ext = args.array<double>("ebqe_bc_w_ext");
1756  xt::pyarray<double>& ebqe_bc_flux_w_diff_ext = args.array<double>("ebqe_bc_flux_w_diff_ext");
1757  xt::pyarray<double>& q_x = args.array<double>("q_x");
1758  xt::pyarray<double>& q_velocity = args.array<double>("q_velocity");
1759  xt::pyarray<double>& ebqe_velocity = args.array<double>("ebqe_velocity");
1760  xt::pyarray<double>& q_grad_u = args.array<double>("q_grad_u");
1761  xt::pyarray<double>& q_grad_v = args.array<double>("q_grad_v");
1762  xt::pyarray<double>& q_grad_w = args.array<double>("q_grad_w");
1763  xt::pyarray<double>& q_divU = args.array<double>("q_divU");
1764  xt::pyarray<double>& ebqe_grad_u = args.array<double>("ebqe_grad_u");
1765  xt::pyarray<double>& ebqe_grad_v = args.array<double>("ebqe_grad_v");
1766  xt::pyarray<double>& ebqe_grad_w = args.array<double>("ebqe_grad_w");
1767  xt::pyarray<double>& flux = args.array<double>("flux");
1768  xt::pyarray<double>& elementResidual_p_save = args.array<double>("elementResidual_p_save");
1769  xt::pyarray<int>& elementFlags = args.array<int>("elementFlags");
1770  xt::pyarray<int>& boundaryFlags = args.array<int>("boundaryFlags");
1771  xt::pyarray<double>& barycenters = args.array<double>("barycenters");
1772  xt::pyarray<double>& wettedAreas = args.array<double>("wettedAreas");
1773  xt::pyarray<double>& netForces_p = args.array<double>("netForces_p");
1774  xt::pyarray<double>& netForces_v = args.array<double>("netForces_v");
1775  xt::pyarray<double>& netMoments = args.array<double>("netMoments");
1776  xt::pyarray<double>& q_rho = args.array<double>("q_rho");
1777  xt::pyarray<double>& ebqe_rho = args.array<double>("ebqe_rho");
1778  xt::pyarray<double>& q_nu = args.array<double>("q_nu");
1779  xt::pyarray<double>& ebqe_nu = args.array<double>("ebqe_nu");
1780  int nParticles = args.scalar<int>("nParticles");
1781  double particle_epsFact = args.scalar<double>("particle_epsFact");
1782  double particle_alpha = args.scalar<double>("particle_alpha");
1783  double particle_beta = args.scalar<double>("particle_beta");
1784  double particle_penalty_constant = args.scalar<double>("particle_penalty_constant");
1785  xt::pyarray<double>& particle_signed_distances = args.array<double>("particle_signed_distances");
1786  xt::pyarray<double>& particle_signed_distance_normals = args.array<double>("particle_signed_distance_normals");
1787  xt::pyarray<double>& particle_velocities = args.array<double>("particle_velocities");
1788  xt::pyarray<double>& particle_centroids = args.array<double>("particle_centroids");
1789  xt::pyarray<double>& particle_netForces = args.array<double>("particle_netForces");
1790  xt::pyarray<double>& particle_netMoments = args.array<double>("particle_netMoments");
1791  xt::pyarray<double>& particle_surfaceArea = args.array<double>("particle_surfaceArea");
1792  double particle_nitsche = args.scalar<double>("particle_nitsche");
1793  int use_ball_as_particle = args.scalar<int>("use_ball_as_particle");
1794  xt::pyarray<double>& ball_center = args.array<double>("ball_center");
1795  xt::pyarray<double>& ball_radius = args.array<double>("ball_radius");
1796  xt::pyarray<double>& ball_velocity = args.array<double>("ball_velocity");
1797  xt::pyarray<double>& ball_angular_velocity = args.array<double>("ball_angular_velocity");
1798  xt::pyarray<double>& phisError = args.array<double>("phisError");
1799  xt::pyarray<double>& phisErrorNodal = args.array<double>("phisErrorNodal");
1800  int USE_SUPG = args.scalar<int>("USE_SUPG");
1801  int ARTIFICIAL_VISCOSITY = args.scalar<int>("ARTIFICIAL_VISCOSITY");
1802  double cMax = args.scalar<double>("cMax");
1803  double cE = args.scalar<double>("cE");
1804  int MULTIPLY_EXTERNAL_FORCE_BY_DENSITY = args.scalar<int>("MULTIPLY_EXTERNAL_FORCE_BY_DENSITY");
1805  xt::pyarray<double>& forcex = args.array<double>("forcex");
1806  xt::pyarray<double>& forcey = args.array<double>("forcey");
1807  xt::pyarray<double>& forcez = args.array<double>("forcez");
1808  int KILL_PRESSURE_TERM = args.scalar<int>("KILL_PRESSURE_TERM");
1809  double dt = args.scalar<double>("dt");
1810  xt::pyarray<double>& quantDOFs = args.array<double>("quantDOFs");
1811  int MATERIAL_PARAMETERS_AS_FUNCTION = args.scalar<int>("MATERIAL_PARAMETERS_AS_FUNCTION");
1812  xt::pyarray<double>& density_as_function = args.array<double>("density_as_function");
1813  xt::pyarray<double>& dynamic_viscosity_as_function = args.array<double>("dynamic_viscosity_as_function");
1814  xt::pyarray<double>& ebqe_density_as_function = args.array<double>("ebqe_density_as_function");
1815  xt::pyarray<double>& ebqe_dynamic_viscosity_as_function = args.array<double>("ebqe_dynamic_viscosity_as_function");
1816  double order_polynomial = args.scalar<double>("order_polynomial");
1817  xt::pyarray<double>& isActiveDOF = args.array<double>("isActiveDOF");
1818  int USE_SBM = args.scalar<int>("USE_SBM");
1819  xt::pyarray<double>& ncDrag = args.array<double>("ncDrag");
1820  xt::pyarray<double>& betaDrag = args.array<double>("betaDrag");
1821  xt::pyarray<double>& vos_vel_nodes = args.array<double>("vos_vel_nodes");
1822  xt::pyarray<double>& entropyResidualPerNode = args.array<double>("entropyResidualPerNode");
1823  xt::pyarray<double>& laggedEntropyResidualPerNode = args.array<double>("laggedEntropyResidualPerNode");
1824  xt::pyarray<double>& uStar_dMatrix = args.array<double>("uStar_dMatrix");
1825  xt::pyarray<double>& vStar_dMatrix = args.array<double>("vStar_dMatrix");
1826  xt::pyarray<double>& wStar_dMatrix = args.array<double>("wStar_dMatrix");
1827  int numDOFs_1D = args.scalar<int>("numDOFs_1D");
1828  int NNZ_1D = args.scalar<int>("NNZ_1D");
1829  xt::pyarray<int>& csrRowIndeces_1D = args.array<int>("csrRowIndeces_1D");
1830  xt::pyarray<int>& csrColumnOffsets_1D = args.array<int>("csrColumnOffsets_1D");
1831  xt::pyarray<int>& rowptr_1D = args.array<int>("rowptr_1D");
1832  xt::pyarray<int>& colind_1D = args.array<int>("colind_1D");
1833  xt::pyarray<double>& isBoundary_1D = args.array<double>("isBoundary_1D");
1834  int INT_BY_PARTS_PRESSURE = args.scalar<int>("INT_BY_PARTS_PRESSURE");
1835  gf.useExact=useExact;
1836  gf_s.useExact=useExact;
1837  surrogate_boundaries.clear();
1840  double cut_cell_boundary_length=0.0, p_force_x=0.0, p_force_y=0.0;
1841  register double element_uStar_He[nElements_global], element_vStar_He[nElements_global];
1842  uStar_hi.resize(numDOFs_1D,0.0);
1843  vStar_hi.resize(numDOFs_1D,0.0);
1844  den_hi.resize(numDOFs_1D,0.0);
1845  uStar_min_hiHe.resize(numDOFs_1D,0.0);
1846  vStar_min_hiHe.resize(numDOFs_1D,0.0);
1847  uStar_gamma.resize(numDOFs_1D,0.0);
1848  vStar_gamma.resize(numDOFs_1D,0.0);
1849  TransportMatrix.resize(NNZ_1D,0.0);
1850  TransposeTransportMatrix.resize(NNZ_1D,0.0);
1851  uStar_psi.resize(numDOFs_1D,0.0);
1852  vStar_psi.resize(numDOFs_1D,0.0);
1853 
1854  if (ARTIFICIAL_VISCOSITY==3 || ARTIFICIAL_VISCOSITY==4)
1855  {
1856  if (TransportMatrix.size() != NNZ_1D)
1857  TransportMatrix.resize(NNZ_1D);
1858  if (TransposeTransportMatrix.size() != NNZ_1D)
1859  TransposeTransportMatrix.resize(NNZ_1D);
1860  if (psi.size() != numDOFs_1D)
1861  psi.resize(numDOFs_1D);
1862  for (int i=0; i<NNZ_1D; i++)
1863  {
1864  uStar_dMatrix[i]=0.;
1865  vStar_dMatrix[i]=0.;
1866  TransportMatrix[i] = 0.;
1867  TransposeTransportMatrix[i] = 0.;
1868  }
1869  for (int i=0; i<numDOFs_1D; i++)
1870  {
1871  uStar_min_hiHe[i] = 1E100;
1872  vStar_min_hiHe[i] = 1E100;
1873  entropyResidualPerNode[i]=0.;
1874  uStar_hi[i] = 0.;
1875  vStar_hi[i] = 0.;
1876  den_hi[i] = 0.;
1877  }
1878  }
1879 
1880  //
1881  //loop over elements to compute volume integrals and load them into element and global residual
1882  //
1883  double mesh_volume_conservation=0.0,
1884  mesh_volume_conservation_weak=0.0,
1885  mesh_volume_conservation_err_max=0.0,
1886  mesh_volume_conservation_err_max_weak=0.0;
1887  double globalConservationError=0.0;
1888  const int nQuadraturePoints_global(nElements_global*nQuadraturePoints_element);
1889  for(int eN=0;eN<nElements_global;eN++)
1890  {
1891  register double elementTransport[nDOF_test_element][nDOF_trial_element];
1892  register double elementTransposeTransport[nDOF_test_element][nDOF_trial_element];
1893  //declare local storage for element residual and initialize
1894  register double elementResidual_p[nDOF_test_element],elementResidual_mesh[nDOF_test_element],
1895  elementResidual_u[nDOF_test_element],
1896  elementResidual_v[nDOF_test_element],
1897  mom_u_source_i[nDOF_test_element],
1898  mom_v_source_i[nDOF_test_element],
1899  betaDrag_i[nDOF_test_element],
1900  vos_i[nDOF_test_element],
1901  phisErrorElement[nDOF_test_element],
1902  //elementResidual_w[nDOF_test_element],
1903  elementEntropyResidual[nDOF_test_element],
1904  eps_rho,eps_mu;
1905  //const double* elementResidual_w(NULL);
1906  double element_active=1.0;//use 1 since by default it is ibm
1907  double mesh_volume_conservation_element=0.0,
1908  mesh_volume_conservation_element_weak=0.0;
1909  // for entropy viscosity
1910  double linVisc_eN = 0, nlinVisc_eN_num = 0, nlinVisc_eN_den = 0;
1911  // for hessians of uStar
1912  double det_hess_uStar_Ke=0.0, det_hess_vStar_Ke=0.0, area_Ke=0.0;
1913  for (int i=0;i<nDOF_test_element;i++)
1914  {
1915  int eN_i = eN*nDOF_test_element+i;
1916  elementResidual_p_save[eN_i]=0.0;
1917  elementResidual_mesh[i]=0.0;
1918  elementResidual_p[i]=0.0;
1919  elementResidual_u[i]=0.0;
1920  elementResidual_v[i]=0.0;
1921  mom_u_source_i[i]=0.0;
1922  mom_v_source_i[i]=0.0;
1923  betaDrag_i[i]=0.0;
1924  vos_i[i]=0.0;
1925  phisErrorElement[i]=0.0;
1926  /* elementResidual_w[i]=0.0; */
1927  elementEntropyResidual[i]=0.0;
1928  if (ARTIFICIAL_VISCOSITY==3 || ARTIFICIAL_VISCOSITY==4)
1929  {
1930  for (int j=0;j<nDOF_trial_element;j++)
1931  {
1932  elementTransport[i][j]=0.0;
1933  elementTransposeTransport[i][j]=0.0;
1934  }
1935  }
1936  }//i
1937  //Use for plotting result
1938  if(use_ball_as_particle==1)
1939  {
1940  for (int I=0;I<nDOF_mesh_trial_element;I++)
1941  get_distance_to_ball(nParticles, ball_center.data(), ball_radius.data(),
1942  mesh_dof[3*mesh_l2g[eN*nDOF_mesh_trial_element+I]+0],
1943  mesh_dof[3*mesh_l2g[eN*nDOF_mesh_trial_element+I]+1],
1944  mesh_dof[3*mesh_l2g[eN*nDOF_mesh_trial_element+I]+2],
1945  phi_solid_nodes[mesh_l2g[eN*nDOF_mesh_trial_element+I]]);
1946  }
1947  if(CUT_CELL_INTEGRATION > 0)
1948  {
1949  //
1950  //detect cut cells, for unfitted fem we want all cells cut by phi=0 or with phi=0 lying on any boundary
1951  //
1952  double _distance[nDOF_mesh_trial_element]={0.0};
1953  int pos_counter=0;
1954  for (int I=0;I<nDOF_mesh_trial_element;I++)
1955  {
1956  if(use_ball_as_particle==1)
1957  {
1958  get_distance_to_ball(nParticles, ball_center.data(), ball_radius.data(),
1959  mesh_dof[3*mesh_l2g[eN*nDOF_mesh_trial_element+I]+0],
1960  mesh_dof[3*mesh_l2g[eN*nDOF_mesh_trial_element+I]+1],
1961  mesh_dof[3*mesh_l2g[eN*nDOF_mesh_trial_element+I]+2],
1962  _distance[I]);
1963  }
1964  else
1965  {
1966  _distance[I] = phi_solid_nodes[mesh_l2g[eN*nDOF_mesh_trial_element+I]];
1967  }
1968  if ( _distance[I] > 0)//fully in fluid
1969  pos_counter++;
1970  }
1971  if (pos_counter == 3)
1972  {
1973  element_active = 1.0;
1974  }
1975  else if (pos_counter == 0)
1976  {
1977  element_active = 1.0;
1978  }
1979  else
1980  {
1981  element_active = 1.0;//for now leave all elements active
1982  //P1 interpolation operator; only 2D for now
1983  double GI[6*3];//3 DOF to 6DOF for linear interpolation onto 4T refinement
1984  double sub_mesh_dof[6*3], sub_u_dof[15], sub_v_dof[15], sub_phi_dof[6], sub_p_dof[6];//6 3D points
1985  int boundaryNodes[6] = {0,0,0,0,0,0};
1986  std::vector<int> ls_nodes;
1987  for (int I=0;I<nDOF_mesh_trial_element;I++)
1988  {
1989  for (int K=0;K<nDOF_mesh_trial_element;K++)
1990  {
1991  GI[I*3+K] = 0.0;
1992  if (I==K)
1993  {
1994  GI[I*3+K] = 1.0;
1995  }
1996  }
1997  const double eps = 1.0e-4;
1998  double delta_phi=0.0,theta;
1999  delta_phi = _distance[(I+1)%3] - _distance[I];
2000  if (fabs(delta_phi) > eps)//level sets are not parallel to edge
2001  //need tolerance selection guidance
2002  {
2003  theta = -_distance[I]/delta_phi;//zero level set is at theta*xIp1+(1-theta)*xI
2004  if (theta > 1.0-eps || theta < eps)//zero level does NOT intersect between nodes; it may got through a node
2005  {
2006  if (theta > 1.0-eps && theta <= 1.0)//
2007  {
2008  ls_nodes.push_back((I+1)%3);
2009  //todo, fix connectivity for this case--can't use 4T
2010  assert(false);
2011  }
2012  else if (theta > 0.0 && theta < eps)//
2013  {
2014  ls_nodes.push_back(I);
2015  assert(false);
2016  }
2017  else
2018  theta = 0.5;//just put the subelement node at midpoint
2019  }
2020  else
2021  {
2022  boundaryNodes[3+I]=1;
2023  ls_nodes.push_back(3+I);
2024  }
2025  }
2026  else //level set lies on edge
2027  {
2028  theta = 0.5;
2029  if (fabs(_distance[I]) <= eps) //edge IS the zero level set
2030  {
2031  boundaryNodes[I]=1;
2032  boundaryNodes[3+I]=1;
2033  boundaryNodes[(I+1)%3]=1;
2034  ls_nodes.push_back(I);
2035  ls_nodes.push_back((I+1)%3);
2036  }
2037  }
2038  assert(theta <= 1.0);
2039  GI[3*3 + I*3 + I] = 1.0-theta;
2040  GI[3*3 + I*3 + (I+1)%3] = theta;
2041  GI[3*3 + I*3 + (I+2)%3] = 0.0;
2042  }
2043  if (ls_nodes.size() != 2)
2044  {
2045  std::cout<<"level set nodes not 2 "<<ls_nodes.size()<<std::endl;
2046  for(int i=0;i<ls_nodes.size();i++)
2047  std::cout<<ls_nodes[i]<<std::endl;
2048  std::sort(ls_nodes.begin(),ls_nodes.end());
2049  }
2050  int sub_mesh_l2g[12] = {0,3,5,
2051  1,4,3,
2052  2,5,4,
2053  3,4,5};
2054  for (int I=0; I<6; I++)
2055  {
2056  sub_phi_dof[I] = 0.0;
2057  sub_p_dof[I] = 0.0;
2058  for (int K=0; K<3; K++)
2059  sub_mesh_dof[I*3+K] = 0.0;
2060  for (int J=0; J<3; J++)
2061  {
2062  for (int K=0; K<3; K++)
2063  {
2064  sub_mesh_dof[I*3+K] += GI[I*3+J]*mesh_dof[3*mesh_l2g[eN*nDOF_mesh_trial_element+J]+K];
2065  }
2066  sub_phi_dof[I] += GI[I*3+J]*phi_solid_nodes[mesh_l2g[eN*nDOF_mesh_trial_element+J]];
2067  sub_p_dof[I] += GI[I*3+J]*p_dof[p_l2g[eN*nDOF_per_element_pressure+J]];
2068  }
2069  }
2070  int L = ls_nodes[0], R=ls_nodes[1];
2071  double DX=sub_mesh_dof[L*3+0] - sub_mesh_dof[R*3+0];
2072  double DY=sub_mesh_dof[L*3+1] - sub_mesh_dof[R*3+1];
2073  double DS = std::sqrt(DX*DX+DY*DY);
2074  double nx = -DY/DS, ny = DX/DS;
2075  double nxL,nyL,nxR,nyR;
2076  get_normal_to_ith_ball(nParticles,ball_center.data(),ball_radius.data(),
2077  0,
2078  sub_mesh_dof[L*3+0],sub_mesh_dof[L*3+1],0.0,
2079  nxL,nyL);
2080  get_normal_to_ith_ball(nParticles,ball_center.data(),ball_radius.data(),
2081  0,
2082  sub_mesh_dof[R*3+0],sub_mesh_dof[R*3+1],0.0,
2083  nxR,nyR);
2084  //std::cout<<"dot L "<<nx_tmp*nxL+ny_tmp*nyL<<std::endl;
2085  //std::cout<<"dot R "<<nx_tmp*nxR+ny_tmp*nyR<<std::endl;
2086  double n_fluid_sign = -sgn(nx*0.5*(nxL+nxR)+ny*0.5*(nyL+nyR));
2087  nx*=n_fluid_sign;
2088  ny*=n_fluid_sign;
2089  //double dot_test=std::fabs(nx_tmp*nx+ny_tmp*ny);
2090  //assert(dot_test > 1.0-1.0e-4 && dot_test < 1.0 + 1.0e-4);
2091  cut_cell_boundary_length += DS;
2092  p_force_x += sub_p_dof[L]*nx*0.5*DS + sub_p_dof[R]*nx*0.5*DS;
2093  p_force_y += sub_p_dof[L]*ny*0.5*DS + sub_p_dof[R]*ny*0.5*DS;
2094  //TODO for P2
2095  //1. Now define the Lagrange nodes for P2 on the submesh X
2096  //2. Define and evaluate the P2 trial functions for the parent element at the new submesh P2 nodes. X
2097  //3. Form the G2I interpolation operator X
2098  //4. Interpolate the P2 DOF from the parent element to the submesh DOF X
2099  double G2I[15*6];//6 DOF to 15 DOF for quadratic interpolation onto 4T refinement
2100  double lagrangeNodes[9*3];//9 new quadratic nodes in addition to the 6 we have
2101  for (int K=0;K<3;K++)
2102  {
2103  lagrangeNodes[0*3+K] = 0.5*(sub_mesh_dof[0*3+K] + sub_mesh_dof[3*3+0*3+K]);
2104  lagrangeNodes[1*3+K] = 0.5*(sub_mesh_dof[1*3+K] + sub_mesh_dof[3*3+0*3+K]);
2105  lagrangeNodes[2*3+K] = 0.5*(sub_mesh_dof[1*3+K] + sub_mesh_dof[3*3+1*3+K]);
2106  lagrangeNodes[3*3+K] = 0.5*(sub_mesh_dof[2*3+K] + sub_mesh_dof[3*3+1*3+K]);
2107  lagrangeNodes[4*3+K] = 0.5*(sub_mesh_dof[2*3+K] + sub_mesh_dof[3*3+2*3+K]);
2108  lagrangeNodes[5*3+K] = 0.5*(sub_mesh_dof[0*3+K] + sub_mesh_dof[3*3+2*3+K]);
2109  lagrangeNodes[6*3+K] = 0.5*(sub_mesh_dof[3*3+0*3+K] + sub_mesh_dof[3*3+1*3+K]);
2110  lagrangeNodes[7*3+K] = 0.5*(sub_mesh_dof[3*3+1*3+K] + sub_mesh_dof[3*3+2*3+K]);
2111  lagrangeNodes[8*3+K] = 0.5*(sub_mesh_dof[3*3+2*3+K] + sub_mesh_dof[3*3+0*3+K]);
2112  }
2113  double lambda[3];
2114  for (int I=0;I<6;I++)
2115  {
2116  baryCoords(&sub_mesh_dof[0],&sub_mesh_dof[1*3],&sub_mesh_dof[2*3],&sub_mesh_dof[I*3],lambda);
2117  //std::cout<<"lambda"<<'\t'<<lambda[0]<<'\t'<<lambda[1]<<'\t'<<lambda[2]<<std::endl;
2118  G2I[I*6+0] = lambda[0]*(2.0*lambda[0] - 1.0);
2119  G2I[I*6+1] = lambda[1]*(2.0*lambda[1] - 1.0);
2120  G2I[I*6+2] = lambda[2]*(2.0*lambda[2] - 1.0);
2121  G2I[I*6+3] = 4.0*lambda[0]*lambda[1];
2122  G2I[I*6+4] = 4.0*lambda[1]*lambda[2];
2123  G2I[I*6+5] = 4.0*lambda[2]*lambda[0];
2124  }
2125  for (int I=0;I<9;I++)
2126  {
2127  baryCoords(&sub_mesh_dof[0],&sub_mesh_dof[1*3],&sub_mesh_dof[2*3],&lagrangeNodes[I*3],lambda);
2128  G2I[6*6 + I*6 + 0] = lambda[0]*(2.0*lambda[0] - 1.0);
2129  G2I[6*6 + I*6 + 1] = lambda[1]*(2.0*lambda[1] - 1.0);
2130  G2I[6*6 + I*6 + 2] = lambda[2]*(2.0*lambda[2] - 1.0);
2131  G2I[6*6 + I*6 + 3] = 4.0*lambda[0]*lambda[1];
2132  G2I[6*6 + I*6 + 4] = 4.0*lambda[1]*lambda[2];
2133  G2I[6*6 + I*6 + 5] = 4.0*lambda[2]*lambda[0];
2134  }
2135  for (int I=0; I<15; I++)
2136  {
2137  sub_u_dof[I] = 0.0;
2138  sub_v_dof[I] = 0.0;
2139  for (int J=0; J<6; J++)
2140  {
2141  sub_u_dof[I] += G2I[I*6+J]*u_dof[vel_l2g[eN*nDOF_trial_element+J]];
2142  sub_v_dof[I] += G2I[I*6+J]*v_dof[vel_l2g[eN*nDOF_trial_element+J]];
2143  }
2144  }
2145  for (int esN=0;esN<4;esN++)
2146  {
2147  std::cout<<sub_mesh_l2g[esN*3]<<'\t'<<sub_mesh_l2g[esN*3+1]<<'\t'<<sub_mesh_l2g[esN*3+2]<<std::endl;
2148  }
2149  for (int I=0; I<6; I++)
2150  {
2151  std::cout<<sub_mesh_dof[I*3+0]<<'\t'<<sub_mesh_dof[I*3+1]<<'\t'<<sub_mesh_dof[I*3+2]<<'\t'<<boundaryNodes[I]<<'\t'<<sub_phi_dof[I]<<'\t'<<sub_p_dof[I]<<'\t'<<sub_u_dof[I]<<'\t'<<sub_v_dof[I]<<'\t'<<G2I[I*6+0]<<'\t'<<G2I[I*6+1]<<'\t'<<G2I[I*6+2]<<'\t'<<G2I[I*6+3]<<'\t'<<G2I[I*6+4]<<'\t'<<G2I[I*6+5]<<std::endl;
2152  }
2153  }
2154  }
2155  if(USE_SBM>0)
2156  {
2157  //
2158  //detect cut cells
2159  //
2160  double _distance[nDOF_mesh_trial_element]={0.0};
2161  int pos_counter=0;
2162  for (int I=0;I<nDOF_mesh_trial_element;I++)
2163  {
2164  if(use_ball_as_particle==1)
2165  {
2166  get_distance_to_ball(nParticles, ball_center.data(), ball_radius.data(),
2167  mesh_dof[3*mesh_l2g[eN*nDOF_mesh_trial_element+I]+0],
2168  mesh_dof[3*mesh_l2g[eN*nDOF_mesh_trial_element+I]+1],
2169  mesh_dof[3*mesh_l2g[eN*nDOF_mesh_trial_element+I]+2],
2170  _distance[I]);
2171  }
2172  else
2173  {
2174  _distance[I] = phi_solid_nodes[mesh_l2g[eN*nDOF_mesh_trial_element+I]];
2175  }
2176  if ( _distance[I] >= 0)
2177  pos_counter++;
2178  }
2179  if (pos_counter == 2)
2180  {
2181  element_active=0.0;
2182  int opp_node=-1;
2183  for (int I=0;I<nDOF_mesh_trial_element;I++)
2184  {
2185  // quantDOFs[vel_l2g[eN*nDOF_trial_element + I]] = 2.0;//for test
2186  if (_distance[I] < 0)
2187  {
2188  opp_node = I;
2189  // quantDOFs[vel_l2g[eN*nDOF_trial_element + I]] = 1.0;//for test
2190  }
2191  }
2192  assert(opp_node >=0);
2193  assert(opp_node <nDOF_mesh_trial_element);
2194  //For parallel. Two reasons:
2195  //if none of nodes of this edge is owned by this processor,
2196  //1. The surrogate_boundary_elements corresponding to this edge is -1, which gives 0 JacDet and infty h_penalty.
2197  //2. there is no contribution of the integral over this edge to Jacobian and residual.
2198  const int ebN = elementBoundariesArray[eN*nDOF_mesh_trial_element+opp_node];//only works for simplices
2199  const int eN_oppo = (eN == elementBoundaryElementsArray[ebN*2+0])?elementBoundaryElementsArray[ebN*2+1]:elementBoundaryElementsArray[ebN*2+0];
2200  if((mesh_l2g[eN*nDOF_mesh_trial_element+(opp_node+1)%3]<nNodes_owned
2201  || mesh_l2g[eN*nDOF_mesh_trial_element+(opp_node+2)%3]<nNodes_owned)
2202  && eN_oppo!= -1)
2203  {
2204  surrogate_boundaries.push_back(ebN);
2205  //now find which element neighbor this element is
2206  //YY: what if this face is a boundary face?
2207  if (eN == elementBoundaryElementsArray[ebN*2+0])//should be ebN
2208  surrogate_boundary_elements.push_back(1);
2209  else
2210  surrogate_boundary_elements.push_back(0);
2211 
2212  //check which particle this surrogate edge is related to.
2213  int j=-1;
2214  if(use_ball_as_particle==1)
2215  {
2216  double middle_point_coord[3]={0.0};
2217  double middle_point_distance;
2218  middle_point_coord[0] = 0.5*(mesh_dof[3*mesh_l2g[eN*nDOF_mesh_trial_element+(opp_node+1)%3]+0]+mesh_dof[3*mesh_l2g[eN*nDOF_mesh_trial_element+(opp_node+2)%3]+0]);
2219  middle_point_coord[1] = 0.5*(mesh_dof[3*mesh_l2g[eN*nDOF_mesh_trial_element+(opp_node+1)%3]+1]+mesh_dof[3*mesh_l2g[eN*nDOF_mesh_trial_element+(opp_node+2)%3]+1]);
2220  j = get_distance_to_ball(nParticles, ball_center.data(), ball_radius.data(),
2221  middle_point_coord[0],middle_point_coord[1],middle_point_coord[2],
2222  middle_point_distance);
2223 
2224  }
2225  else
2226  {
2227  //The method is to check one quadrature point inside of this element.
2228  //It works based on the assumption that the distance between any two particles
2229  //is larger than 2*h_min, otherwise it depends on the choice of the quadrature point
2230  //or one edge belongs to two particles .
2231  //But in any case, phi_s is well defined as the minimum.
2232  double distance=1e10, distance_to_ith_particle;
2233  for (int i=0;i<nParticles;++i)
2234  {
2235  distance_to_ith_particle=particle_signed_distances[i*nElements_global*nQuadraturePoints_element
2236  +eN*nQuadraturePoints_element
2237  +0];//0-th quadrature point
2238  if (distance_to_ith_particle<distance)
2239  {
2240  distance = distance_to_ith_particle;
2241  j = i;
2242  }
2243  }
2244  }
2245  surrogate_boundary_particle.push_back(j);
2246  }else{
2247  //If the integral over the surrogate boundary is needed, we have to make sure all edges are in surrogate_boundaries,
2248  //which is based on the assumption that if none of its nodes is owned by the processor, then the edge is not owned
2249  //by the processor. This assert is used to make sure this is the case.
2250  if(ebN<nElementBoundaries_owned)//eN_oppo ==-1
2251  {
2252  assert(eN_oppo==-1);
2253  }
2254  }
2255  }
2256  else if (pos_counter == 3)
2257  {
2258  element_active=1.0;
2259  for (int i=0;i<nDOF_test_element;i++)
2260  {
2261  isActiveDOF[offset_u+stride_u*vel_l2g[eN*nDOF_trial_element + i]]=1.0;
2262  isActiveDOF[offset_v+stride_v*vel_l2g[eN*nDOF_trial_element + i]]=1.0;
2263  }
2264  }
2265  else
2266  {
2267  element_active=0.0;
2268  }
2269  }
2270  double element_phi[nDOF_mesh_trial_element], element_phi_s[nDOF_mesh_trial_element];
2271  for (int j=0;j<nDOF_mesh_trial_element;j++)
2272  {
2273  register int eN_j = eN*nDOF_mesh_trial_element+j;
2274  element_phi[j] = phi_dof[p_l2g[eN_j]];
2275  element_phi_s[j] = phi_solid_nodes[p_l2g[eN_j]];
2276  }
2277  double element_nodes[nDOF_mesh_trial_element*3];
2278  for (int i=0;i<nDOF_mesh_trial_element;i++)
2279  {
2280  register int eN_i=eN*nDOF_mesh_trial_element+i;
2281  for(int I=0;I<3;I++)
2282  element_nodes[i*3 + I] = mesh_dof[mesh_l2g[eN_i]*3 + I];
2283  }//i
2284  gf_s.calculate(element_phi_s, element_nodes, x_ref.data(), false);
2285  gf.calculate(element_phi, element_nodes, x_ref.data(), false);
2286  //
2287  //loop over quadrature points and compute integrands
2288  //
2289  for(int k=0;k<nQuadraturePoints_element;k++)
2290  {
2291  gf.set_quad(k);
2292  gf_s.set_quad(k);
2293  //compute indices and declare local storage
2294  register int eN_k = eN*nQuadraturePoints_element+k,
2295  eN_k_nSpace = eN_k*nSpace,
2296  eN_k_3d = eN_k*3,
2297  eN_nDOF_trial_element = eN*nDOF_trial_element;
2298  register double p=0.0,u=0.0,v=0.0,w=0.0,un=0.0,vn=0.0,wn=0.0,
2299  grad_p[nSpace],grad_u[nSpace],grad_v[nSpace],grad_w[nSpace],
2300  hess_u[nSpace2],hess_v[nSpace2],
2301  mom_u_acc=0.0,
2302  dmom_u_acc_u=0.0,
2303  mom_v_acc=0.0,
2304  dmom_v_acc_v=0.0,
2305  mom_w_acc=0.0,
2306  dmom_w_acc_w=0.0,
2307  mass_adv[nSpace],
2308  dmass_adv_u[nSpace],
2309  dmass_adv_v[nSpace],
2310  dmass_adv_w[nSpace],
2311  mom_u_adv[nSpace],
2312  dmom_u_adv_u[nSpace],
2313  dmom_u_adv_v[nSpace],
2314  dmom_u_adv_w[nSpace],
2315  mom_v_adv[nSpace],
2316  dmom_v_adv_u[nSpace],
2317  dmom_v_adv_v[nSpace],
2318  dmom_v_adv_w[nSpace],
2319  mom_w_adv[nSpace],
2320  dmom_w_adv_u[nSpace],
2321  dmom_w_adv_v[nSpace],
2322  dmom_w_adv_w[nSpace],
2323  mom_uu_diff_ten[nSpace],
2324  mom_vv_diff_ten[nSpace],
2325  mom_ww_diff_ten[nSpace],
2326  mom_uv_diff_ten[1],
2327  mom_uw_diff_ten[1],
2328  mom_vu_diff_ten[1],
2329  mom_vw_diff_ten[1],
2330  mom_wu_diff_ten[1],
2331  mom_wv_diff_ten[1],
2332  mom_u_source=0.0,
2333  mom_v_source=0.0,
2334  mom_w_source=0.0,
2335  mom_u_ham=0.0,
2336  dmom_u_ham_grad_p[nSpace],
2337  dmom_u_ham_grad_u[nSpace],
2338  mom_v_ham=0.0,
2339  dmom_v_ham_grad_p[nSpace],
2340  dmom_v_ham_grad_v[nSpace],
2341  mom_w_ham=0.0,
2342  dmom_w_ham_grad_p[nSpace],
2343  dmom_w_ham_grad_w[nSpace],
2344  mom_u_acc_t=0.0,
2345  dmom_u_acc_u_t=0.0,
2346  mom_v_acc_t=0.0,
2347  dmom_v_acc_v_t=0.0,
2348  mom_w_acc_t=0.0,
2349  dmom_w_acc_w_t=0.0,
2350  pdeResidual_p=0.0,
2351  pdeResidual_u=0.0,
2352  pdeResidual_v=0.0,
2353  pdeResidual_w=0.0,
2354  Lstar_u_p[nDOF_test_element],
2355  Lstar_v_p[nDOF_test_element],
2356  Lstar_w_p[nDOF_test_element],
2357  Lstar_u_u[nDOF_test_element],
2358  Lstar_v_v[nDOF_test_element],
2359  Lstar_w_w[nDOF_test_element],
2360  Lstar_p_u[nDOF_test_element],
2361  Lstar_p_v[nDOF_test_element],
2362  Lstar_p_w[nDOF_test_element],
2363  subgridError_p=0.0,
2364  subgridError_u=0.0,
2365  subgridError_v=0.0,
2366  subgridError_w=0.0,
2367  tau_p=0.0,tau_p0=0.0,tau_p1=0.0,
2368  tau_v=0.0,tau_v0=0.0,tau_v1=0.0,
2369  jac[nSpace*nSpace],
2370  jacDet,
2371  jacInv[nSpace*nSpace],
2372  p_grad_trial[nDOF_trial_element*nSpace],vel_grad_trial[nDOF_trial_element*nSpace],
2373  vel_hess_trial[nDOF_trial_element*nSpace2],
2374  p_test_dV[nDOF_trial_element],vel_test_dV[nDOF_trial_element],
2375  p_grad_test_dV[nDOF_test_element*nSpace],vel_grad_test_dV[nDOF_test_element*nSpace],
2376  u_times_vel_grad_test_dV[nDOF_test_element*nSpace], // For entropy residual
2377  v_times_vel_grad_test_dV[nDOF_test_element*nSpace], // For entropy residual
2378  dV,x,y,z,xt,yt,zt,
2379  //
2380  porosity,
2381  //meanGrainSize,
2382  mass_source,
2383  dmom_u_source[nSpace],
2384  dmom_v_source[nSpace],
2385  dmom_w_source[nSpace],
2386  //
2387  velStar[nSpace], hess_uStar[nSpace2], hess_vStar[nSpace2],
2388  //
2389  G[nSpace*nSpace],G_dd_G,tr_G,norm_Rv,h_phi, dmom_adv_star[nSpace],dmom_adv_sge[nSpace];
2390  //get jacobian, etc for mapping reference element
2391  ck.calculateMapping_element(eN,
2392  k,
2393  mesh_dof.data(),
2394  mesh_l2g.data(),
2395  mesh_trial_ref.data(),
2396  mesh_grad_trial_ref.data(),
2397  jac,
2398  jacDet,
2399  jacInv,
2400  x,y,z);
2401  ck.calculateH_element(eN,
2402  k,
2403  nodeDiametersArray.data(),
2404  mesh_l2g.data(),
2405  mesh_trial_ref.data(),
2406  h_phi);
2407  ck.calculateMappingVelocity_element(eN,
2408  k,
2409  mesh_velocity_dof.data(),
2410  mesh_l2g.data(),
2411  mesh_trial_ref.data(),
2412  xt,yt,zt);
2413  //xt=0.0;yt=0.0;zt=0.0;
2414  //std::cout<<"xt "<<xt<<'\t'<<yt<<'\t'<<zt<<std::endl;
2415  //get the physical integration weight
2416  dV = fabs(jacDet)*dV_ref[k];
2417  ck.calculateG(jacInv,G,G_dd_G,tr_G);
2418  //ck.calculateGScale(G,&normal_phi[eN_k_nSpace],h_phi);
2419 
2420  eps_rho = epsFact_rho*(useMetrics*h_phi+(1.0-useMetrics)*elementDiameter[eN]);
2421  eps_mu = epsFact_mu *(useMetrics*h_phi+(1.0-useMetrics)*elementDiameter[eN]);
2422  double particle_eps = particle_epsFact*(useMetrics*h_phi+(1.0-useMetrics)*elementDiameter[eN]);
2423 
2424  //get the trial function gradients
2425  /* ck.gradTrialFromRef(&p_grad_trial_ref[k*nDOF_trial_element*nSpace],jacInv,p_grad_trial); */
2426  ck.gradTrialFromRef(&vel_grad_trial_ref[k*nDOF_trial_element*nSpace],jacInv,vel_grad_trial);
2427  ck.hessTrialFromRef(&vel_hess_trial_ref[k*nDOF_trial_element*nSpace2],jacInv,vel_hess_trial);
2428  //get the solution
2429  /* ck.valFromDOF(p_dof,&p_l2g[eN_nDOF_trial_element],&p_trial_ref[k*nDOF_trial_element],p); */
2430  p = q_p[eN_k];
2431  // get solution at quad points
2432  ck.valFromDOF(u_dof.data(),&vel_l2g[eN_nDOF_trial_element],&vel_trial_ref[k*nDOF_trial_element],u);
2433  ck.valFromDOF(v_dof.data(),&vel_l2g[eN_nDOF_trial_element],&vel_trial_ref[k*nDOF_trial_element],v);
2434  /* ck.valFromDOF(w_dof,&vel_l2g[eN_nDOF_trial_element],&vel_trial_ref[k*nDOF_trial_element],w); */
2435  // get old solution at quad points
2436  ck.valFromDOF(u_dof_old.data(),&vel_l2g[eN_nDOF_trial_element],&vel_trial_ref[k*nDOF_trial_element],un);
2437  ck.valFromDOF(v_dof_old.data(),&vel_l2g[eN_nDOF_trial_element],&vel_trial_ref[k*nDOF_trial_element],vn);
2438  /* ck.valFromDOF(w_dof_old,&vel_l2g[eN_nDOF_trial_element],&vel_trial_ref[k*nDOF_trial_element],wn); */
2439  //get the solution gradients
2440  /* ck.gradFromDOF(p_dof,&p_l2g[eN_nDOF_trial_element],p_grad_trial,grad_p); */
2441  for (int I=0;I<nSpace;I++)
2442  grad_p[I] = q_grad_p[eN_k_nSpace + I];
2443  ck.gradFromDOF(u_dof.data(),&vel_l2g[eN_nDOF_trial_element],vel_grad_trial,grad_u);
2444  ck.gradFromDOF(v_dof.data(),&vel_l2g[eN_nDOF_trial_element],vel_grad_trial,grad_v);
2445  ck.hessFromDOF(u_dof.data(),&vel_l2g[eN_nDOF_trial_element],vel_hess_trial,hess_u);
2446  ck.hessFromDOF(v_dof.data(),&vel_l2g[eN_nDOF_trial_element],vel_hess_trial,hess_v);
2447  ck.hessFromDOF(uStar_dof.data(),&vel_l2g[eN_nDOF_trial_element],vel_hess_trial,hess_uStar);
2448  ck.hessFromDOF(vStar_dof.data(),&vel_l2g[eN_nDOF_trial_element],vel_hess_trial,hess_vStar);
2449  /* ck.gradFromDOF(w_dof,&vel_l2g[eN_nDOF_trial_element],vel_grad_trial,grad_w); */
2450  //precalculate test function products with integration weights
2451  for (int j=0;j<nDOF_trial_element;j++)
2452  {
2453  /* p_test_dV[j] = p_test_ref[k*nDOF_trial_element+j]*dV; */
2454  vel_test_dV[j] = vel_test_ref[k*nDOF_trial_element+j]*dV;
2455  for (int I=0;I<nSpace;I++)
2456  {
2457  /* p_grad_test_dV[j*nSpace+I] = p_grad_trial[j*nSpace+I]*dV;//cek warning won't work for Petrov-Galerkin */
2458  vel_grad_test_dV[j*nSpace+I] = vel_grad_trial[j*nSpace+I]*dV;//cek warning won't work for Petrov-Galerkin
2459  if (ARTIFICIAL_VISCOSITY==4)
2460  {
2461  // mql: for entropy residual. grad(u*phi) and grad(v*phi)
2462  u_times_vel_grad_test_dV[j*nSpace+I] =
2463  u*vel_grad_trial[j*nSpace+I]*dV + vel_test_dV[j]*grad_u[I];
2464  v_times_vel_grad_test_dV[j*nSpace+I] =
2465  v*vel_grad_trial[j*nSpace+I]*dV + vel_test_dV[j]*grad_v[I];
2466  /*w_times_vel_grad_test_dV[j*nSpace+I] =
2467  w*vel_grad_trial[j*nSpace+I]*dV + vel_test_dV[j]*grad_w[I];*/
2468  }
2469  }
2470  }
2471  // compute determinant of Hessians
2472  if (ARTIFICIAL_VISCOSITY==3)
2473  {
2474  det_hess_uStar_Ke += (hess_uStar[0]*hess_uStar[3] - hess_uStar[2]*hess_uStar[1])*dV;
2475  det_hess_vStar_Ke += (hess_vStar[0]*hess_vStar[3] - hess_vStar[2]*hess_vStar[1])*dV;
2476  area_Ke += dV;
2477  }
2478  //cek hack
2479  double div_mesh_velocity=0.0;
2480  int NDOF_MESH_TRIAL_ELEMENT=3;
2481  for (int j=0;j<NDOF_MESH_TRIAL_ELEMENT;j++)
2482  {
2483  int eN_j=eN*NDOF_MESH_TRIAL_ELEMENT+j;
2484  div_mesh_velocity +=
2485  mesh_velocity_dof[mesh_l2g[eN_j]*3+0]*vel_grad_trial[j*nSpace+0] +
2486  mesh_velocity_dof[mesh_l2g[eN_j]*3+1]*vel_grad_trial[j*nSpace+1];
2487  }
2488  mesh_volume_conservation_element += (alphaBDF*(dV-q_dV_last[eN_k])/dV - div_mesh_velocity)*dV;
2489  div_mesh_velocity = DM3*div_mesh_velocity + (1.0-DM3)*alphaBDF*(dV-q_dV_last[eN_k])/dV;
2490  //VRANS
2491  porosity = 1.0 - q_vos[eN_k];
2492  //meanGrainSize = q_meanGrain[eN_k];
2493  //
2494  q_x[eN_k_3d+0]=x;
2495  q_x[eN_k_3d+1]=y;
2496  /* q_x[eN_k_3d+2]=z; */
2497  //
2498  //calculate pde coefficients at quadrature points
2499  //
2500  double distance_to_omega_solid = 1e10;
2501  if(use_ball_as_particle==1)
2502  {
2503  get_distance_to_ball(nParticles, ball_center.data(), ball_radius.data(),
2504  x,y,z,
2505  distance_to_omega_solid);
2506  }
2507  else
2508  {
2509  for (int i = 0; i < nParticles; i++)
2510  {
2511  double distance_to_i_th_solid = particle_signed_distances[i * nElements_global * nQuadraturePoints_element + eN_k];
2512  distance_to_omega_solid = (distance_to_i_th_solid < distance_to_omega_solid)?distance_to_i_th_solid:distance_to_omega_solid;
2513  }
2514  }
2515  phi_solid[eN_k] = distance_to_omega_solid;//save it
2516  //
2517  //calculate pde coefficients at quadrature points
2518  //
2519  evaluateCoefficients(eps_rho,
2520  eps_mu,
2521  particle_eps,
2522  sigma,
2523  rho_0,
2524  nu_0,
2525  rho_1,
2526  nu_1,
2527  elementDiameter[eN],
2528  smagorinskyConstant,
2529  turbulenceClosureModel,
2530  g.data(),
2531  useVF,
2532  vf[eN_k],
2533  phi[eN_k],
2534  &normal_phi[eN_k_nSpace],
2535  distance_to_omega_solid,
2536  kappa_phi[eN_k],
2537  //VRANS
2538  porosity,
2539  //
2540  p,
2541  grad_p,
2542  grad_u,
2543  grad_v,
2544  grad_w,
2545  u,
2546  v,
2547  w,
2548  q_velocity_sge[eN_k_nSpace+0],
2549  q_velocity_sge[eN_k_nSpace+1],
2550  q_velocity_sge[eN_k_nSpace+1],//hack, shouldn't be used
2551  q_eddy_viscosity[eN_k],
2552  mom_u_acc,
2553  dmom_u_acc_u,
2554  mom_v_acc,
2555  dmom_v_acc_v,
2556  mom_w_acc,
2557  dmom_w_acc_w,
2558  mass_adv,
2559  dmass_adv_u,
2560  dmass_adv_v,
2561  dmass_adv_w,
2562  mom_u_adv,
2563  dmom_u_adv_u,
2564  dmom_u_adv_v,
2565  dmom_u_adv_w,
2566  mom_v_adv,
2567  dmom_v_adv_u,
2568  dmom_v_adv_v,
2569  dmom_v_adv_w,
2570  mom_w_adv,
2571  dmom_w_adv_u,
2572  dmom_w_adv_v,
2573  dmom_w_adv_w,
2574  mom_uu_diff_ten,
2575  mom_vv_diff_ten,
2576  mom_ww_diff_ten,
2577  mom_uv_diff_ten,
2578  mom_uw_diff_ten,
2579  mom_vu_diff_ten,
2580  mom_vw_diff_ten,
2581  mom_wu_diff_ten,
2582  mom_wv_diff_ten,
2583  mom_u_source,
2584  mom_v_source,
2585  mom_w_source,
2586  mom_u_ham,
2587  dmom_u_ham_grad_p,
2588  dmom_u_ham_grad_u,
2589  mom_v_ham,
2590  dmom_v_ham_grad_p,
2591  dmom_v_ham_grad_v,
2592  mom_w_ham,
2593  dmom_w_ham_grad_p,
2594  dmom_w_ham_grad_w,
2595  q_rho[eN_k],
2596  q_nu[eN_k],
2597  KILL_PRESSURE_TERM,
2598  MULTIPLY_EXTERNAL_FORCE_BY_DENSITY,
2599  forcex[eN_k],
2600  forcey[eN_k],
2601  forcez[eN_k],
2602  MATERIAL_PARAMETERS_AS_FUNCTION,
2603  density_as_function[eN_k],
2604  dynamic_viscosity_as_function[eN_k],
2605  USE_SBM,
2606  x,y,z,
2607  use_ball_as_particle,
2608  ball_center.data(),
2609  ball_radius.data(),
2610  ball_velocity.data(),
2611  ball_angular_velocity.data(),
2612  INT_BY_PARTS_PRESSURE);
2613 
2614  //VRANS
2615  mass_source = q_mass_source[eN_k];
2616  for (int I=0;I<nSpace;I++)
2617  {
2618  dmom_u_source[I] = 0.0;
2619  dmom_v_source[I] = 0.0;
2620  dmom_w_source[I] = 0.0;
2621  }
2623  q_dragAlpha[eN_k],
2624  q_dragBeta[eN_k],
2625  eps_rho,
2626  eps_mu,
2627  rho_0,
2628  nu_0,
2629  rho_1,
2630  nu_1,
2631  q_eddy_viscosity[eN_k],
2632  useVF,
2633  vf[eN_k],
2634  phi[eN_k],
2635  u,
2636  v,
2637  w,
2638  q_velocity_sge[eN_k_nSpace+0],
2639  q_velocity_sge[eN_k_nSpace+1],
2640  q_velocity_sge[eN_k_nSpace+1],//hack, shouldn't be used
2641  eps_solid[elementFlags[eN]],
2642  porosity,
2643  q_velocity_solid[eN_k_nSpace+0],
2644  q_velocity_solid[eN_k_nSpace+1],
2645  q_velocity_solid[eN_k_nSpace+1],//cek hack, should not be used
2646  q_velocityStar_solid[eN_k_nSpace+0],
2647  q_velocityStar_solid[eN_k_nSpace+1],
2648  q_velocityStar_solid[eN_k_nSpace+1],//cek hack, should not be used
2649  mom_u_source,
2650  mom_v_source,
2651  mom_w_source,
2652  dmom_u_source,
2653  dmom_v_source,
2654  dmom_w_source,
2655  q_grad_vos[eN_k_nSpace+0],
2656  q_grad_vos[eN_k_nSpace+1],
2657  q_grad_vos[eN_k_nSpace+1]);
2658  double C_particles=0.0;
2659  if(nParticles > 0 && USE_SBM==0)
2660  updateSolidParticleTerms(eN < nElements_owned,
2661  particle_nitsche,
2662  dV,
2663  nParticles,
2664  nQuadraturePoints_global,
2665  &particle_signed_distances[eN_k],
2666  &particle_signed_distance_normals[eN_k_3d],
2667  &particle_velocities[eN_k_3d],
2668  particle_centroids.data(),
2669  use_ball_as_particle,
2670  ball_center.data(),
2671  ball_radius.data(),
2672  ball_velocity.data(),
2673  ball_angular_velocity.data(),
2674  porosity,
2675  particle_penalty_constant/h_phi,
2676  particle_alpha/h_phi,
2677  particle_beta/h_phi,
2678  eps_rho,
2679  eps_mu,
2680  rho_0,
2681  nu_0,
2682  rho_1,
2683  nu_1,
2684  useVF,
2685  vf[eN_k],
2686  phi[eN_k],
2687  x,
2688  y,
2689  z,
2690  p,
2691  u,
2692  v,
2693  w,
2694  q_velocity_sge[eN_k_nSpace+0],
2695  q_velocity_sge[eN_k_nSpace+1],
2696  q_velocity_sge[eN_k_nSpace+1],
2697  particle_eps,
2698  grad_u,
2699  grad_v,
2700  grad_w,
2701  mom_u_source,
2702  mom_v_source,
2703  mom_w_source,
2704  dmom_u_source,
2705  dmom_v_source,
2706  dmom_w_source,
2707  mom_u_adv,
2708  mom_v_adv,
2709  mom_w_adv,
2710  dmom_u_adv_u,
2711  dmom_v_adv_v,
2712  dmom_w_adv_w,
2713  mom_u_ham,
2714  dmom_u_ham_grad_u,
2715  mom_v_ham,
2716  dmom_v_ham_grad_v,
2717  mom_w_ham,
2718  dmom_w_ham_grad_w,
2719  particle_netForces.data(),
2720  particle_netMoments.data(),
2721  particle_surfaceArea.data());
2722  if(USE_SBM==2)
2723  compute_force_around_solid(eN < nElements_owned,
2724  dV,
2725  nParticles,
2726  nQuadraturePoints_global,
2727  &particle_signed_distances[eN_k],
2728  &particle_signed_distance_normals[eN_k_3d],
2729  &particle_velocities[eN_k_3d],
2730  particle_centroids.data(),
2731  use_ball_as_particle,
2732  ball_center.data(),
2733  ball_radius.data(),
2734  ball_velocity.data(),
2735  ball_angular_velocity.data(),
2736  particle_penalty_constant/h_phi,
2737  particle_alpha/h_phi,
2738  particle_beta/h_phi,
2739  eps_rho,
2740  eps_mu,
2741  rho_0,
2742  nu_0,
2743  rho_1,
2744  nu_1,
2745  useVF,
2746  vf[eN_k],
2747  phi[eN_k],
2748  x,
2749  y,
2750  z,
2751  p,
2752  u,
2753  v,
2754  w,
2755  q_velocity_sge[eN_k_nSpace+0],
2756  q_velocity_sge[eN_k_nSpace+1],
2757  q_velocity_sge[eN_k_nSpace+1],
2758  particle_eps,
2759  grad_u,
2760  grad_v,
2761  grad_w,
2762  particle_netForces.data(),
2763  particle_netMoments.data());
2764  //Turbulence closure model
2765  if (turbulenceClosureModel >= 3)
2766  {
2767  const double c_mu = 0.09;//mwf hack
2768  updateTurbulenceClosure(turbulenceClosureModel,
2769  eps_rho,
2770  eps_mu,
2771  rho_0,
2772  nu_0,
2773  rho_1,
2774  nu_1,
2775  useVF,
2776  vf[eN_k],
2777  phi[eN_k],
2778  porosity,
2779  c_mu, //mwf hack
2780  q_turb_var_0[eN_k],
2781  q_turb_var_1[eN_k],
2782  &q_turb_var_grad_0[eN_k_nSpace],
2783  q_eddy_viscosity[eN_k],
2784  mom_uu_diff_ten,
2785  mom_vv_diff_ten,
2786  mom_ww_diff_ten,
2787  mom_uv_diff_ten,
2788  mom_uw_diff_ten,
2789  mom_vu_diff_ten,
2790  mom_vw_diff_ten,
2791  mom_wu_diff_ten,
2792  mom_wv_diff_ten,
2793  mom_u_source,
2794  mom_v_source,
2795  mom_w_source);
2796 
2797  }
2798  //
2799  //save momentum for time history and velocity for subgrid error
2800  //
2801  q_mom_u_acc[eN_k] = mom_u_acc;
2802  q_mom_v_acc[eN_k] = mom_v_acc;
2803  /* q_mom_w_acc[eN_k] = mom_w_acc; */
2804  //subgrid error uses grid scale velocity
2805  q_mass_adv[eN_k_nSpace+0] = u;
2806  q_mass_adv[eN_k_nSpace+1] = v;
2807  /* q_mass_adv[eN_k_nSpace+2] = w; */
2808  //
2809  //moving mesh
2810  //
2811  mom_u_adv[0] -= MOVING_DOMAIN*dmom_u_acc_u*mom_u_acc*xt; // multiply by rho*porosity. mql. CHECK.
2812  mom_u_adv[1] -= MOVING_DOMAIN*dmom_u_acc_u*mom_u_acc*yt;
2813  /* mom_u_adv[2] -= MOVING_DOMAIN*dmom_u_acc_u*mom_u_acc*zt; */
2814  dmom_u_adv_u[0] -= MOVING_DOMAIN*dmom_u_acc_u*xt;
2815  dmom_u_adv_u[1] -= MOVING_DOMAIN*dmom_u_acc_u*yt;
2816  /* dmom_u_adv_u[2] -= MOVING_DOMAIN*dmom_u_acc_u*zt; */
2817 
2818  mom_v_adv[0] -= MOVING_DOMAIN*dmom_v_acc_v*mom_v_acc*xt;
2819  mom_v_adv[1] -= MOVING_DOMAIN*dmom_v_acc_v*mom_v_acc*yt;
2820  /* mom_v_adv[2] -= MOVING_DOMAIN*dmom_v_acc_v*mom_v_acc*zt; */
2821  dmom_v_adv_v[0] -= MOVING_DOMAIN*dmom_v_acc_v*xt;
2822  dmom_v_adv_v[1] -= MOVING_DOMAIN*dmom_v_acc_v*yt;
2823  /* dmom_v_adv_v[2] -= MOVING_DOMAIN*dmom_v_acc_v*zt; */
2824 
2825  /* mom_w_adv[0] -= MOVING_DOMAIN*dmom_w_acc_w*mom_w_acc*xt; */
2826  /* mom_w_adv[1] -= MOVING_DOMAIN*dmom_w_acc_w*mom_w_acc*yt; */
2827  /* mom_w_adv[2] -= MOVING_DOMAIN*dmom_w_acc_w*mom_w_acc*zt; */
2828  /* dmom_w_adv_w[0] -= MOVING_DOMAIN*dmom_w_acc_w*xt; */
2829  /* dmom_w_adv_w[1] -= MOVING_DOMAIN*dmom_w_acc_w*yt; */
2830  /* dmom_w_adv_w[2] -= MOVING_DOMAIN*dmom_w_acc_w*zt; */
2831  //
2832  //calculate time derivative at quadrature points
2833  //
2834  if (q_dV_last[eN_k] <= -100)
2835  q_dV_last[eN_k] = dV;
2836  q_dV[eN_k] = dV;
2837  ck.bdf(alphaBDF,
2838  q_mom_u_acc_beta_bdf[eN_k]*q_dV_last[eN_k]/dV,
2839  mom_u_acc,
2840  dmom_u_acc_u,
2841  mom_u_acc_t,
2842  dmom_u_acc_u_t);
2843  ck.bdf(alphaBDF,
2844  q_mom_v_acc_beta_bdf[eN_k]*q_dV_last[eN_k]/dV,
2845  mom_v_acc,
2846  dmom_v_acc_v,
2847  mom_v_acc_t,
2848  dmom_v_acc_v_t);
2849 
2850  /* ck.bdf(alphaBDF, */
2851  /* q_mom_w_acc_beta_bdf[eN_k]*q_dV_last[eN_k]/dV, */
2852  /* mom_w_acc, */
2853  /* dmom_w_acc_w, */
2854  /* mom_w_acc_t, */
2855  /* dmom_w_acc_w_t); */
2856  /* // */
2857 
2858  mom_u_acc_t *= dmom_u_acc_u; //multiply by rho*porosity. mql. CHECK.
2859  mom_v_acc_t *= dmom_v_acc_v;
2860 
2861  //calculate subgrid error (strong residual and adjoint)
2862  //
2863  //calculate strong residual
2864  pdeResidual_p =
2865  ck.Mass_strong(-q_dvos_dt[eN_k]) + // mql. CHECK.
2866  ck.Advection_strong(dmass_adv_u,grad_u) +
2867  ck.Advection_strong(dmass_adv_v,grad_v) +
2868  /* ck.Advection_strong(dmass_adv_w,grad_w) + */
2869  DM2*MOVING_DOMAIN*ck.Reaction_strong(alphaBDF*(dV-q_dV_last[eN_k])/dV - div_mesh_velocity) +
2870  //VRANS
2871  ck.Reaction_strong(mass_source);
2872  //
2873 
2874  dmom_adv_sge[0] = dmom_u_acc_u*(q_velocity_sge[eN_k_nSpace+0] - MOVING_DOMAIN*xt);
2875  dmom_adv_sge[1] = dmom_u_acc_u*(q_velocity_sge[eN_k_nSpace+1] - MOVING_DOMAIN*yt);
2876  /* dmom_adv_sge[2] = dmom_u_acc_u*(q_velocity_sge[eN_k_nSpace+2] - MOVING_DOMAIN*zt); */
2877 
2878  pdeResidual_u =
2879  ck.Mass_strong(mom_u_acc_t) + // mql. CHECK.
2880  ck.Advection_strong(dmom_adv_sge,grad_u) + //note here and below: same in cons. and non-cons.
2881  ck.Hamiltonian_strong(dmom_u_ham_grad_p,grad_p) +
2882  ck.Reaction_strong(mom_u_source) -
2883  ck.Reaction_strong(u*div_mesh_velocity);
2884 
2885  pdeResidual_v =
2886  ck.Mass_strong(mom_v_acc_t) +
2887  ck.Advection_strong(dmom_adv_sge,grad_v) +
2888  ck.Hamiltonian_strong(dmom_v_ham_grad_p,grad_p) +
2889  ck.Reaction_strong(mom_v_source) -
2890  ck.Reaction_strong(v*div_mesh_velocity);
2891 
2892  /* pdeResidual_w = ck.Mass_strong(dmom_w_acc_w*mom_w_acc_t) + */
2893  /* ck.Advection_strong(dmom_adv_sge,grad_w) + */
2894  /* ck.Hamiltonian_strong(dmom_w_ham_grad_p,grad_p) + */
2895  /* ck.Reaction_strong(mom_w_source) - */
2896  /* ck.Reaction_strong(w*div_mesh_velocity); */
2897 
2898  //calculate tau and tau*Res
2899  //cek debug
2900  double tmpR=dmom_u_acc_u_t + dmom_u_source[0];
2901  calculateSubgridError_tau(hFactor,
2902  elementDiameter[eN],
2903  tmpR,//dmom_u_acc_u_t,
2904  dmom_u_acc_u,
2905  dmom_adv_sge,
2906  mom_uu_diff_ten[1],
2907  dmom_u_ham_grad_p[0],
2908  tau_v0,
2909  tau_p0,
2910  q_cfl[eN_k]);
2911 
2912  calculateSubgridError_tau(Ct_sge,Cd_sge,
2913  G,G_dd_G,tr_G,
2914  tmpR,//dmom_u_acc_u_t,
2915  dmom_adv_sge,
2916  mom_uu_diff_ten[1],
2917  dmom_u_ham_grad_p[0],
2918  tau_v1,
2919  tau_p1,
2920  q_cfl[eN_k]);
2921 
2922  tau_v = useMetrics*tau_v1+(1.0-useMetrics)*tau_v0;
2923  tau_p = KILL_PRESSURE_TERM == 1 ? 0. : PSTAB*(useMetrics*tau_p1+(1.0-useMetrics)*tau_p0);
2924 
2926  tau_v,
2927  pdeResidual_p,
2928  pdeResidual_u,
2929  pdeResidual_v,
2930  pdeResidual_w,
2931  subgridError_p,
2932  subgridError_u,
2933  subgridError_v,
2934  subgridError_w);
2935  // velocity used in adjoint (VMS or RBLES, with or without lagging the grid scale velocity)
2936  dmom_adv_star[0] = dmom_u_acc_u*(q_velocity_sge[eN_k_nSpace+0] - MOVING_DOMAIN*xt + useRBLES*subgridError_u);
2937  dmom_adv_star[1] = dmom_u_acc_u*(q_velocity_sge[eN_k_nSpace+1] - MOVING_DOMAIN*yt + useRBLES*subgridError_v);
2938  /* dmom_adv_star[2] = dmom_u_acc_u*(q_velocity_sge[eN_k_nSpace+2] - MOVING_DOMAIN*zt + useRBLES*subgridError_w); */
2939 
2940  mom_u_adv[0] += dmom_u_acc_u*(useRBLES*subgridError_u*q_velocity_sge[eN_k_nSpace+0]);
2941  mom_u_adv[1] += dmom_u_acc_u*(useRBLES*subgridError_v*q_velocity_sge[eN_k_nSpace+0]);
2942  /* mom_u_adv[2] += dmom_u_acc_u*(useRBLES*subgridError_w*q_velocity_sge[eN_k_nSpace+0]); */
2943 
2944  // adjoint times the test functions
2945  for (int i=0;i<nDOF_test_element;i++)
2946  {
2947  register int i_nSpace = i*nSpace;
2948  /* Lstar_u_p[i]=ck.Advection_adjoint(dmass_adv_u,&p_grad_test_dV[i_nSpace]); */
2949  /* Lstar_v_p[i]=ck.Advection_adjoint(dmass_adv_v,&p_grad_test_dV[i_nSpace]); */
2950  /* Lstar_w_p[i]=ck.Advection_adjoint(dmass_adv_w,&p_grad_test_dV[i_nSpace]); */
2951  //use the same advection adjoint for all three since we're approximating the linearized adjoint
2952  Lstar_u_u[i]=ck.Advection_adjoint(dmom_adv_star,&vel_grad_test_dV[i_nSpace]);
2953  Lstar_v_v[i]=ck.Advection_adjoint(dmom_adv_star,&vel_grad_test_dV[i_nSpace]);
2954  /* Lstar_w_w[i]=ck.Advection_adjoint(dmom_adv_star,&vel_grad_test_dV[i_nSpace]); */
2955  Lstar_p_u[i]=ck.Hamiltonian_adjoint(dmom_u_ham_grad_p,&vel_grad_test_dV[i_nSpace]);
2956  Lstar_p_v[i]=ck.Hamiltonian_adjoint(dmom_v_ham_grad_p,&vel_grad_test_dV[i_nSpace]);
2957  /* Lstar_p_w[i]=ck.Hamiltonian_adjoint(dmom_w_ham_grad_p,&vel_grad_test_dV[i_nSpace]); */
2958 
2959  //VRANS account for drag terms, diagonal only here ... decide if need off diagonal terms too
2960  Lstar_u_u[i]+=ck.Reaction_adjoint(dmom_u_source[0],vel_test_dV[i]);
2961  Lstar_v_v[i]+=ck.Reaction_adjoint(dmom_v_source[1],vel_test_dV[i]);
2962  /* Lstar_w_w[i]+=ck.Reaction_adjoint(dmom_w_source[2],vel_test_dV[i]); */
2963  //
2964  }
2965 
2966  if (ARTIFICIAL_VISCOSITY==0 || ARTIFICIAL_VISCOSITY==3 || ARTIFICIAL_VISCOSITY==4)
2967  {
2968  q_numDiff_u[eN_k] = 0;
2969  q_numDiff_v[eN_k] = 0;
2970  q_numDiff_w[eN_k] = 0;
2971  }
2972  else if (ARTIFICIAL_VISCOSITY==1) // SHOCK CAPTURING
2973  {
2974  norm_Rv = sqrt(pdeResidual_u*pdeResidual_u + pdeResidual_v*pdeResidual_v);// + pdeResidual_w*pdeResidual_w);
2975  q_numDiff_u[eN_k] = C_dc*norm_Rv*(useMetrics/sqrt(G_dd_G+1.0e-12) +
2976  (1.0-useMetrics)*hFactor*hFactor*elementDiameter[eN]*elementDiameter[eN]);
2977  q_numDiff_v[eN_k] = q_numDiff_u[eN_k];
2978  q_numDiff_w[eN_k] = q_numDiff_u[eN_k];
2979  }
2980  else // ARTIFICIAL_VISCOSITY==2; i.e, ENTROPY VISCOSITY
2981  {
2982  double rho = q_rho[eN_k];
2983  double mu = q_rho[eN_k]*q_nu[eN_k];
2984 
2985  double vel2 = u*u + v*v;
2986 
2987  // entropy residual
2988  double Res_in_x =
2989  porosity*rho*((u-un)/dt + (u*grad_u[0]+v*grad_u[1]) - g[0])
2990  + (KILL_PRESSURE_TERM == 1 ? 0. : 1.)*grad_p[0]
2991  - (MULTIPLY_EXTERNAL_FORCE_BY_DENSITY == 1 ? porosity*rho : 1.0)*forcex[eN_k]
2992  - mu*(hess_u[0] + hess_u[3]) // u_xx + u_yy
2993  - mu*(hess_u[0] + hess_v[2]); // u_xx + v_yx
2994 
2995  double Res_in_y =
2996  porosity*rho*((v-vn)/dt + (u*grad_v[0]+v*grad_v[1]) - g[1])
2997  + (KILL_PRESSURE_TERM == 1 ? 0. : 1.)*grad_p[1]
2998  - (MULTIPLY_EXTERNAL_FORCE_BY_DENSITY == 1 ? porosity*rho : 1.0)*forcey[eN_k]
2999  - mu*(hess_v[0] + hess_v[3]) // v_xx + v_yy
3000  - mu*(hess_u[1] + hess_v[3]); // u_xy + v_yy
3001 
3002  // compute entropy residual
3003  double entRes_times_u = Res_in_x*u + Res_in_y*v;
3004 
3005  double hK = elementDiameter[eN]/order_polynomial;
3006  q_numDiff_u[eN_k] = fmin(cMax*porosity*rho*hK*std::sqrt(vel2),
3007  cE*hK*hK*fabs(entRes_times_u)/(vel2+1E-10));
3008  q_numDiff_v[eN_k] = q_numDiff_u[eN_k];
3009  q_numDiff_w[eN_k] = q_numDiff_u[eN_k];
3010 
3011  if (CELL_BASED_EV_COEFF)
3012  {
3013  linVisc_eN = fmax(porosity*rho*std::sqrt(vel2),linVisc_eN);
3014  nlinVisc_eN_num = fmax(fabs(entRes_times_u),nlinVisc_eN_num);
3015  nlinVisc_eN_den = fmax(vel2,nlinVisc_eN_den);
3016  }
3017  }
3018 
3019  //
3020  //update element residual
3021  //
3022  double mesh_vel[2];
3023  mesh_vel[0] = xt;
3024  mesh_vel[1] = yt;
3025  // Save velocity and its gradient (to be used in other models and to compute errors)
3026  q_velocity[eN_k_nSpace+0]=u;
3027  q_velocity[eN_k_nSpace+1]=v;
3028  /* q_velocity[eN_k_nSpace+2]=w; */
3029  for (int I=0;I<nSpace;I++)
3030  {
3031  q_grad_u[eN_k_nSpace+I] = grad_u[I];
3032  q_grad_v[eN_k_nSpace+I] = grad_v[I];
3033  /* q_grad_w[eN_k_nSpace+I] = grad_w[I]; */
3034  }
3035  // save divergence of velocity
3036  q_divU[eN_k] = q_grad_u[eN_k_nSpace+0] + q_grad_v[eN_k_nSpace+1];
3037 
3038  // SURFACE TENSION //
3039  double unit_normal[nSpace];
3040  double norm_grad_phi = 0.;
3041  for (int I=0;I<nSpace;I++)
3042  norm_grad_phi += normal_phi[eN_k_nSpace+I]*normal_phi[eN_k_nSpace+I];
3043  norm_grad_phi = std::sqrt(norm_grad_phi) + 1E-10;
3044  for (int I=0;I<nSpace;I++)
3045  unit_normal[I] = normal_phi[eN_k_nSpace+I]/norm_grad_phi;
3046  // compute auxiliary vectors for explicit term of 2D surf tension
3047  // v1 = [1-nx^2 -nx*ny]^T
3048  double v1[nSpace];
3049  v1[0]=1.-unit_normal[0]*unit_normal[0];
3050  v1[1]=-unit_normal[0]*unit_normal[1];
3051  // v2 = [-nx*ny 1-ny^2]^T
3052  double v2[nSpace];
3053  v2[0]=-unit_normal[0]*unit_normal[1];
3054  v2[1]=1.-unit_normal[1]*unit_normal[1];
3055  double delta = gf.D(eps_mu,phi[eN_k]); //use eps_rho instead?
3056  register double vel_tgrad_test_i[nSpace], tgrad_u[nSpace], tgrad_v[nSpace];
3057  calculateTangentialGradient(unit_normal,
3058  grad_u,
3059  tgrad_u);
3060  calculateTangentialGradient(unit_normal,
3061  grad_v,
3062  tgrad_v);
3063  // END OF SURFACE TENSION //
3064 
3065  if (ARTIFICIAL_VISCOSITY==3 || ARTIFICIAL_VISCOSITY==4)
3066  {
3067  velStar[0] = q_velocity_sge[eN_k_nSpace+0];
3068  velStar[1] = q_velocity_sge[eN_k_nSpace+1];
3069  /*velStar[2] = q_velocity_sge[eN_k_nSpace+2];*/
3070  }
3071  for(int i=0;i<nDOF_test_element;i++)
3072  {
3073  register int i_nSpace=i*nSpace;
3074  calculateTangentialGradient(unit_normal,
3075  &vel_grad_trial[i_nSpace],
3076  vel_tgrad_test_i);
3077  phisErrorElement[i]+=std::abs(phisError[eN_k_nSpace+0])*p_test_dV[i];
3078  /* std::cout<<"elemRes_mesh "<<mesh_vel[0]<<'\t'<<mesh_vel[2]<<'\t'<<p_test_dV[i]<<'\t'<<(q_dV_last[eN_k]/dV)<<'\t'<<dV<<std::endl; */
3079  /* elementResidual_mesh[i] += ck.Reaction_weak(1.0,p_test_dV[i]) - */
3080  /* ck.Reaction_weak(1.0,p_test_dV[i]*q_dV_last[eN_k]/dV) - */
3081  /* ck.Advection_weak(mesh_vel,&p_grad_test_dV[i_nSpace]); */
3082 
3083  /* elementResidual_p[i] += ck.Mass_weak(-q_dvos_dt[eN_k],p_test_dV[i]) + */
3084  /* ck.Advection_weak(mass_adv,&p_grad_test_dV[i_nSpace]) + */
3085  /* DM*MOVING_DOMAIN*(ck.Reaction_weak(alphaBDF*1.0,p_test_dV[i]) - */
3086  /* ck.Reaction_weak(alphaBDF*1.0,p_test_dV[i]*q_dV_last[eN_k]/dV) - */
3087  /* ck.Advection_weak(mesh_vel,&p_grad_test_dV[i_nSpace])) + */
3088  /* //VRANS */
3089  /* ck.Reaction_weak(mass_source,p_test_dV[i]) + //VRANS source term for wave maker */
3090  /* // */
3091  /* ck.SubgridError(subgridError_u,Lstar_u_p[i]) + */
3092  /* ck.SubgridError(subgridError_v,Lstar_v_p[i]);// + */
3093  /* /\* ck.SubgridError(subgridError_w,Lstar_w_p[i]); *\/ */
3094 
3095  elementResidual_u[i] += // mql. CHECK.
3096  ck.Mass_weak(mom_u_acc_t,vel_test_dV[i]) +
3097  ck.Advection_weak(mom_u_adv,&vel_grad_test_dV[i_nSpace]) +
3098  ck.Diffusion_weak(sdInfo_u_u_rowptr.data(),sdInfo_u_u_colind.data(),mom_uu_diff_ten,grad_u,&vel_grad_test_dV[i_nSpace]) +
3099  ck.Diffusion_weak(sdInfo_u_v_rowptr.data(),sdInfo_u_v_colind.data(),mom_uv_diff_ten,grad_v,&vel_grad_test_dV[i_nSpace]) +
3100  /* ck.Diffusion_weak(sdInfo_u_w_rowptr,sdInfo_u_w_colind,mom_uw_diff_ten,grad_w,&vel_grad_test_dV[i_nSpace]) + */
3101  ck.Reaction_weak(mom_u_source,vel_test_dV[i]) +
3102  ck.Hamiltonian_weak(mom_u_ham,vel_test_dV[i]) +
3103  (INT_BY_PARTS_PRESSURE==1 ? -1.0*p*vel_grad_test_dV[i_nSpace+0] : 0.) +
3104  //ck.SubgridError(subgridError_p,Lstar_p_u[i]) +
3105  USE_SUPG*ck.SubgridError(subgridError_u,Lstar_u_u[i]) +
3106  ck.NumericalDiffusion(q_numDiff_u_last[eN_k],grad_u,&vel_grad_test_dV[i_nSpace]) +
3107  //surface tension
3108  ck.NumericalDiffusion(delta*sigma*dV,v1,vel_tgrad_test_i) + //exp.
3109  ck.NumericalDiffusion(dt*delta*sigma*dV,tgrad_u,vel_tgrad_test_i); //imp.
3110  mom_u_source_i[i] += ck.Reaction_weak(mom_u_source,vel_test_dV[i]);
3111  betaDrag_i[i] += ck.Reaction_weak(dmom_u_source[0],
3112  vel_test_dV[i]);
3113  vos_i[i] += ck.Reaction_weak(1.0-porosity,
3114  vel_test_dV[i]);
3115 
3116  elementResidual_v[i] +=
3117  ck.Mass_weak(mom_v_acc_t,vel_test_dV[i]) +
3118  ck.Advection_weak(mom_v_adv,&vel_grad_test_dV[i_nSpace]) +
3119  ck.Diffusion_weak(sdInfo_v_u_rowptr.data(),sdInfo_v_u_colind.data(),mom_vu_diff_ten,grad_u,&vel_grad_test_dV[i_nSpace]) +
3120  ck.Diffusion_weak(sdInfo_v_v_rowptr.data(),sdInfo_v_v_colind.data(),mom_vv_diff_ten,grad_v,&vel_grad_test_dV[i_nSpace]) +
3121  /* ck.Diffusion_weak(sdInfo_v_w_rowptr,sdInfo_v_w_colind,mom_vw_diff_ten,grad_w,&vel_grad_test_dV[i_nSpace]) + */
3122  ck.Reaction_weak(mom_v_source,vel_test_dV[i]) +
3123  ck.Hamiltonian_weak(mom_v_ham,vel_test_dV[i]) +
3124  (INT_BY_PARTS_PRESSURE==1 ? -1.0*p*vel_grad_test_dV[i_nSpace+1] : 0.) +
3125  //ck.SubgridError(subgridError_p,Lstar_p_v[i]) +
3126  USE_SUPG*ck.SubgridError(subgridError_v,Lstar_v_v[i]) +
3127  ck.NumericalDiffusion(q_numDiff_v_last[eN_k],grad_v,&vel_grad_test_dV[i_nSpace]) +
3128  //surface tension
3129  ck.NumericalDiffusion(delta*sigma*dV,v2,vel_tgrad_test_i) + //exp.
3130  ck.NumericalDiffusion(dt*delta*sigma*dV,tgrad_v,vel_tgrad_test_i); //imp.
3131  mom_v_source_i[i] += ck.Reaction_weak(mom_v_source,vel_test_dV[i]);
3132 
3133  /* elementResidual_w[i] +=
3134  ck.Mass_weak(mom_w_acc_t,vel_test_dV[i]) + */
3135  /* ck.Advection_weak(mom_w_adv,&vel_grad_test_dV[i_nSpace]) + */
3136  /* ck.Diffusion_weak(sdInfo_w_u_rowptr,sdInfo_w_u_colind,mom_wu_diff_ten,grad_u,&vel_grad_test_dV[i_nSpace]) + */
3137  /* ck.Diffusion_weak(sdInfo_w_v_rowptr,sdInfo_w_v_colind,mom_wv_diff_ten,grad_v,&vel_grad_test_dV[i_nSpace]) + */
3138  /* ck.Diffusion_weak(sdInfo_w_w_rowptr,sdInfo_w_w_colind,mom_ww_diff_ten,grad_w,&vel_grad_test_dV[i_nSpace]) + */
3139  /* ck.Reaction_weak(mom_w_source,vel_test_dV[i]) + */
3140  /* ck.Hamiltonian_weak(mom_w_ham,vel_test_dV[i]) + */
3141  /* (INT_BY_PARTS_PRESSURE==1 ? -1.0*p*vel_grad_test_dV[i_nSpace+2] : 0.) + */
3142  /* ck.SubgridError(subgridError_p,Lstar_p_w[i]) + */
3143  /* ck.SubgridError(subgridError_w,Lstar_w_w[i]) + */
3144  /* ck.NumericalDiffusion(q_numDiff_w_last[eN_k],grad_w,&vel_grad_test_dV[i_nSpace]); */
3145  if (ARTIFICIAL_VISCOSITY==4)
3146  {
3147  // ***** COMPUTE ENTROPY RESIDUAL ***** //
3148  // mql. NOTE that the test functions are weighted by the velocity
3149  elementEntropyResidual[i] +=
3150  // x-component
3151  ck.Mass_weak(mom_u_acc_t,u*vel_test_dV[i]) + // time derivative
3152  ck.Advection_weak(mom_u_adv,&u_times_vel_grad_test_dV[i_nSpace])+//m.mesh
3153  ck.Diffusion_weak(sdInfo_u_u_rowptr.data(),
3154  sdInfo_u_u_colind.data(),
3155  mom_uu_diff_ten,
3156  grad_u,
3157  &u_times_vel_grad_test_dV[i_nSpace]) +
3158  ck.Diffusion_weak(sdInfo_u_v_rowptr.data(),
3159  sdInfo_u_v_colind.data(),
3160  mom_uv_diff_ten,
3161  grad_v,
3162  &u_times_vel_grad_test_dV[i_nSpace]) +
3163  ck.Reaction_weak(mom_u_source,u*vel_test_dV[i]) + // Force term
3164  ck.Hamiltonian_weak(mom_u_ham,u*vel_test_dV[i]) // Pres + Non-linearity
3165  + // y-component
3166  ck.Mass_weak(mom_v_acc_t,v*vel_test_dV[i]) + // time derivative
3167  ck.Advection_weak(mom_v_adv,&v_times_vel_grad_test_dV[i_nSpace])+//m.mesh
3168  ck.Diffusion_weak(sdInfo_v_u_rowptr.data(),
3169  sdInfo_v_u_colind.data(),
3170  mom_vu_diff_ten,
3171  grad_u,
3172  &v_times_vel_grad_test_dV[i_nSpace])+
3173  ck.Diffusion_weak(sdInfo_v_v_rowptr.data(),
3174  sdInfo_v_v_colind.data(),
3175  mom_vv_diff_ten,
3176  grad_v,
3177  &v_times_vel_grad_test_dV[i_nSpace])+
3178  ck.Reaction_weak(mom_v_source,v*vel_test_dV[i]) + // force term
3179  ck.Hamiltonian_weak(mom_v_ham,v*vel_test_dV[i]); // Pres + Non-linearity
3180  }
3181  if (ARTIFICIAL_VISCOSITY==3 || ARTIFICIAL_VISCOSITY==4)
3182  {
3183  for(int j=0;j<nDOF_trial_element;j++)
3184  {
3185  int j_nSpace = j*nSpace;
3186  int i_nSpace = i*nSpace;
3187  elementTransport[i][j] += // int[rho*(velStar.grad_wj)*wi*dx]
3188  q_rho[eN_k]*porosity*
3189  ck.AdvectionJacobian_strong(velStar,
3190  &vel_grad_test_dV[j_nSpace])
3191  *vel_trial_ref[k*nDOF_trial_element+i];
3192  elementTransposeTransport[i][j] += // int[rho*(velStar.grad_wi)*wj*dx]
3193  q_rho[eN_k]*porosity*
3194  ck.AdvectionJacobian_strong(velStar,
3195  &vel_grad_test_dV[i_nSpace])
3196  *vel_trial_ref[k*nDOF_trial_element+j];
3197  }
3198  }//j
3199  }//i
3200  }
3201  element_uStar_He[eN] = det_hess_uStar_Ke/area_Ke;
3202  element_vStar_He[eN] = det_hess_vStar_Ke/area_Ke;
3203 
3204  // End computation of cell based EV coeff //
3205  if (CELL_BASED_EV_COEFF && ARTIFICIAL_VISCOSITY==2)
3206  {
3207  double hK = elementDiameter[eN];
3208  double artVisc = fmin(cMax*hK*linVisc_eN,
3209  cE*hK*hK*nlinVisc_eN_num/(nlinVisc_eN_den+1E-10));
3210  for(int k=0;k<nQuadraturePoints_element;k++)
3211  {
3212  register int eN_k = eN*nQuadraturePoints_element+k;
3213  q_numDiff_u[eN_k] = artVisc;
3214  q_numDiff_v[eN_k] = artVisc;
3215  q_numDiff_w[eN_k] = artVisc;
3216  }
3217  }
3218  //
3219  //load element into global residual and save element residual
3220  //
3221  for(int i=0;i<nDOF_test_element;i++)
3222  {
3223  register int eN_i=eN*nDOF_test_element+i;
3224  phisErrorNodal[vel_l2g[eN_i]]+= element_active*phisErrorElement[i];
3225  /* elementResidual_p_save[eN_i] += elementResidual_p[i]; */
3226  /* mesh_volume_conservation_element_weak += elementResidual_mesh[i]; */
3227  /* globalResidual[offset_p+stride_p*p_l2g[eN_i]]+=elementResidual_p[i]; */
3228  globalResidual[offset_u+stride_u*vel_l2g[eN_i]]+=element_active*elementResidual_u[i];
3229  globalResidual[offset_v+stride_v*vel_l2g[eN_i]]+=element_active*elementResidual_v[i];
3230  /* globalResidual[offset_w+stride_w*vel_l2g[eN_i]]+=elementResidual_w[i]; */
3231  ncDrag[offset_u+stride_u*vel_l2g[eN_i]]+=mom_u_source_i[i];
3232  ncDrag[offset_v+stride_v*vel_l2g[eN_i]]+=mom_v_source_i[i];
3233  betaDrag[vel_l2g[eN_i]] += betaDrag_i[i];
3234  vos_vel_nodes[vel_l2g[eN_i]] += vos_i[i];
3235 
3236  // compute numerator and denominator of uStar_hi and vStar_hi
3237  if (ARTIFICIAL_VISCOSITY==3)
3238  {
3239  uStar_hi[vel_l2g[eN_i]] += element_uStar_He[eN]; // offset=0, stride=1 since this is per component of the equation
3240  vStar_hi[vel_l2g[eN_i]] += element_vStar_He[eN];
3241  den_hi[vel_l2g[eN_i]] += 1;
3242  }
3243  if (ARTIFICIAL_VISCOSITY==4)
3244  {
3245  // DISTRIBUTE ENTROPY RESIDUAL //
3246  entropyResidualPerNode[vel_l2g[eN_i]] += elementEntropyResidual[i];
3247  }
3248  if (ARTIFICIAL_VISCOSITY==3 || ARTIFICIAL_VISCOSITY==4)
3249  {
3250  for (int j=0;j<nDOF_trial_element;j++)
3251  {
3252  int eN_i_j = eN_i*nDOF_trial_element+j;
3253  TransportMatrix[csrRowIndeces_1D[eN_i]
3254  + csrColumnOffsets_1D[eN_i_j]]
3255  += elementTransport[i][j];
3256  // transpose
3257  TransposeTransportMatrix[csrRowIndeces_1D[eN_i]
3258  + csrColumnOffsets_1D[eN_i_j]]
3259  += elementTransposeTransport[i][j];
3260  }//j
3261  }
3262  }//i
3263  /* mesh_volume_conservation += mesh_volume_conservation_element; */
3264  /* mesh_volume_conservation_weak += mesh_volume_conservation_element_weak; */
3265  /* mesh_volume_conservation_err_max=fmax(mesh_volume_conservation_err_max,fabs(mesh_volume_conservation_element)); */
3266  /* mesh_volume_conservation_err_max_weak=fmax(mesh_volume_conservation_err_max_weak,fabs(mesh_volume_conservation_element_weak)); */
3267  }//elements
3268 
3269  if(CUT_CELL_INTEGRATION > 0)
3270  std::cout<<std::flush;
3271  // loop in DOFs for discrete upwinding
3272  if (ARTIFICIAL_VISCOSITY==3 || ARTIFICIAL_VISCOSITY==4)
3273  {
3274  // FIRST LOOP ON DOFs //
3275  for (int i=0; i<numDOFs_1D; i++)
3276  {
3277  if (ARTIFICIAL_VISCOSITY==4) // via entropy viscosity
3278  {
3279  // normalize entropy residual per node
3280  double max_u2i = (std::pow(u_dof[i],2.) +
3281  std::pow(v_dof[i],2.));
3282  double min_u2i = max_u2i;
3283  for (int offset=rowptr_1D[i]; offset<rowptr_1D[i+1]; offset++)
3284  {
3285  int j = colind_1D[offset];
3286  double u2j = (std::pow(u_dof[j],2.) +
3287  std::pow(v_dof[j],2.));
3288  max_u2i = fmax(max_u2i,u2j);
3289  min_u2i = fmin(min_u2i,u2j);
3290  }
3291  double normi = 0.5*(max_u2i + min_u2i) + 1E-10;
3292  entropyResidualPerNode[i] = fabs(entropyResidualPerNode[i])/normi;
3293  }
3294  else // via smoothness indicator
3295  {
3296  // computation of beta
3297  double uStari = uStar_dof[i];
3298  double vStari = vStar_dof[i];
3299 
3300  double u_beta_numerator = 0., u_beta_denominator = 0.;
3301  double v_beta_numerator = 0., v_beta_denominator = 0.;
3302 
3303  // loop on sparsity pattern
3304  for (int offset=rowptr_1D[i]; offset<rowptr_1D[i+1]; offset++)
3305  {
3306  int j = colind_1D[offset];
3307  double uStarj = uStar_dof[j];
3308  double vStarj = vStar_dof[j];
3309 
3310  // for u component
3311  u_beta_numerator += (uStarj - uStari);
3312  u_beta_denominator += fabs(uStarj - uStari);
3313  // for v component
3314  v_beta_numerator += (vStarj - vStari);
3315  v_beta_denominator += fabs(vStarj - vStari);
3316  }
3317  double u_beta = fabs(u_beta_numerator)/(u_beta_denominator+1E-10);
3318  double v_beta = fabs(v_beta_numerator)/(v_beta_denominator+1E-10);
3319  // compute psi=beta^power
3320  if (ANISOTROPIC_DIFFUSION==1)
3321  {
3322  uStar_psi[i] = (POWER_SMOOTHNESS_INDICATOR==0 ? 1.0 : std::pow(u_beta, POWER_SMOOTHNESS_INDICATOR));
3323  vStar_psi[i] = (POWER_SMOOTHNESS_INDICATOR==0 ? 1.0 : std::pow(v_beta, POWER_SMOOTHNESS_INDICATOR));
3324  }
3325  else // ISOTROPIC ARTIFICIAL DIFFUSION
3326  {
3327  double psi = (POWER_SMOOTHNESS_INDICATOR==0 ? 1.0 : std::pow(fmax(u_beta,v_beta), POWER_SMOOTHNESS_INDICATOR));
3328  uStar_psi[i] = psi;
3329  vStar_psi[i] = psi;
3330  }
3331  // for computation of gamma
3332  uStar_hi[i] /= den_hi[i];
3333  vStar_hi[i] /= den_hi[i];
3334  }
3335  }
3336 
3337  if (ARTIFICIAL_VISCOSITY==3)
3338  {
3339  for(int eN=0;eN<nElements_global;eN++)
3340  {
3341  double uStar_He = element_uStar_He[eN];
3342  double vStar_He = element_vStar_He[eN];
3343  for(int i=0;i<nDOF_test_element;i++)
3344  {
3345  register int eN_i=eN*nDOF_test_element+i;
3346  register int gi = vel_l2g[eN_i]; // offset=0, stride=1
3347  uStar_min_hiHe[gi] = fmin(uStar_min_hiHe[gi], uStar_hi[gi]*uStar_He);
3348  vStar_min_hiHe[gi] = fmin(vStar_min_hiHe[gi], vStar_hi[gi]*vStar_He);
3349  }
3350  }
3351  }
3352 
3353  // EXTRA LOOP ON DOFs to COMPUTE GAMMA INDICATOR//
3354  if (ARTIFICIAL_VISCOSITY==3)
3355  {
3356  for (int i=0; i<numDOFs_1D; i++)
3357  {
3358  // for gamma indicator
3359  double uStar_hi2 = uStar_hi[i]*uStar_hi[i];
3360  double vStar_hi2 = vStar_hi[i]*vStar_hi[i];
3361  if (isBoundary_1D[i] == 1)
3362  {
3363  uStar_gamma[i] = 1; // set gamma=1 since at boundary we don't have enough information
3364  vStar_gamma[i] = 1;
3365  }
3366  else
3367  {
3368  if (ANISOTROPIC_DIFFUSION==1)
3369  {
3370  uStar_gamma[i] = 1.-fmax(0, fmin(uStar_hi2, C_FOR_GAMMA_INDICATOR*uStar_min_hiHe[i]))/(uStar_hi2+EPS_FOR_GAMMA_INDICATOR);
3371  vStar_gamma[i] = 1.-fmax(0, fmin(vStar_hi2, C_FOR_GAMMA_INDICATOR*vStar_min_hiHe[i]))/(vStar_hi2+EPS_FOR_GAMMA_INDICATOR);
3372  }
3373  else // ISOTROPIC ARTIFICIAL DIFFUSION
3374  {
3375  double gamma = fmax(1.-fmax(0, fmin(uStar_hi2, C_FOR_GAMMA_INDICATOR*uStar_min_hiHe[i]))/(uStar_hi2+EPS_FOR_GAMMA_INDICATOR),
3376  1.-fmax(0, fmin(vStar_hi2, C_FOR_GAMMA_INDICATOR*vStar_min_hiHe[i]))/(vStar_hi2+EPS_FOR_GAMMA_INDICATOR));
3377  uStar_gamma[i] = gamma;
3378  vStar_gamma[i] = gamma;
3379  }
3380  }
3381  }
3382  }
3383  // SECOND LOOP ON DOFs //
3384  int ij=0;
3385  for (int i=0; i<numDOFs_1D; i++)
3386  {
3387  int ii;
3388  double uStar_dii = 0;
3389  double vStar_dii = 0;
3390  double ui = u_dof[i];
3391  double vi = v_dof[i];
3392 
3393  double ith_u_dissipative_term = 0;
3394  double ith_v_dissipative_term = 0;
3395 
3396  double uStar_alphai = USE_GAMMA_INDICATOR==1 ? fmin(uStar_psi[i], uStar_gamma[i]) : uStar_psi[i];
3397  double vStar_alphai = USE_GAMMA_INDICATOR==1 ? fmin(vStar_psi[i], vStar_gamma[i]) : vStar_psi[i];
3398 
3399  for (int offset=rowptr_1D[i]; offset<rowptr_1D[i+1]; offset++)
3400  {
3401  int j = colind_1D[offset];
3402  if (i!=j)
3403  {
3404  double uj = u_dof[j];
3405  double vj = v_dof[j];
3406 
3407  double uStar_alphaj = USE_GAMMA_INDICATOR==1 ? fmin(uStar_psi[j], uStar_gamma[j]) : uStar_psi[j];
3408  double vStar_alphaj = USE_GAMMA_INDICATOR==1 ? fmin(vStar_psi[j], vStar_gamma[j]) : vStar_psi[j];
3409 
3410  if (ARTIFICIAL_VISCOSITY==4) // via entropy viscosity
3411  {
3412  double dEVij = fmax(laggedEntropyResidualPerNode[i],
3413  laggedEntropyResidualPerNode[j]);
3414  double dLij = fmax(0.,fmax(TransportMatrix[ij],
3416  uStar_dMatrix[ij] = fmin(dLij,cE*dEVij);
3417  vStar_dMatrix[i] = uStar_dMatrix[ij];
3418  }
3419  else // via smoothness indicator
3420  {
3421  uStar_dMatrix[ij] = fmax(0.,fmax(uStar_alphai*TransportMatrix[ij], // by S. Badia
3422  uStar_alphaj*TransposeTransportMatrix[ij]));
3423  vStar_dMatrix[ij] = fmax(0.,fmax(vStar_alphai*TransportMatrix[ij], // by S. Badia
3424  vStar_alphaj*TransposeTransportMatrix[ij]));
3425  }
3426  uStar_dii -= uStar_dMatrix[ij];
3427  vStar_dii -= vStar_dMatrix[ij];
3428  //dissipative terms
3429  ith_u_dissipative_term += uStar_dMatrix[ij]*(uj-ui);
3430  ith_v_dissipative_term += vStar_dMatrix[ij]*(vj-vi);
3431  }
3432  else
3433  {
3434  ii = ij;
3435  }
3436  // update ij
3437  ij++;
3438  }
3439  uStar_dMatrix[ii] = uStar_dii;
3440  vStar_dMatrix[ii] = vStar_dii;
3441  globalResidual[offset_u+stride_u*i] += -ith_u_dissipative_term;
3442  globalResidual[offset_v+stride_v*i] += -ith_v_dissipative_term;
3443  }
3444  }
3445 
3446  //
3447  //loop over the surrogate boundaries in SB method and assembly into residual
3448  //
3449  if(USE_SBM>0)
3450  {
3451  if(USE_SBM==1)
3452  {
3453  std::memset(particle_netForces.data(),0,nParticles*3*sizeof(double));
3454  std::memset(particle_netMoments.data(),0,nParticles*3*sizeof(double));
3455  }
3456  for (int ebN_s=0;ebN_s < surrogate_boundaries.size();ebN_s++)
3457  {
3458  // Initialization of the force to 0
3459  register double Fx = 0.0, Fy = 0.0, Fxp = 0.0, Fyp = 0.0, surfaceArea=0.0, Mz = 0.0;
3460  register int ebN = surrogate_boundaries[ebN_s],
3461  eN = elementBoundaryElementsArray[ebN*2+surrogate_boundary_elements[ebN_s]],
3462  ebN_local = elementBoundaryLocalElementBoundariesArray[ebN*2+surrogate_boundary_elements[ebN_s]],
3463  eN_nDOF_trial_element = eN*nDOF_trial_element;
3464  register double elementResidual_mesh[nDOF_test_element],
3465  elementResidual_p[nDOF_test_element],
3466  elementResidual_u[nDOF_test_element],
3467  elementResidual_v[nDOF_test_element],
3468  //elementResidual_w[nDOF_test_element],
3469  eps_rho,eps_mu;
3470  //This assumption is wrong for parallel: If one of nodes of this edge is owned by this processor,
3471  //then the integral over this edge has contribution to the residual and Jacobian.
3472  //if (ebN >= nElementBoundaries_owned) continue;
3473  //std::cout<<"Surrogate edge "<<ebN<<" element neighbor "<<eN<<" local element boundary "<<ebN_local<<std::endl;
3474  for (int i=0;i<nDOF_test_element;i++)
3475  {
3476  elementResidual_mesh[i]=0.0;
3477  elementResidual_p[i]=0.0;
3478  elementResidual_u[i]=0.0;
3479  elementResidual_v[i]=0.0;
3480  /* elementResidual_w[i]=0.0; */
3481  }
3482  for (int kb=0;kb<nQuadraturePoints_elementBoundary;kb++)
3483  {
3484  register int ebN_kb = ebN*nQuadraturePoints_elementBoundary+kb,
3485  /* ebNE_kb_nSpace = ebNE_kb*nSpace, */
3486  ebN_local_kb = ebN_local*nQuadraturePoints_elementBoundary+kb,
3487  ebN_local_kb_nSpace = ebN_local_kb*nSpace;
3488  register double
3489  u_ext=0.0,
3490  v_ext=0.0,
3491  bc_u_ext=0.0,
3492  bc_v_ext=0.0,
3493  grad_u_ext[nSpace],
3494  grad_v_ext[nSpace],
3495  jac_ext[nSpace*nSpace],
3496  jacDet_ext,
3497  jacInv_ext[nSpace*nSpace],
3498  boundaryJac[nSpace*(nSpace-1)],
3499  metricTensor[(nSpace-1)*(nSpace-1)],
3500  metricTensorDetSqrt,
3501  dS,p_test_dS[nDOF_test_element],vel_test_dS[nDOF_test_element],
3502  p_grad_trial_trace[nDOF_trial_element*nSpace],vel_grad_trial_trace[nDOF_trial_element*nSpace],
3503  vel_grad_test_dS[nDOF_trial_element*nSpace],
3504  normal[2],x_ext,y_ext,z_ext,xt_ext,yt_ext,zt_ext,integralScaling,
3505  G[nSpace*nSpace],G_dd_G,tr_G,h_phi,h_penalty,penalty,
3506  force_x,force_y,force_z,force_p_x,force_p_y,force_p_z,force_v_x,force_v_y,force_v_z,r_x,r_y,r_z;
3507  //compute information about mapping from reference element to physical element
3508  ck.calculateMapping_elementBoundary(eN,
3509  ebN_local,
3510  kb,
3511  ebN_local_kb,
3512  mesh_dof.data(),
3513  mesh_l2g.data(),
3514  mesh_trial_trace_ref.data(),
3515  mesh_grad_trial_trace_ref.data(),
3516  boundaryJac_ref.data(),
3517  jac_ext,
3518  jacDet_ext,
3519  jacInv_ext,
3520  boundaryJac,
3521  metricTensor,
3522  metricTensorDetSqrt,
3523  normal_ref.data(),
3524  normal,
3525  x_ext,y_ext,z_ext);
3526  ck.calculateMappingVelocity_elementBoundary(eN,
3527  ebN_local,
3528  kb,
3529  ebN_local_kb,
3530  mesh_velocity_dof.data(),
3531  mesh_l2g.data(),
3532  mesh_trial_trace_ref.data(),
3533  xt_ext,yt_ext,zt_ext,
3534  normal,
3535  boundaryJac,
3536  metricTensor,
3537  integralScaling);
3538  dS = metricTensorDetSqrt*dS_ref[kb];
3539  //get the metric tensor
3540  ck.calculateG(jacInv_ext,G,G_dd_G,tr_G);
3541  //compute shape and solution information
3542  //shape
3543  ck.gradTrialFromRef(&vel_grad_trial_trace_ref[ebN_local_kb_nSpace*nDOF_trial_element],jacInv_ext,vel_grad_trial_trace);
3544  //solution and gradients
3545  ck.valFromDOF(u_dof.data(),&vel_l2g[eN_nDOF_trial_element],&vel_trial_trace_ref[ebN_local_kb*nDOF_test_element],u_ext);
3546  ck.valFromDOF(v_dof.data(),&vel_l2g[eN_nDOF_trial_element],&vel_trial_trace_ref[ebN_local_kb*nDOF_test_element],v_ext);
3547 
3548  ck.gradFromDOF(u_dof.data(),&vel_l2g[eN_nDOF_trial_element],vel_grad_trial_trace,grad_u_ext);
3549  ck.gradFromDOF(v_dof.data(),&vel_l2g[eN_nDOF_trial_element],vel_grad_trial_trace,grad_v_ext);
3550  //precalculate test function products with integration weights
3551  for (int j=0;j<nDOF_trial_element;j++)
3552  {
3553  vel_test_dS[j] = vel_test_trace_ref[ebN_local_kb*nDOF_test_element+j]*dS;
3554  for (int I=0;I<nSpace;I++)
3555  vel_grad_test_dS[j*nSpace+I] = vel_grad_trial_trace[j*nSpace+I]*dS;//cek hack, using trial
3556  }
3557 
3558  double dist = 0.0;
3559  double distance[2], P_normal[2], P_tangent[2]; // distance vector, normal and tangent of the physical boundary
3560 
3561 
3562 
3563  if(use_ball_as_particle==1)
3564  {
3565  get_distance_to_ball(nParticles,ball_center.data(),ball_radius.data(),
3566  x_ext,y_ext,z_ext,
3567  dist);
3568  get_normal_to_ith_ball(nParticles,ball_center.data(),ball_radius.data(),
3570  x_ext,y_ext,z_ext,
3571  P_normal[0],P_normal[1]);
3572  get_velocity_to_ith_ball(nParticles,ball_center.data(),ball_radius.data(),
3573  ball_velocity.data(),ball_angular_velocity.data(),
3575  x_ext-dist*P_normal[0],//corresponding point on the boundary of the particle
3576  y_ext-dist*P_normal[1],
3577  0.0,//z_ext,
3578  bc_u_ext,bc_v_ext);
3579  }
3580  else
3581  {
3582  dist = ebq_global_phi_solid[ebN_kb];
3583  P_normal[0] = ebq_global_grad_phi_solid[ebN_kb*3+0];
3584  P_normal[1] = ebq_global_grad_phi_solid[ebN_kb*3+1];
3585  bc_u_ext = ebq_particle_velocity_solid [ebN_kb*3+0];
3586  bc_v_ext = ebq_particle_velocity_solid [ebN_kb*3+1];
3587 
3588  }
3589 
3590  ck.calculateGScale(G,normal,h_penalty);
3591  //
3592  //update the element and global residual storage
3593  //
3594  assert(h_penalty>0.0);
3595  if (h_penalty < std::abs(dist))
3596  h_penalty = std::abs(dist);
3597  distance[0] = -P_normal[0]*dist;//distance=vector from \tilde{x} to x. It holds also when dist<0.0
3598  distance[1] = -P_normal[1]*dist;
3599  P_tangent[0] = -P_normal[1];
3600  P_tangent[1] = P_normal[0];
3601  double visco = nu_0*rho_0;
3602  double C_adim = C_sbm*visco/h_penalty;
3603  double beta_adim = beta_sbm*visco/h_penalty;
3604 
3605  const double grad_u_d[2] = {get_dot_product(distance,grad_u_ext),
3606  get_dot_product(distance,grad_v_ext)};
3607  double res[2];
3608  const double u_m_uD[2] = {u_ext - bc_u_ext,v_ext - bc_v_ext};
3609  const double zero_vec[2]={0.,0.};
3610  const double grad_u_t[2] = {get_dot_product(P_tangent,grad_u_ext),
3611  get_dot_product(P_tangent,grad_v_ext)};
3612  for (int i=0;i<nDOF_test_element;i++)
3613  {
3614  int eN_i = eN*nDOF_test_element+i;
3615 
3616  int GlobPos_u = offset_u+stride_u*vel_l2g[eN_i];
3617  int GlobPos_v = offset_v+stride_v*vel_l2g[eN_i];
3618  double phi_i = vel_test_dS[i];
3619  double Gxphi_i = vel_grad_test_dS[i*nSpace+0];
3620  double Gyphi_i = vel_grad_test_dS[i*nSpace+1];
3621  double *grad_phi_i = &vel_grad_test_dS[i*nSpace+0];
3622  const double grad_phi_i_dot_d = get_dot_product(distance,grad_phi_i);
3623  const double grad_phi_i_dot_t = get_dot_product(P_tangent,grad_phi_i);
3624 
3625  // (1)
3626  globalResidual[GlobPos_u] += C_adim*phi_i*u_m_uD[0];
3627  globalResidual[GlobPos_v] += C_adim*phi_i*u_m_uD[1];
3628  Fx += C_adim*phi_i*u_m_uD[0];
3629  Fy += C_adim*phi_i*u_m_uD[1];
3630 
3631  // (2)
3632  get_symmetric_gradient_dot_vec(grad_u_ext,grad_v_ext,normal,res);//Use normal for consistency
3633  globalResidual[GlobPos_u] -= visco * phi_i*res[0];
3634  globalResidual[GlobPos_v] -= visco * phi_i*res[1];
3635  Fx -= visco * phi_i*res[0];
3636  Fy -= visco * phi_i*res[1];
3637 
3638  // (3)
3639  get_symmetric_gradient_dot_vec(grad_phi_i,zero_vec,normal,res);
3640  globalResidual[GlobPos_u] -= visco * get_dot_product(u_m_uD,res);//Use normal for consistency
3641  get_symmetric_gradient_dot_vec(zero_vec,grad_phi_i,normal,res);
3642  globalResidual[GlobPos_v] -= visco * get_dot_product(u_m_uD,res);//Use normal for consistency
3643  get_symmetric_gradient_dot_vec(grad_phi_i,zero_vec,normal,res);
3644  Fx -= visco * get_dot_product(u_m_uD,res);//Use normal for consistency
3645  get_symmetric_gradient_dot_vec(zero_vec,grad_phi_i,normal,res);
3646  Fy -= visco * get_dot_product(u_m_uD,res);//Use normal for consistency
3647 
3648  // (4)
3649  globalResidual[GlobPos_u] += C_adim*grad_phi_i_dot_d*u_m_uD[0];
3650  globalResidual[GlobPos_v] += C_adim*grad_phi_i_dot_d*u_m_uD[1];
3651  Fx += C_adim*grad_phi_i_dot_d*u_m_uD[0];
3652  Fy += C_adim*grad_phi_i_dot_d*u_m_uD[1];
3653 
3654  // (5)
3655  globalResidual[GlobPos_u] += C_adim*grad_phi_i_dot_d*grad_u_d[0];
3656  globalResidual[GlobPos_v] += C_adim*grad_phi_i_dot_d*grad_u_d[1];
3657  Fx += C_adim*grad_phi_i_dot_d*grad_u_d[0];
3658  Fy += C_adim*grad_phi_i_dot_d*grad_u_d[1];
3659 
3660  // (6)
3661  globalResidual[GlobPos_u] += C_adim*phi_i*grad_u_d[0];
3662  globalResidual[GlobPos_v] += C_adim*phi_i*grad_u_d[1];
3663  Fx += C_adim*phi_i*grad_u_d[0];
3664  Fy += C_adim*phi_i*grad_u_d[1];
3665 
3666  // (7)
3667  get_symmetric_gradient_dot_vec(grad_phi_i,zero_vec,normal,res);//Use normal for consistency
3668  globalResidual[GlobPos_u] -= visco*get_dot_product(grad_u_d,res);
3669  get_symmetric_gradient_dot_vec(zero_vec,grad_phi_i,normal,res);//Use normal for consistency
3670  globalResidual[GlobPos_v] -= visco*get_dot_product(grad_u_d,res);
3671  get_symmetric_gradient_dot_vec(grad_phi_i,zero_vec,normal,res);//Use normal for consistency
3672  Fx -= visco*get_dot_product(grad_u_d,res);
3673  get_symmetric_gradient_dot_vec(zero_vec,grad_phi_i,normal,res);//Use normal for consistency
3674  Fy -= visco*get_dot_product(grad_u_d,res);
3675 
3676  //the penalization on the tangential derivative
3677  //B < Gw t , (Gu - GuD) t >
3678  globalResidual[GlobPos_u] += beta_adim*grad_u_t[0]*grad_phi_i_dot_t;
3679  globalResidual[GlobPos_v] += beta_adim*grad_u_t[1]*grad_phi_i_dot_t;
3680  Fx += beta_adim*grad_u_t[0]*grad_phi_i_dot_t;
3681  Fy += beta_adim*grad_u_t[1]*grad_phi_i_dot_t;
3682 
3683  }//i
3684 
3685  //
3686  // Forces
3687  //
3688  //compute pressure at the quadrature point of the edge from dof-value of the pressure
3689  double p_ext = 0.0;
3690  for (int i=0; i<nDOF_per_element_pressure;++i)
3691  {
3692  p_ext += p_dof[p_l2g[eN*nDOF_per_element_pressure+i]]*p_trial_trace_ref[ebN_local_kb*nDOF_per_element_pressure+i];
3693  }
3694  double nx = P_normal[0]; //YY: normal direction outward of the solid.
3695  double ny = P_normal[1];
3696  Fx -= p_ext*nx*dS;
3697  Fy -= p_ext*ny*dS;
3698  Fxp -= p_ext*nx*dS;
3699  Fyp -= p_ext*ny*dS;
3700  surfaceArea += dS;
3701  if(use_ball_as_particle==1)
3702  {
3703  r_x = x_ext - ball_center[surrogate_boundary_particle[ebN_s] * 3 + 0];
3704  r_y = y_ext - ball_center[surrogate_boundary_particle[ebN_s] * 3 + 1];
3705  }
3706  else
3707  {
3708  r_x = x_ext - particle_centroids[surrogate_boundary_particle[ebN_s] * 3 + 0];
3709  r_y = y_ext - particle_centroids[surrogate_boundary_particle[ebN_s] * 3 + 1];
3710  }
3711  Mz += r_x*Fy-r_y*Fx;
3712  }//kb
3713  if(USE_SBM==1
3714  && ebN < nElementBoundaries_owned)//avoid double counting
3715  {
3716  particle_surfaceArea[surrogate_boundary_particle[ebN_s]] += surfaceArea;
3717  particle_netForces[3*surrogate_boundary_particle[ebN_s]+0] += Fx;
3718  particle_netForces[3*surrogate_boundary_particle[ebN_s]+1] += Fy;
3719  particle_netForces[3*( nParticles+surrogate_boundary_particle[ebN_s])+0] += Fxp;
3720  particle_netForces[3*(2*nParticles+surrogate_boundary_particle[ebN_s])+0] += (Fx-Fxp);
3721  particle_netForces[3*( nParticles+surrogate_boundary_particle[ebN_s])+1] += Fyp;
3722  particle_netForces[3*(2*nParticles+surrogate_boundary_particle[ebN_s])+1] += (Fy-Fyp);
3723  particle_netMoments[3*surrogate_boundary_particle[ebN_s]+2]+= Mz;
3724  }
3725  }//ebN_s
3726  //std::cout<<" sbm force over surrogate boundary is: "<<Fx<<"\t"<<Fy<<std::endl;
3727  //
3728  }
3729  //loop over exterior element boundaries to calculate surface integrals and load into element and global residuals
3730  //
3731  //ebNE is the Exterior element boundary INdex
3732  //ebN is the element boundary INdex
3733  //eN is the element index
3734  gf.useExact=false;
3735  gf_s.useExact=false;
3736  for (int ebNE = 0; ebNE < nExteriorElementBoundaries_global; ebNE++)
3737  {
3738  register int ebN = exteriorElementBoundariesArray[ebNE],
3739  eN = elementBoundaryElementsArray[ebN*2+0],
3740  ebN_local = elementBoundaryLocalElementBoundariesArray[ebN*2+0],
3741  eN_nDOF_trial_element = eN*nDOF_trial_element;
3742  register double elementResidual_mesh[nDOF_test_element],
3743  elementResidual_p[nDOF_test_element],
3744  elementResidual_u[nDOF_test_element],
3745  elementResidual_v[nDOF_test_element],
3746  //elementResidual_w[nDOF_test_element],
3747  eps_rho,eps_mu;
3748  const double* elementResidual_w(NULL);
3749  for (int i=0;i<nDOF_test_element;i++)
3750  {
3751  elementResidual_mesh[i]=0.0;
3752  elementResidual_p[i]=0.0;
3753  elementResidual_u[i]=0.0;
3754  elementResidual_v[i]=0.0;
3755  /* elementResidual_w[i]=0.0; */
3756  }
3757  for (int kb=0;kb<nQuadraturePoints_elementBoundary;kb++)
3758  {
3759  register int ebNE_kb = ebNE*nQuadraturePoints_elementBoundary+kb,
3760  ebNE_kb_nSpace = ebNE_kb*nSpace,
3761  ebN_local_kb = ebN_local*nQuadraturePoints_elementBoundary+kb,
3762  ebN_local_kb_nSpace = ebN_local_kb*nSpace;
3763  register double p_ext=0.0,
3764  u_ext=0.0,
3765  v_ext=0.0,
3766  w_ext=0.0,
3767  grad_p_ext[nSpace],
3768  grad_u_ext[nSpace],
3769  grad_v_ext[nSpace],
3770  grad_w_ext[nSpace],
3771  mom_u_acc_ext=0.0,
3772  dmom_u_acc_u_ext=0.0,
3773  mom_v_acc_ext=0.0,
3774  dmom_v_acc_v_ext=0.0,
3775  mom_w_acc_ext=0.0,
3776  dmom_w_acc_w_ext=0.0,
3777  mass_adv_ext[nSpace],
3778  dmass_adv_u_ext[nSpace],
3779  dmass_adv_v_ext[nSpace],
3780  dmass_adv_w_ext[nSpace],
3781  mom_u_adv_ext[nSpace],
3782  dmom_u_adv_u_ext[nSpace],
3783  dmom_u_adv_v_ext[nSpace],
3784  dmom_u_adv_w_ext[nSpace],
3785  mom_v_adv_ext[nSpace],
3786  dmom_v_adv_u_ext[nSpace],
3787  dmom_v_adv_v_ext[nSpace],
3788  dmom_v_adv_w_ext[nSpace],
3789  mom_w_adv_ext[nSpace],
3790  dmom_w_adv_u_ext[nSpace],
3791  dmom_w_adv_v_ext[nSpace],
3792  dmom_w_adv_w_ext[nSpace],
3793  mom_uu_diff_ten_ext[nSpace],
3794  mom_vv_diff_ten_ext[nSpace],
3795  mom_ww_diff_ten_ext[nSpace],
3796  mom_uv_diff_ten_ext[1],
3797  mom_uw_diff_ten_ext[1],
3798  mom_vu_diff_ten_ext[1],
3799  mom_vw_diff_ten_ext[1],
3800  mom_wu_diff_ten_ext[1],
3801  mom_wv_diff_ten_ext[1],
3802  mom_u_source_ext=0.0,
3803  mom_v_source_ext=0.0,
3804  mom_w_source_ext=0.0,
3805  mom_u_ham_ext=0.0,
3806  dmom_u_ham_grad_p_ext[nSpace],
3807  dmom_u_ham_grad_u_ext[nSpace],
3808  mom_v_ham_ext=0.0,
3809  dmom_v_ham_grad_p_ext[nSpace],
3810  dmom_v_ham_grad_v_ext[nSpace],
3811  mom_w_ham_ext=0.0,
3812  dmom_w_ham_grad_p_ext[nSpace],
3813  dmom_w_ham_grad_w_ext[nSpace],
3814  dmom_u_adv_p_ext[nSpace],
3815  dmom_v_adv_p_ext[nSpace],
3816  dmom_w_adv_p_ext[nSpace],
3817  flux_mass_ext=0.0,
3818  flux_mom_u_adv_ext=0.0,
3819  flux_mom_v_adv_ext=0.0,
3820  flux_mom_w_adv_ext=0.0,
3821  flux_mom_uu_diff_ext=0.0,
3822  flux_mom_uv_diff_ext=0.0,
3823  flux_mom_uw_diff_ext=0.0,
3824  flux_mom_vu_diff_ext=0.0,
3825  flux_mom_vv_diff_ext=0.0,
3826  flux_mom_vw_diff_ext=0.0,
3827  flux_mom_wu_diff_ext=0.0,
3828  flux_mom_wv_diff_ext=0.0,
3829  flux_mom_ww_diff_ext=0.0,
3830  bc_p_ext=0.0,
3831  bc_u_ext=0.0,
3832  bc_v_ext=0.0,
3833  bc_w_ext=0.0,
3834  bc_mom_u_acc_ext=0.0,
3835  bc_dmom_u_acc_u_ext=0.0,
3836  bc_mom_v_acc_ext=0.0,
3837  bc_dmom_v_acc_v_ext=0.0,
3838  bc_mom_w_acc_ext=0.0,
3839  bc_dmom_w_acc_w_ext=0.0,
3840  bc_mass_adv_ext[nSpace],
3841  bc_dmass_adv_u_ext[nSpace],
3842  bc_dmass_adv_v_ext[nSpace],
3843  bc_dmass_adv_w_ext[nSpace],
3844  bc_mom_u_adv_ext[nSpace],
3845  bc_dmom_u_adv_u_ext[nSpace],
3846  bc_dmom_u_adv_v_ext[nSpace],
3847  bc_dmom_u_adv_w_ext[nSpace],
3848  bc_mom_v_adv_ext[nSpace],
3849  bc_dmom_v_adv_u_ext[nSpace],
3850  bc_dmom_v_adv_v_ext[nSpace],
3851  bc_dmom_v_adv_w_ext[nSpace],
3852  bc_mom_w_adv_ext[nSpace],
3853  bc_dmom_w_adv_u_ext[nSpace],
3854  bc_dmom_w_adv_v_ext[nSpace],
3855  bc_dmom_w_adv_w_ext[nSpace],
3856  bc_mom_uu_diff_ten_ext[nSpace],
3857  bc_mom_vv_diff_ten_ext[nSpace],
3858  bc_mom_ww_diff_ten_ext[nSpace],
3859  bc_mom_uv_diff_ten_ext[1],
3860  bc_mom_uw_diff_ten_ext[1],
3861  bc_mom_vu_diff_ten_ext[1],
3862  bc_mom_vw_diff_ten_ext[1],
3863  bc_mom_wu_diff_ten_ext[1],
3864  bc_mom_wv_diff_ten_ext[1],
3865  bc_mom_u_source_ext=0.0,
3866  bc_mom_v_source_ext=0.0,
3867  bc_mom_w_source_ext=0.0,
3868  bc_mom_u_ham_ext=0.0,
3869  bc_dmom_u_ham_grad_p_ext[nSpace],
3870  bc_dmom_u_ham_grad_u_ext[nSpace],
3871  bc_mom_v_ham_ext=0.0,
3872  bc_dmom_v_ham_grad_p_ext[nSpace],
3873  bc_dmom_v_ham_grad_v_ext[nSpace],
3874  bc_mom_w_ham_ext=0.0,
3875  bc_dmom_w_ham_grad_p_ext[nSpace],
3876  bc_dmom_w_ham_grad_w_ext[nSpace],
3877  jac_ext[nSpace*nSpace],
3878  jacDet_ext,
3879  jacInv_ext[nSpace*nSpace],
3880  boundaryJac[nSpace*(nSpace-1)],
3881  metricTensor[(nSpace-1)*(nSpace-1)],
3882  metricTensorDetSqrt,
3883  dS,p_test_dS[nDOF_test_element],vel_test_dS[nDOF_test_element],
3884  p_grad_trial_trace[nDOF_trial_element*nSpace],vel_grad_trial_trace[nDOF_trial_element*nSpace],
3885  vel_grad_test_dS[nDOF_trial_element*nSpace],
3886  normal[2],x_ext,y_ext,z_ext,xt_ext,yt_ext,zt_ext,integralScaling,
3887  //VRANS
3888  porosity_ext,
3889  //
3890  G[nSpace*nSpace],G_dd_G,tr_G,h_phi,h_penalty,penalty,
3891  force_x,force_y,force_z,force_p_x,force_p_y,force_p_z,force_v_x,force_v_y,force_v_z,r_x,r_y,r_z;
3892  //compute information about mapping from reference element to physical element
3893  ck.calculateMapping_elementBoundary(eN,
3894  ebN_local,
3895  kb,
3896  ebN_local_kb,
3897  mesh_dof.data(),
3898  mesh_l2g.data(),
3899  mesh_trial_trace_ref.data(),
3900  mesh_grad_trial_trace_ref.data(),
3901  boundaryJac_ref.data(),
3902  jac_ext,
3903  jacDet_ext,
3904  jacInv_ext,
3905  boundaryJac,
3906  metricTensor,
3907  metricTensorDetSqrt,
3908  normal_ref.data(),
3909  normal,
3910  x_ext,y_ext,z_ext);
3911  ck.calculateMappingVelocity_elementBoundary(eN,
3912  ebN_local,
3913  kb,
3914  ebN_local_kb,
3915  mesh_velocity_dof.data(),
3916  mesh_l2g.data(),
3917  mesh_trial_trace_ref.data(),
3918  xt_ext,yt_ext,zt_ext,
3919  normal,
3920  boundaryJac,
3921  metricTensor,
3922  integralScaling);
3923  //xt_ext=0.0;yt_ext=0.0;zt_ext=0.0;
3924  //std::cout<<"xt_ext "<<xt_ext<<'\t'<<yt_ext<<'\t'<<zt_ext<<std::endl;
3925  //std::cout<<"x_ext "<<x_ext<<'\t'<<y_ext<<'\t'<<z_ext<<std::endl;
3926  //std::cout<<"integralScaling - metricTensorDetSrt ==============================="<<integralScaling-metricTensorDetSqrt<<std::endl;
3927  /* std::cout<<"metricTensorDetSqrt "<<metricTensorDetSqrt */
3928  /* <<"dS_ref[kb]"<<dS_ref[kb]<<std::endl; */
3929  //dS = ((1.0-MOVING_DOMAIN)*metricTensorDetSqrt + MOVING_DOMAIN*integralScaling)*dS_ref[kb];//cek need to test effect on accuracy
3930  dS = metricTensorDetSqrt*dS_ref[kb];
3931  //get the metric tensor
3932  //cek todo use symmetry
3933  ck.calculateG(jacInv_ext,G,G_dd_G,tr_G);
3934  ck.calculateGScale(G,&ebqe_normal_phi_ext[ebNE_kb_nSpace],h_phi);
3935 
3936  eps_rho = epsFact_rho*(useMetrics*h_phi+(1.0-useMetrics)*elementDiameter[eN]);
3937  eps_mu = epsFact_mu *(useMetrics*h_phi+(1.0-useMetrics)*elementDiameter[eN]);
3938  double particle_eps = particle_epsFact*(useMetrics*h_phi+(1.0-useMetrics)*elementDiameter[eN]);
3939 
3940  //compute shape and solution information
3941  //shape
3942  /* ck.gradTrialFromRef(&p_grad_trial_trace_ref[ebN_local_kb_nSpace*nDOF_trial_element],jacInv_ext,p_grad_trial_trace); */
3943  ck.gradTrialFromRef(&vel_grad_trial_trace_ref[ebN_local_kb_nSpace*nDOF_trial_element],jacInv_ext,vel_grad_trial_trace);
3944  //cek hack use trial ck.gradTrialFromRef(&vel_grad_test_trace_ref[ebN_local_kb_nSpace*nDOF_trial_element],jacInv_ext,vel_grad_test_trace);
3945  //solution and gradients
3946  /* ck.valFromDOF(p_dof,&p_l2g[eN_nDOF_trial_element],&p_trial_trace_ref[ebN_local_kb*nDOF_test_element],p_ext); */
3947  p_ext = ebqe_p[ebNE_kb];
3948  ck.valFromDOF(u_dof.data(),&vel_l2g[eN_nDOF_trial_element],&vel_trial_trace_ref[ebN_local_kb*nDOF_test_element],u_ext);
3949  ck.valFromDOF(v_dof.data(),&vel_l2g[eN_nDOF_trial_element],&vel_trial_trace_ref[ebN_local_kb*nDOF_test_element],v_ext);
3950  /* ck.valFromDOF(w_dof,&vel_l2g[eN_nDOF_trial_element],&vel_trial_trace_ref[ebN_local_kb*nDOF_test_element],w_ext); */
3951  /* ck.gradFromDOF(p_dof,&p_l2g[eN_nDOF_trial_element],p_grad_trial_trace,grad_p_ext); */
3952  for (int I=0;I<nSpace;I++)
3953  grad_p_ext[I] = ebqe_grad_p[ebNE_kb_nSpace + I];
3954  ck.gradFromDOF(u_dof.data(),&vel_l2g[eN_nDOF_trial_element],vel_grad_trial_trace,grad_u_ext);
3955  ck.gradFromDOF(v_dof.data(),&vel_l2g[eN_nDOF_trial_element],vel_grad_trial_trace,grad_v_ext);
3956  /* ck.gradFromDOF(w_dof,&vel_l2g[eN_nDOF_trial_element],vel_grad_trial_trace,grad_w_ext); */
3957  //precalculate test function products with integration weights
3958  for (int j=0;j<nDOF_trial_element;j++)
3959  {
3960  /* p_test_dS[j] = p_test_trace_ref[ebN_local_kb*nDOF_test_element+j]*dS; */
3961  vel_test_dS[j] = vel_test_trace_ref[ebN_local_kb*nDOF_test_element+j]*dS;
3962  for (int I=0;I<nSpace;I++)
3963  vel_grad_test_dS[j*nSpace+I] = vel_grad_trial_trace[j*nSpace+I]*dS;//cek hack, using trial
3964  }
3965  bc_p_ext = isDOFBoundary_p[ebNE_kb]*ebqe_bc_p_ext[ebNE_kb]+(1-isDOFBoundary_p[ebNE_kb])*p_ext;
3966  //note, our convention is that bc values at moving boundaries are relative to boundary velocity so we add it here
3967  bc_u_ext = isDOFBoundary_u[ebNE_kb]*(ebqe_bc_u_ext[ebNE_kb] + MOVING_DOMAIN*xt_ext) + (1-isDOFBoundary_u[ebNE_kb])*u_ext;
3968  bc_v_ext = isDOFBoundary_v[ebNE_kb]*(ebqe_bc_v_ext[ebNE_kb] + MOVING_DOMAIN*yt_ext) + (1-isDOFBoundary_v[ebNE_kb])*v_ext;
3969  /* bc_w_ext = isDOFBoundary_w[ebNE_kb]*(ebqe_bc_w_ext[ebNE_kb] + MOVING_DOMAIN*zt_ext) + (1-isDOFBoundary_w[ebNE_kb])*w_ext; */
3970  //VRANS
3971  porosity_ext = 1.0 - ebqe_vos_ext[ebNE_kb];
3972  //
3973  //calculate the pde coefficients using the solution and the boundary values for the solution
3974  //
3975  double distance_to_omega_solid = 1e10;
3976  if (use_ball_as_particle == 1)
3977  {
3978  get_distance_to_ball(nParticles, ball_center.data(), ball_radius.data(), x_ext, y_ext, z_ext, distance_to_omega_solid);
3979  }
3980  else
3981  {
3982  distance_to_omega_solid = ebq_global_phi_solid[ebN*nQuadraturePoints_elementBoundary+kb];
3983  }
3984  double eddy_viscosity_ext(0.),bc_eddy_viscosity_ext(0.); //not interested in saving boundary eddy viscosity for now
3985  evaluateCoefficients(eps_rho,
3986  eps_mu,
3987  particle_eps,
3988  sigma,
3989  rho_0,
3990  nu_0,
3991  rho_1,
3992  nu_1,
3993  elementDiameter[eN],
3994  smagorinskyConstant,
3995  turbulenceClosureModel,
3996  g.data(),
3997  useVF,
3998  ebqe_vf_ext[ebNE_kb],
3999  ebqe_phi_ext[ebNE_kb],
4000  &ebqe_normal_phi_ext[ebNE_kb_nSpace],
4001  distance_to_omega_solid,
4002  ebqe_kappa_phi_ext[ebNE_kb],
4003  //VRANS
4004  porosity_ext,
4005  //
4006  p_ext,
4007  grad_p_ext,
4008  grad_u_ext,
4009  grad_v_ext,
4010  grad_w_ext,
4011  u_ext,
4012  v_ext,
4013  w_ext,
4014  ebqe_velocity_star[ebNE_kb_nSpace+0],
4015  ebqe_velocity_star[ebNE_kb_nSpace+1],
4016  ebqe_velocity_star[ebNE_kb_nSpace+1],//hack,not used
4017  eddy_viscosity_ext,
4018  mom_u_acc_ext,
4019  dmom_u_acc_u_ext,
4020  mom_v_acc_ext,
4021  dmom_v_acc_v_ext,
4022  mom_w_acc_ext,
4023  dmom_w_acc_w_ext,
4024  mass_adv_ext,
4025  dmass_adv_u_ext,
4026  dmass_adv_v_ext,
4027  dmass_adv_w_ext,
4028  mom_u_adv_ext,
4029  dmom_u_adv_u_ext,
4030  dmom_u_adv_v_ext,
4031  dmom_u_adv_w_ext,
4032  mom_v_adv_ext,
4033  dmom_v_adv_u_ext,
4034  dmom_v_adv_v_ext,
4035  dmom_v_adv_w_ext,
4036  mom_w_adv_ext,
4037  dmom_w_adv_u_ext,
4038  dmom_w_adv_v_ext,
4039  dmom_w_adv_w_ext,
4040  mom_uu_diff_ten_ext,
4041  mom_vv_diff_ten_ext,
4042  mom_ww_diff_ten_ext,
4043  mom_uv_diff_ten_ext,
4044  mom_uw_diff_ten_ext,
4045  mom_vu_diff_ten_ext,
4046  mom_vw_diff_ten_ext,
4047  mom_wu_diff_ten_ext,
4048  mom_wv_diff_ten_ext,
4049  mom_u_source_ext,
4050  mom_v_source_ext,
4051  mom_w_source_ext,
4052  mom_u_ham_ext,
4053  dmom_u_ham_grad_p_ext,
4054  dmom_u_ham_grad_u_ext,
4055  mom_v_ham_ext,
4056  dmom_v_ham_grad_p_ext,
4057  dmom_v_ham_grad_v_ext,
4058  mom_w_ham_ext,
4059  dmom_w_ham_grad_p_ext,
4060  dmom_w_ham_grad_w_ext,
4061  ebqe_rho[ebNE_kb],
4062  ebqe_nu[ebNE_kb],
4063  KILL_PRESSURE_TERM,
4064  0,
4065  0., // mql: zero force term at boundary
4066  0.,
4067  0.,
4068  MATERIAL_PARAMETERS_AS_FUNCTION,
4069  ebqe_density_as_function[ebNE_kb],
4070  ebqe_dynamic_viscosity_as_function[ebNE_kb],
4071  USE_SBM,
4072  x_ext,y_ext,z_ext,
4073  use_ball_as_particle,
4074  ball_center.data(),
4075  ball_radius.data(),
4076  ball_velocity.data(),
4077  ball_angular_velocity.data(),
4078  INT_BY_PARTS_PRESSURE);
4079  evaluateCoefficients(eps_rho,
4080  eps_mu,
4081  particle_eps,
4082  sigma,
4083  rho_0,
4084  nu_0,
4085  rho_1,
4086  nu_1,
4087  elementDiameter[eN],
4088  smagorinskyConstant,
4089  turbulenceClosureModel,
4090  g.data(),
4091  useVF,
4092  bc_ebqe_vf_ext[ebNE_kb],
4093  bc_ebqe_phi_ext[ebNE_kb],
4094  &ebqe_normal_phi_ext[ebNE_kb_nSpace],
4095  distance_to_omega_solid,
4096  ebqe_kappa_phi_ext[ebNE_kb],
4097  //VRANS
4098  porosity_ext,
4099  //
4100  bc_p_ext,
4101  grad_p_ext,
4102  grad_u_ext,
4103  grad_v_ext,
4104  grad_w_ext,
4105  bc_u_ext,
4106  bc_v_ext,
4107  bc_w_ext,
4108  ebqe_velocity_star[ebNE_kb_nSpace+0],
4109  ebqe_velocity_star[ebNE_kb_nSpace+1],
4110  ebqe_velocity_star[ebNE_kb_nSpace+1],//hack,not used
4111  bc_eddy_viscosity_ext,
4112  bc_mom_u_acc_ext,
4113  bc_dmom_u_acc_u_ext,
4114  bc_mom_v_acc_ext,
4115  bc_dmom_v_acc_v_ext,
4116  bc_mom_w_acc_ext,
4117  bc_dmom_w_acc_w_ext,
4118  bc_mass_adv_ext,
4119  bc_dmass_adv_u_ext,
4120  bc_dmass_adv_v_ext,
4121  bc_dmass_adv_w_ext,
4122  bc_mom_u_adv_ext,
4123  bc_dmom_u_adv_u_ext,
4124  bc_dmom_u_adv_v_ext,
4125  bc_dmom_u_adv_w_ext,
4126  bc_mom_v_adv_ext,
4127  bc_dmom_v_adv_u_ext,
4128  bc_dmom_v_adv_v_ext,
4129  bc_dmom_v_adv_w_ext,
4130  bc_mom_w_adv_ext,
4131  bc_dmom_w_adv_u_ext,
4132  bc_dmom_w_adv_v_ext,
4133  bc_dmom_w_adv_w_ext,
4134  bc_mom_uu_diff_ten_ext,
4135  bc_mom_vv_diff_ten_ext,
4136  bc_mom_ww_diff_ten_ext,
4137  bc_mom_uv_diff_ten_ext,
4138  bc_mom_uw_diff_ten_ext,
4139  bc_mom_vu_diff_ten_ext,
4140  bc_mom_vw_diff_ten_ext,
4141  bc_mom_wu_diff_ten_ext,
4142  bc_mom_wv_diff_ten_ext,
4143  bc_mom_u_source_ext,
4144  bc_mom_v_source_ext,
4145  bc_mom_w_source_ext,
4146  bc_mom_u_ham_ext,
4147  bc_dmom_u_ham_grad_p_ext,
4148  bc_dmom_u_ham_grad_u_ext,
4149  bc_mom_v_ham_ext,
4150  bc_dmom_v_ham_grad_p_ext,
4151  bc_dmom_v_ham_grad_v_ext,
4152  bc_mom_w_ham_ext,
4153  bc_dmom_w_ham_grad_p_ext,
4154  bc_dmom_w_ham_grad_w_ext,
4155  ebqe_rho[ebNE_kb],
4156  ebqe_nu[ebNE_kb],
4157  KILL_PRESSURE_TERM,
4158  0,
4159  0., // mql: zero force term at boundary
4160  0.,
4161  0.,
4162  MATERIAL_PARAMETERS_AS_FUNCTION,
4163  ebqe_density_as_function[ebNE_kb],
4164  ebqe_dynamic_viscosity_as_function[ebNE_kb],
4165  USE_SBM,
4166  x_ext,y_ext,z_ext,
4167  use_ball_as_particle,
4168  ball_center.data(),
4169  ball_radius.data(),
4170  ball_velocity.data(),
4171  ball_angular_velocity.data(),
4172  INT_BY_PARTS_PRESSURE);
4173 
4174  //Turbulence closure model
4175  if (turbulenceClosureModel >= 3)
4176  {
4177  const double turb_var_grad_0_dummy[2] = {0.,0.};
4178  const double c_mu = 0.09;//mwf hack
4179  updateTurbulenceClosure(turbulenceClosureModel,
4180  eps_rho,
4181  eps_mu,
4182  rho_0,
4183  nu_0,
4184  rho_1,
4185  nu_1,
4186  useVF,
4187  ebqe_vf_ext[ebNE_kb],
4188  ebqe_phi_ext[ebNE_kb],
4189  porosity_ext,
4190  c_mu, //mwf hack
4191  ebqe_turb_var_0[ebNE_kb],
4192  ebqe_turb_var_1[ebNE_kb],
4193  turb_var_grad_0_dummy, //not needed
4194  eddy_viscosity_ext,
4195  mom_uu_diff_ten_ext,
4196  mom_vv_diff_ten_ext,
4197  mom_ww_diff_ten_ext,
4198  mom_uv_diff_ten_ext,
4199  mom_uw_diff_ten_ext,
4200  mom_vu_diff_ten_ext,
4201  mom_vw_diff_ten_ext,
4202  mom_wu_diff_ten_ext,
4203  mom_wv_diff_ten_ext,
4204  mom_u_source_ext,
4205  mom_v_source_ext,
4206  mom_w_source_ext);
4207 
4208  updateTurbulenceClosure(turbulenceClosureModel,
4209  eps_rho,
4210  eps_mu,
4211  rho_0,
4212  nu_0,
4213  rho_1,
4214  nu_1,
4215  useVF,
4216  bc_ebqe_vf_ext[ebNE_kb],
4217  bc_ebqe_phi_ext[ebNE_kb],
4218  porosity_ext,
4219  c_mu, //mwf hack
4220  ebqe_turb_var_0[ebNE_kb],
4221  ebqe_turb_var_1[ebNE_kb],
4222  turb_var_grad_0_dummy, //not needed
4223  bc_eddy_viscosity_ext,
4224  bc_mom_uu_diff_ten_ext,
4225  bc_mom_vv_diff_ten_ext,
4226  bc_mom_ww_diff_ten_ext,
4227  bc_mom_uv_diff_ten_ext,
4228  bc_mom_uw_diff_ten_ext,
4229  bc_mom_vu_diff_ten_ext,
4230  bc_mom_vw_diff_ten_ext,
4231  bc_mom_wu_diff_ten_ext,
4232  bc_mom_wv_diff_ten_ext,
4233  bc_mom_u_source_ext,
4234  bc_mom_v_source_ext,
4235  bc_mom_w_source_ext);
4236  }
4237 
4238 
4239  //
4240  //moving domain
4241  //
4242  mom_u_adv_ext[0] -= MOVING_DOMAIN*dmom_u_acc_u_ext*mom_u_acc_ext*xt_ext; // times rho*porosity. mql. CHECK.
4243  mom_u_adv_ext[1] -= MOVING_DOMAIN*dmom_u_acc_u_ext*mom_u_acc_ext*yt_ext;
4244  /* mom_u_adv_ext[2] -= MOVING_DOMAIN*dmom_u_acc_u_ext*mom_u_acc_ext*zt_ext; */
4245  dmom_u_adv_u_ext[0] -= MOVING_DOMAIN*dmom_u_acc_u_ext*xt_ext;
4246  dmom_u_adv_u_ext[1] -= MOVING_DOMAIN*dmom_u_acc_u_ext*yt_ext;
4247  /* dmom_u_adv_u_ext[2] -= MOVING_DOMAIN*dmom_u_acc_u_ext*zt_ext; */
4248 
4249  mom_v_adv_ext[0] -= MOVING_DOMAIN*dmom_v_acc_v_ext*mom_v_acc_ext*xt_ext;
4250  mom_v_adv_ext[1] -= MOVING_DOMAIN*dmom_v_acc_v_ext*mom_v_acc_ext*yt_ext;
4251  /* mom_v_adv_ext[2] -= MOVING_DOMAIN*dmom_v_acc_v_ext*mom_v_acc_ext*zt_ext; */
4252  dmom_v_adv_v_ext[0] -= MOVING_DOMAIN*dmom_v_acc_v_ext*xt_ext;
4253  dmom_v_adv_v_ext[1] -= MOVING_DOMAIN*dmom_v_acc_v_ext*yt_ext;
4254  /* dmom_v_adv_v_ext[2] -= MOVING_DOMAIN*dmom_v_acc_v_ext*zt_ext; */
4255 
4256  /* mom_w_adv_ext[0] -= MOVING_DOMAIN*dmom_w_acc_w_ext*mom_w_acc_ext*xt_ext; */
4257  /* mom_w_adv_ext[1] -= MOVING_DOMAIN*dmom_w_acc_w_ext*mom_w_acc_ext*yt_ext; */
4258  /* mom_w_adv_ext[2] -= MOVING_DOMAIN*dmom_w_acc_w_ext*mom_w_acc_ext*zt_ext; */
4259  /* dmom_w_adv_w_ext[0] -= MOVING_DOMAIN*dmom_w_acc_w_ext*xt_ext; */
4260  /* dmom_w_adv_w_ext[1] -= MOVING_DOMAIN*dmom_w_acc_w_ext*yt_ext; */
4261  /* dmom_w_adv_w_ext[2] -= MOVING_DOMAIN*dmom_w_acc_w_ext*zt_ext; */
4262 
4263  //bc's
4264  // mql. CHECK.
4265  bc_mom_u_adv_ext[0] -= MOVING_DOMAIN*dmom_u_acc_u_ext*bc_mom_u_acc_ext*xt_ext;
4266  bc_mom_u_adv_ext[1] -= MOVING_DOMAIN*dmom_u_acc_u_ext*bc_mom_u_acc_ext*yt_ext;
4267  /* bc_mom_u_adv_ext[2] -= MOVING_DOMAIN*dmom_u_acc_u_ext*bc_mom_u_acc_ext*zt_ext; */
4268 
4269  bc_mom_v_adv_ext[0] -= MOVING_DOMAIN*dmom_v_acc_v_ext*bc_mom_v_acc_ext*xt_ext;
4270  bc_mom_v_adv_ext[1] -= MOVING_DOMAIN*dmom_v_acc_v_ext*bc_mom_v_acc_ext*yt_ext;
4271  /* bc_mom_v_adv_ext[2] -= MOVING_DOMAIN*dmom_v_acc_v_ext*bc_mom_v_acc_ext*zt_ext; */
4272 
4273  /* bc_mom_w_adv_ext[0] -= MOVING_DOMAIN*dmom_w_acc_w_ext*bc_mom_w_acc_ext*xt_ext; */
4274  /* bc_mom_w_adv_ext[1] -= MOVING_DOMAIN*dmom_w_acc_w_ext*bc_mom_w_acc_ext*yt_ext; */
4275  /* bc_mom_w_adv_ext[2] -= MOVING_DOMAIN*dmom_w_acc_w_ext*bc_mom_w_acc_ext*zt_ext; */
4276  //
4277  //calculate the numerical fluxes
4278  //
4279  ck.calculateGScale(G,normal,h_penalty);
4280  penalty = useMetrics*C_b/h_penalty + (1.0-useMetrics)*ebqe_penalty_ext[ebNE_kb];
4281  exteriorNumericalAdvectiveFlux(isDOFBoundary_p[ebNE_kb],
4282  isDOFBoundary_u[ebNE_kb],
4283  isDOFBoundary_v[ebNE_kb],
4284  isDOFBoundary_w[ebNE_kb],
4285  isAdvectiveFluxBoundary_p[ebNE_kb],
4286  isAdvectiveFluxBoundary_u[ebNE_kb],
4287  isAdvectiveFluxBoundary_v[ebNE_kb],
4288  isAdvectiveFluxBoundary_w[ebNE_kb],
4289  dmom_u_ham_grad_p_ext[0],//=1/rho,
4290  bc_dmom_u_ham_grad_p_ext[0],//=1/bc_rho,
4291  normal,
4292  dmom_u_acc_u_ext,
4293  bc_p_ext,
4294  bc_u_ext,
4295  bc_v_ext,
4296  bc_w_ext,
4297  bc_mass_adv_ext,
4298  bc_mom_u_adv_ext,
4299  bc_mom_v_adv_ext,
4300  bc_mom_w_adv_ext,
4301  ebqe_bc_flux_mass_ext[ebNE_kb]+MOVING_DOMAIN*(xt_ext*normal[0]+yt_ext*normal[1]),//BC is relative mass flux
4302  ebqe_bc_flux_mom_u_adv_ext[ebNE_kb],
4303  ebqe_bc_flux_mom_v_adv_ext[ebNE_kb],
4304  ebqe_bc_flux_mom_w_adv_ext[ebNE_kb],
4305  p_ext,
4306  u_ext,
4307  v_ext,
4308  w_ext,
4309  mass_adv_ext,
4310  mom_u_adv_ext,
4311  mom_v_adv_ext,
4312  mom_w_adv_ext,
4313  dmass_adv_u_ext,
4314  dmass_adv_v_ext,
4315  dmass_adv_w_ext,
4316  dmom_u_adv_p_ext,
4317  dmom_u_adv_u_ext,
4318  dmom_u_adv_v_ext,
4319  dmom_u_adv_w_ext,
4320  dmom_v_adv_p_ext,
4321  dmom_v_adv_u_ext,
4322  dmom_v_adv_v_ext,
4323  dmom_v_adv_w_ext,
4324  dmom_w_adv_p_ext,
4325  dmom_w_adv_u_ext,
4326  dmom_w_adv_v_ext,
4327  dmom_w_adv_w_ext,
4328  flux_mass_ext,
4329  flux_mom_u_adv_ext,
4330  flux_mom_v_adv_ext,
4331  flux_mom_w_adv_ext,
4332  &ebqe_velocity_star[ebNE_kb_nSpace],
4333  &ebqe_velocity[ebNE_kb_nSpace]);
4334  // mql: save gradient of solution for other models and to compute errors
4335  for (int I=0;I<nSpace;I++)
4336  {
4337  ebqe_grad_u[ebNE_kb_nSpace+I] = grad_u_ext[I];
4338  ebqe_grad_v[ebNE_kb_nSpace+I] = grad_v_ext[I];
4339  /* ebqe_grad_w[ebNE_kb_nSpace+I] = grad_w_ext[I]; */
4340  }
4342  ebqe_phi_ext[ebNE_kb],
4343  sdInfo_u_u_rowptr.data(),
4344  sdInfo_u_u_colind.data(),
4345  isDOFBoundary_u[ebNE_kb],
4346  isDiffusiveFluxBoundary_u[ebNE_kb],
4347  normal,
4348  bc_mom_uu_diff_ten_ext,
4349  bc_u_ext,
4350  ebqe_bc_flux_u_diff_ext[ebNE_kb],
4351  mom_uu_diff_ten_ext,
4352  grad_u_ext,
4353  u_ext,
4354  penalty,//ebqe_penalty_ext[ebNE_kb],
4355  flux_mom_uu_diff_ext);
4357  ebqe_phi_ext[ebNE_kb],
4358  sdInfo_u_v_rowptr.data(),
4359  sdInfo_u_v_colind.data(),
4360  isDOFBoundary_v[ebNE_kb],
4361  isDiffusiveFluxBoundary_v[ebNE_kb],
4362  normal,
4363  bc_mom_uv_diff_ten_ext,
4364  bc_v_ext,
4365  0.0,//assume all of the flux gets applied in diagonal component
4366  mom_uv_diff_ten_ext,
4367  grad_v_ext,
4368  v_ext,
4369  penalty,//ebqe_penalty_ext[ebNE_kb],
4370  flux_mom_uv_diff_ext);
4371  /* exteriorNumericalDiffusiveFlux(eps_rho, */
4372  /* ebqe_phi_ext[ebNE_kb], */
4373  /* sdInfo_u_w_rowptr, */
4374  /* sdInfo_u_w_colind, */
4375  /* isDOFBoundary_w[ebNE_kb], */
4376  /* isDiffusiveFluxBoundary_u[ebNE_kb], */
4377  /* normal, */
4378  /* bc_mom_uw_diff_ten_ext, */
4379  /* bc_w_ext, */
4380  /* 0.0,//see above */
4381  /* mom_uw_diff_ten_ext, */
4382  /* grad_w_ext, */
4383  /* w_ext, */
4384  /* penalty,//ebqe_penalty_ext[ebNE_kb], */
4385  /* flux_mom_uw_diff_ext); */
4387  ebqe_phi_ext[ebNE_kb],
4388  sdInfo_v_u_rowptr.data(),
4389  sdInfo_v_u_colind.data(),
4390  isDOFBoundary_u[ebNE_kb],
4391  isDiffusiveFluxBoundary_u[ebNE_kb],
4392  normal,
4393  bc_mom_vu_diff_ten_ext,
4394  bc_u_ext,
4395  0.0,//see above
4396  mom_vu_diff_ten_ext,
4397  grad_u_ext,
4398  u_ext,
4399  penalty,//ebqe_penalty_ext[ebNE_kb],
4400  flux_mom_vu_diff_ext);
4402  ebqe_phi_ext[ebNE_kb],
4403  sdInfo_v_v_rowptr.data(),
4404  sdInfo_v_v_colind.data(),
4405  isDOFBoundary_v[ebNE_kb],
4406  isDiffusiveFluxBoundary_v[ebNE_kb],
4407  normal,
4408  bc_mom_vv_diff_ten_ext,
4409  bc_v_ext,
4410  ebqe_bc_flux_v_diff_ext[ebNE_kb],
4411  mom_vv_diff_ten_ext,
4412  grad_v_ext,
4413  v_ext,
4414  penalty,//ebqe_penalty_ext[ebNE_kb],
4415  flux_mom_vv_diff_ext);
4416  /* exteriorNumericalDiffusiveFlux(eps_rho, */
4417  /* ebqe_phi_ext[ebNE_kb], */
4418  /* sdInfo_v_w_rowptr, */
4419  /* sdInfo_v_w_colind, */
4420  /* isDOFBoundary_w[ebNE_kb], */
4421  /* isDiffusiveFluxBoundary_v[ebNE_kb], */
4422  /* normal, */
4423  /* bc_mom_vw_diff_ten_ext, */
4424  /* bc_w_ext, */
4425  /* 0.0,//see above */
4426  /* mom_vw_diff_ten_ext, */
4427  /* grad_w_ext, */
4428  /* w_ext, */
4429  /* penalty,//ebqe_penalty_ext[ebNE_kb], */
4430  /* flux_mom_vw_diff_ext); */
4431  /* exteriorNumericalDiffusiveFlux(eps_rho, */
4432  /* ebqe_phi_ext[ebNE_kb], */
4433  /* sdInfo_w_u_rowptr, */
4434  /* sdInfo_w_u_colind, */
4435  /* isDOFBoundary_u[ebNE_kb], */
4436  /* isDiffusiveFluxBoundary_w[ebNE_kb], */
4437  /* normal, */
4438  /* bc_mom_wu_diff_ten_ext, */
4439  /* bc_u_ext, */
4440  /* 0.0,//see above */
4441  /* mom_wu_diff_ten_ext, */
4442  /* grad_u_ext, */
4443  /* u_ext, */
4444  /* penalty,//ebqe_penalty_ext[ebNE_kb], */
4445  /* flux_mom_wu_diff_ext); */
4446  /* exteriorNumericalDiffusiveFlux(eps_rho, */
4447  /* ebqe_phi_ext[ebNE_kb], */
4448  /* sdInfo_w_v_rowptr, */
4449  /* sdInfo_w_v_colind, */
4450  /* isDOFBoundary_v[ebNE_kb], */
4451  /* isDiffusiveFluxBoundary_w[ebNE_kb], */
4452  /* normal, */
4453  /* bc_mom_wv_diff_ten_ext, */
4454  /* bc_v_ext, */
4455  /* 0.0,//see above */
4456  /* mom_wv_diff_ten_ext, */
4457  /* grad_v_ext, */
4458  /* v_ext, */
4459  /* penalty,//ebqe_penalty_ext[ebNE_kb], */
4460  /* flux_mom_wv_diff_ext); */
4461  /* exteriorNumericalDiffusiveFlux(eps_rho, */
4462  /* ebqe_phi_ext[ebNE_kb], */
4463  /* sdInfo_w_w_rowptr, */
4464  /* sdInfo_w_w_colind, */
4465  /* isDOFBoundary_w[ebNE_kb], */
4466  /* isDiffusiveFluxBoundary_w[ebNE_kb], */
4467  /* normal, */
4468  /* bc_mom_ww_diff_ten_ext, */
4469  /* bc_w_ext, */
4470  /* ebqe_bc_flux_w_diff_ext[ebNE_kb], */
4471  /* mom_ww_diff_ten_ext, */
4472  /* grad_w_ext, */
4473  /* w_ext, */
4474  /* penalty,//ebqe_penalty_ext[ebNE_kb], */
4475  /* flux_mom_ww_diff_ext); */
4476  flux[ebN*nQuadraturePoints_elementBoundary+kb] = flux_mass_ext;
4477  /* std::cout<<"external u,v,u_n " */
4478  /* <<ebqe_velocity[ebNE_kb_nSpace+0]<<'\t' */
4479  /* <<ebqe_velocity[ebNE_kb_nSpace+1]<<'\t' */
4480  /* <<flux[ebN*nQuadraturePoints_elementBoundary+kb]<<std::endl; */
4481  //
4482  //integrate the net force and moment on flagged boundaries
4483  //
4484  if (ebN < nElementBoundaries_owned)
4485  {
4486  force_v_x = (flux_mom_u_adv_ext + flux_mom_uu_diff_ext + flux_mom_uv_diff_ext + flux_mom_uw_diff_ext)/dmom_u_ham_grad_p_ext[0];//same as *rho
4487  force_v_y = (flux_mom_v_adv_ext + flux_mom_vu_diff_ext + flux_mom_vv_diff_ext + flux_mom_vw_diff_ext)/dmom_u_ham_grad_p_ext[0];
4488  //force_v_z = (flux_mom_wu_diff_ext + flux_mom_wv_diff_ext + flux_mom_ww_diff_ext)/dmom_u_ham_grad_p_ext[0];
4489 
4490  force_p_x = p_ext*normal[0];
4491  force_p_y = p_ext*normal[1];
4492  //force_p_z = p_ext*normal[2];
4493 
4494  force_x = force_p_x + force_v_x;
4495  force_y = force_p_y + force_v_y;
4496  //force_z = force_p_z + force_v_z;
4497 
4498  r_x = x_ext - barycenters[3*boundaryFlags[ebN]+0];
4499  r_y = y_ext - barycenters[3*boundaryFlags[ebN]+1];
4500  //r_z = z_ext - barycenters[3*boundaryFlags[ebN]+2];
4501 
4502  wettedAreas[boundaryFlags[ebN]] += dS*(1.0-ebqe_vf_ext[ebNE_kb]);
4503 
4504  netForces_p[3*boundaryFlags[ebN]+0] += force_p_x*dS;
4505  netForces_p[3*boundaryFlags[ebN]+1] += force_p_y*dS;
4506  //netForces_p[3*boundaryFlags[ebN]+2] += force_p_z*dS;
4507 
4508  netForces_v[3*boundaryFlags[ebN]+0] += force_v_x*dS;
4509  netForces_v[3*boundaryFlags[ebN]+1] += force_v_y*dS;
4510  //netForces_v[3*boundaryFlags[ebN]+2] += force_v_z*dS;
4511 
4512  //netMoments[3*boundaryFlags[ebN]+0] += (r_y*force_z - r_z*force_y)*dS;
4513  //netMoments[3*boundaryFlags[ebN]+1] += (r_z*force_x - r_x*force_z)*dS;
4514  netMoments[3*boundaryFlags[ebN]+2] += (r_x*force_y - r_y*force_x)*dS;
4515  }
4516  //
4517  //update residuals
4518  //
4519  for (int i=0;i<nDOF_test_element;i++)
4520  {
4521  /* elementResidual_mesh[i] -= ck.ExteriorElementBoundaryFlux(MOVING_DOMAIN*(xt_ext*normal[0]+yt_ext*normal[1]),p_test_dS[i]); */
4522  /* elementResidual_p[i] += ck.ExteriorElementBoundaryFlux(flux_mass_ext,p_test_dS[i]); */
4523  /* elementResidual_p[i] -= DM*ck.ExteriorElementBoundaryFlux(MOVING_DOMAIN*(xt_ext*normal[0]+yt_ext*normal[1]),p_test_dS[i]); */
4524  /* globalConservationError += ck.ExteriorElementBoundaryFlux(flux_mass_ext,p_test_dS[i]); */
4525  elementResidual_u[i] +=
4526  (INT_BY_PARTS_PRESSURE==1 ? p_ext*vel_test_dS[i]*normal[0] : 0.) +
4527  ck.ExteriorElementBoundaryFlux(flux_mom_u_adv_ext,vel_test_dS[i])+
4528  ck.ExteriorElementBoundaryFlux(flux_mom_uu_diff_ext,vel_test_dS[i])+
4529  ck.ExteriorElementBoundaryFlux(flux_mom_uv_diff_ext,vel_test_dS[i])+
4530  ck.ExteriorElementBoundaryDiffusionAdjoint(isDOFBoundary_u[ebNE_kb],
4531  isDiffusiveFluxBoundary_u[ebNE_kb],
4532  eb_adjoint_sigma,
4533  u_ext,
4534  bc_u_ext,
4535  normal,
4536  sdInfo_u_u_rowptr.data(),
4537  sdInfo_u_u_colind.data(),
4538  mom_uu_diff_ten_ext,
4539  &vel_grad_test_dS[i*nSpace])+
4540  ck.ExteriorElementBoundaryDiffusionAdjoint(isDOFBoundary_v[ebNE_kb],
4541  isDiffusiveFluxBoundary_u[ebNE_kb],
4542  eb_adjoint_sigma,
4543  v_ext,
4544  bc_v_ext,
4545  normal,
4546  sdInfo_u_v_rowptr.data(),
4547  sdInfo_u_v_colind.data(),
4548  mom_uv_diff_ten_ext,
4549  &vel_grad_test_dS[i*nSpace]);//+
4550  /* ck.ExteriorElementBoundaryDiffusionAdjoint(isDOFBoundary_w[ebNE_kb], */
4551  /* isDiffusiveFluxBoundary_u[ebNE_kb], */
4552  /* eb_adjoint_sigma, */
4553  /* w_ext, */
4554  /* bc_w_ext, */
4555  /* normal, */
4556  /* sdInfo_u_w_rowptr, */
4557  /* sdInfo_u_w_colind, */
4558  /* mom_uw_diff_ten_ext, */
4559  /* &vel_grad_test_dS[i*nSpace]); */
4560  elementResidual_v[i] +=
4561  (INT_BY_PARTS_PRESSURE==1 ? p_ext*vel_test_dS[i]*normal[1] : 0.) +
4562  ck.ExteriorElementBoundaryFlux(flux_mom_v_adv_ext,vel_test_dS[i]) +
4563  ck.ExteriorElementBoundaryFlux(flux_mom_vu_diff_ext,vel_test_dS[i])+
4564  ck.ExteriorElementBoundaryFlux(flux_mom_vv_diff_ext,vel_test_dS[i])+
4565  ck.ExteriorElementBoundaryDiffusionAdjoint(isDOFBoundary_u[ebNE_kb],
4566  isDiffusiveFluxBoundary_v[ebNE_kb],
4567  eb_adjoint_sigma,
4568  u_ext,
4569  bc_u_ext,
4570  normal,
4571  sdInfo_v_u_rowptr.data(),
4572  sdInfo_v_u_colind.data(),
4573  mom_vu_diff_ten_ext,
4574  &vel_grad_test_dS[i*nSpace])+
4575  ck.ExteriorElementBoundaryDiffusionAdjoint(isDOFBoundary_v[ebNE_kb],
4576  isDiffusiveFluxBoundary_v[ebNE_kb],
4577  eb_adjoint_sigma,
4578  v_ext,
4579  bc_v_ext,
4580  normal,
4581  sdInfo_v_v_rowptr.data(),
4582  sdInfo_v_v_colind.data(),
4583  mom_vv_diff_ten_ext,
4584  &vel_grad_test_dS[i*nSpace]);//+
4585  /* ck.ExteriorElementBoundaryDiffusionAdjoint(isDOFBoundary_w[ebNE_kb], */
4586  /* isDiffusiveFluxBoundary_v[ebNE_kb], */
4587  /* eb_adjoint_sigma, */
4588  /* w_ext, */
4589  /* bc_w_ext, */
4590  /* normal, */
4591  /* sdInfo_v_w_rowptr, */
4592  /* sdInfo_v_w_colind, */
4593  /* mom_vw_diff_ten_ext, */
4594  /* &vel_grad_test_dS[i*nSpace]); */
4595 
4596  /* elementResidual_w[i] += */
4597  /* (INT_BY_PARTS_PRESSURE==1 ? p_ext*vel_test_dS[i]*normal[2] : 0.) +*/
4598  /* ck.ExteriorElementBoundaryFlux(flux_mom_w_adv_ext,vel_test_dS[i]) + */
4599  /* ck.ExteriorElementBoundaryFlux(flux_mom_wu_diff_ext,vel_test_dS[i])+ */
4600  /* ck.ExteriorElementBoundaryFlux(flux_mom_wv_diff_ext,vel_test_dS[i])+ */
4601  /* ck.ExteriorElementBoundaryFlux(flux_mom_ww_diff_ext,vel_test_dS[i])+ */
4602  /* ck.ExteriorElementBoundaryDiffusionAdjoint(isDOFBoundary_u[ebNE_kb], */
4603  /* isDiffusiveFluxBoundary_w[ebNE_kb], */
4604  /* eb_adjoint_sigma, */
4605  /* u_ext, */
4606  /* bc_u_ext, */
4607  /* normal, */
4608  /* sdInfo_w_u_rowptr, */
4609  /* sdInfo_w_u_colind, */
4610  /* mom_wu_diff_ten_ext, */
4611  /* &vel_grad_test_dS[i*nSpace])+ */
4612  /* ck.ExteriorElementBoundaryDiffusionAdjoint(isDOFBoundary_v[ebNE_kb], */
4613  /* isDiffusiveFluxBoundary_w[ebNE_kb], */
4614  /* eb_adjoint_sigma, */
4615  /* v_ext, */
4616  /* bc_v_ext, */
4617  /* normal, */
4618  /* sdInfo_w_v_rowptr, */
4619  /* sdInfo_w_v_colind, */
4620  /* mom_wv_diff_ten_ext, */
4621  /* &vel_grad_test_dS[i*nSpace])+ */
4622  /* ck.ExteriorElementBoundaryDiffusionAdjoint(isDOFBoundary_w[ebNE_kb], */
4623  /* isDiffusiveFluxBoundary_w[ebNE_kb], */
4624  /* eb_adjoint_sigma, */
4625  /* w_ext, */
4626  /* bc_w_ext, */
4627  /* normal, */
4628  /* sdInfo_w_w_rowptr, */
4629  /* sdInfo_w_w_colind, */
4630  /* mom_ww_diff_ten_ext, */
4631  /* &vel_grad_test_dS[i*nSpace]); */
4632  }//i
4633  }//kb
4634  //
4635  //update the element and global residual storage
4636  //
4637  for (int i=0;i<nDOF_test_element;i++)
4638  {
4639  int eN_i = eN*nDOF_test_element+i;
4640 
4641  /* elementResidual_p_save[eN_i] += elementResidual_p[i]; */
4642  /* mesh_volume_conservation_weak += elementResidual_mesh[i]; */
4643  /* globalResidual[offset_p+stride_p*p_l2g[eN_i]]+=elementResidual_p[i]; */
4644  globalResidual[offset_u+stride_u*vel_l2g[eN_i]]+=elementResidual_u[i];
4645  globalResidual[offset_v+stride_v*vel_l2g[eN_i]]+=elementResidual_v[i];
4646  /* globalResidual[offset_w+stride_w*vel_l2g[eN_i]]+=elementResidual_w[i]; */
4647  }//i
4648  }//ebNE
4649  gf.useExact=useExact;
4650  gf_s.useExact=useExact;
4651  /* std::cout<<"mesh volume conservation = "<<mesh_volume_conservation<<std::endl; */
4652  /* std::cout<<"mesh volume conservation weak = "<<mesh_volume_conservation_weak<<std::endl; */
4653  /* std::cout<<"mesh volume conservation err max= "<<mesh_volume_conservation_err_max<<std::endl; */
4654  /* std::cout<<"mesh volume conservation err max weak = "<<mesh_volume_conservation_err_max_weak<<std::endl; */
4656  {
4657  particle_surfaceArea[0] = cut_cell_boundary_length;
4658  particle_netForces[(0+nParticles)*3 +0] = p_force_x;
4659  particle_netForces[(0+nParticles)*3 +1] = p_force_y;
4660  std::cout<<"===end mesh==="<<std::endl<<std::flush;
4661  }
4662  }
4663 
4665  bool useExact)
4666  {
4667  xt::pyarray<double>& mesh_trial_ref = args.array<double>("mesh_trial_ref");
4668  xt::pyarray<double>& mesh_grad_trial_ref = args.array<double>("mesh_grad_trial_ref");
4669  xt::pyarray<double>& mesh_dof = args.array<double>("mesh_dof");
4670  xt::pyarray<double>& mesh_velocity_dof = args.array<double>("mesh_velocity_dof");
4671  double MOVING_DOMAIN = args.scalar<double>("MOVING_DOMAIN");
4672  double PSTAB = args.scalar<double>("PSTAB");
4673  xt::pyarray<int>& mesh_l2g = args.array<int>("mesh_l2g");
4674  xt::pyarray<double>& x_ref = args.array<double>("x_ref");
4675  xt::pyarray<double>& dV_ref = args.array<double>("dV_ref");
4676  xt::pyarray<double>& p_trial_ref = args.array<double>("p_trial_ref");
4677  xt::pyarray<double>& p_grad_trial_ref = args.array<double>("p_grad_trial_ref");
4678  xt::pyarray<double>& p_test_ref = args.array<double>("p_test_ref");
4679  xt::pyarray<double>& p_grad_test_ref = args.array<double>("p_grad_test_ref");
4680  xt::pyarray<double>& q_p = args.array<double>("q_p");
4681  xt::pyarray<double>& q_grad_p = args.array<double>("q_grad_p");
4682  xt::pyarray<double>& ebqe_p = args.array<double>("ebqe_p");
4683  xt::pyarray<double>& ebqe_grad_p = args.array<double>("ebqe_grad_p");
4684  xt::pyarray<double>& vel_trial_ref = args.array<double>("vel_trial_ref");
4685  xt::pyarray<double>& vel_grad_trial_ref = args.array<double>("vel_grad_trial_ref");
4686  xt::pyarray<double>& vel_hess_trial_ref = args.array<double>("vel_hess_trial_ref");
4687  xt::pyarray<double>& vel_test_ref = args.array<double>("vel_test_ref");
4688  xt::pyarray<double>& vel_grad_test_ref = args.array<double>("vel_grad_test_ref");
4689  xt::pyarray<double>& mesh_trial_trace_ref = args.array<double>("mesh_trial_trace_ref");
4690  xt::pyarray<double>& mesh_grad_trial_trace_ref = args.array<double>("mesh_grad_trial_trace_ref");
4691  xt::pyarray<double>& dS_ref = args.array<double>("dS_ref");
4692  xt::pyarray<double>& p_trial_trace_ref = args.array<double>("p_trial_trace_ref");
4693  xt::pyarray<double>& p_grad_trial_trace_ref = args.array<double>("p_grad_trial_trace_ref");
4694  xt::pyarray<double>& p_test_trace_ref = args.array<double>("p_test_trace_ref");
4695  xt::pyarray<double>& p_grad_test_trace_ref = args.array<double>("p_grad_test_trace_ref");
4696  xt::pyarray<double>& vel_trial_trace_ref = args.array<double>("vel_trial_trace_ref");
4697  xt::pyarray<double>& vel_grad_trial_trace_ref = args.array<double>("vel_grad_trial_trace_ref");
4698  xt::pyarray<double>& vel_test_trace_ref = args.array<double>("vel_test_trace_ref");
4699  xt::pyarray<double>& vel_grad_test_trace_ref = args.array<double>("vel_grad_test_trace_ref");
4700  xt::pyarray<double>& normal_ref = args.array<double>("normal_ref");
4701  xt::pyarray<double>& boundaryJac_ref = args.array<double>("boundaryJac_ref");
4702  double eb_adjoint_sigma = args.scalar<double>("eb_adjoint_sigma");
4703  xt::pyarray<double>& elementDiameter = args.array<double>("elementDiameter");
4704  xt::pyarray<double>& nodeDiametersArray = args.array<double>("nodeDiametersArray");
4705  double hFactor = args.scalar<double>("hFactor");
4706  int nElements_global = args.scalar<int>("nElements_global");
4707  int nElements_owned = args.scalar<int>("nElements_owned");
4708  int nElementBoundaries_global = args.scalar<int>("nElementBoundaries_global");
4709  int nElementBoundaries_owned = args.scalar<int>("nElementBoundaries_owned");
4710  int nNodes_owned = args.scalar<int>("nNodes_owned");
4711  double useRBLES = args.scalar<double>("useRBLES");
4712  double useMetrics = args.scalar<double>("useMetrics");
4713  double alphaBDF = args.scalar<double>("alphaBDF");
4714  double epsFact_rho = args.scalar<double>("epsFact_rho");
4715  double epsFact_mu = args.scalar<double>("epsFact_mu");
4716  double sigma = args.scalar<double>("sigma");
4717  double rho_0 = args.scalar<double>("rho_0");
4718  double nu_0 = args.scalar<double>("nu_0");
4719  double rho_1 = args.scalar<double>("rho_1");
4720  double nu_1 = args.scalar<double>("nu_1");
4721  double smagorinskyConstant = args.scalar<double>("smagorinskyConstant");
4722  int turbulenceClosureModel = args.scalar<int>("turbulenceClosureModel");
4723  double Ct_sge = args.scalar<double>("Ct_sge");
4724  double Cd_sge = args.scalar<double>("Cd_sge");
4725  double C_dg = args.scalar<double>("C_dg");
4726  double C_b = args.scalar<double>("C_b");
4727  const xt::pyarray<double>& eps_solid = args.array<double>("eps_solid");
4728  const xt::pyarray<double>& ebq_global_phi_solid = args.array<double>("ebq_global_phi_solid");
4729  const xt::pyarray<double>& ebq_global_grad_phi_solid = args.array<double>("ebq_global_grad_phi_solid");
4730  const xt::pyarray<double>& ebq_particle_velocity_solid = args.array<double>("ebq_particle_velocity_solid");
4731  xt::pyarray<double>& phi_solid_nodes = args.array<double>("phi_solid_nodes");
4732  const xt::pyarray<double>& phi_solid = args.array<double>("phi_solid");
4733  const xt::pyarray<double>& q_velocity_solid = args.array<double>("q_velocity_solid");
4734  const xt::pyarray<double>& q_velocityStar_solid = args.array<double>("q_velocityStar_solid");
4735  const xt::pyarray<double>& q_vos = args.array<double>("q_vos");
4736  const xt::pyarray<double>& q_dvos_dt = args.array<double>("q_dvos_dt");
4737  const xt::pyarray<double>& q_grad_vos = args.array<double>("q_grad_vos");
4738  const xt::pyarray<double>& q_dragAlpha = args.array<double>("q_dragAlpha");
4739  const xt::pyarray<double>& q_dragBeta = args.array<double>("q_dragBeta");
4740  const xt::pyarray<double>& q_mass_source = args.array<double>("q_mass_source");
4741  const xt::pyarray<double>& q_turb_var_0 = args.array<double>("q_turb_var_0");
4742  const xt::pyarray<double>& q_turb_var_1 = args.array<double>("q_turb_var_1");
4743  const xt::pyarray<double>& q_turb_var_grad_0 = args.array<double>("q_turb_var_grad_0");
4744  xt::pyarray<int>& p_l2g = args.array<int>("p_l2g");
4745  xt::pyarray<int>& vel_l2g = args.array<int>("vel_l2g");
4746  xt::pyarray<double>& p_dof = args.array<double>("p_dof");
4747  xt::pyarray<double>& u_dof = args.array<double>("u_dof");
4748  xt::pyarray<double>& v_dof = args.array<double>("v_dof");
4749  xt::pyarray<double>& w_dof = args.array<double>("w_dof");
4750  xt::pyarray<double>& g = args.array<double>("g");
4751  const double useVF = args.scalar<double>("useVF");
4752  xt::pyarray<double>& vf = args.array<double>("vf");
4753  xt::pyarray<double>& phi = args.array<double>("phi");
4754  xt::pyarray<double>& phi_dof = args.array<double>("phi_dof");
4755  xt::pyarray<double>& normal_phi = args.array<double>("normal_phi");
4756  xt::pyarray<double>& kappa_phi = args.array<double>("kappa_phi");
4757  xt::pyarray<double>& q_mom_u_acc_beta_bdf = args.array<double>("q_mom_u_acc_beta_bdf");
4758  xt::pyarray<double>& q_mom_v_acc_beta_bdf = args.array<double>("q_mom_v_acc_beta_bdf");
4759  xt::pyarray<double>& q_mom_w_acc_beta_bdf = args.array<double>("q_mom_w_acc_beta_bdf");
4760  xt::pyarray<double>& q_dV = args.array<double>("q_dV");
4761  xt::pyarray<double>& q_dV_last = args.array<double>("q_dV_last");
4762  xt::pyarray<double>& q_velocity_sge = args.array<double>("q_velocity_sge");
4763  xt::pyarray<double>& ebqe_velocity_star = args.array<double>("ebqe_velocity_star");
4764  xt::pyarray<double>& q_cfl = args.array<double>("q_cfl");
4765  xt::pyarray<double>& q_numDiff_u_last = args.array<double>("q_numDiff_u_last");
4766  xt::pyarray<double>& q_numDiff_v_last = args.array<double>("q_numDiff_v_last");
4767  xt::pyarray<double>& q_numDiff_w_last = args.array<double>("q_numDiff_w_last");
4768  xt::pyarray<int>& sdInfo_u_u_rowptr = args.array<int>("sdInfo_u_u_rowptr");
4769  xt::pyarray<int>& sdInfo_u_u_colind = args.array<int>("sdInfo_u_u_colind");
4770  xt::pyarray<int>& sdInfo_u_v_rowptr = args.array<int>("sdInfo_u_v_rowptr");
4771  xt::pyarray<int>& sdInfo_u_v_colind = args.array<int>("sdInfo_u_v_colind");
4772  xt::pyarray<int>& sdInfo_u_w_rowptr = args.array<int>("sdInfo_u_w_rowptr");
4773  xt::pyarray<int>& sdInfo_u_w_colind = args.array<int>("sdInfo_u_w_colind");
4774  xt::pyarray<int>& sdInfo_v_v_rowptr = args.array<int>("sdInfo_v_v_rowptr");
4775  xt::pyarray<int>& sdInfo_v_v_colind = args.array<int>("sdInfo_v_v_colind");
4776  xt::pyarray<int>& sdInfo_v_u_rowptr = args.array<int>("sdInfo_v_u_rowptr");
4777  xt::pyarray<int>& sdInfo_v_u_colind = args.array<int>("sdInfo_v_u_colind");
4778  xt::pyarray<int>& sdInfo_v_w_rowptr = args.array<int>("sdInfo_v_w_rowptr");
4779  xt::pyarray<int>& sdInfo_v_w_colind = args.array<int>("sdInfo_v_w_colind");
4780  xt::pyarray<int>& sdInfo_w_w_rowptr = args.array<int>("sdInfo_w_w_rowptr");
4781  xt::pyarray<int>& sdInfo_w_w_colind = args.array<int>("sdInfo_w_w_colind");
4782  xt::pyarray<int>& sdInfo_w_u_rowptr = args.array<int>("sdInfo_w_u_rowptr");
4783  xt::pyarray<int>& sdInfo_w_u_colind = args.array<int>("sdInfo_w_u_colind");
4784  xt::pyarray<int>& sdInfo_w_v_rowptr = args.array<int>("sdInfo_w_v_rowptr");
4785  xt::pyarray<int>& sdInfo_w_v_colind = args.array<int>("sdInfo_w_v_colind");
4786  xt::pyarray<int>& csrRowIndeces_p_p = args.array<int>("csrRowIndeces_p_p");
4787  xt::pyarray<int>& csrColumnOffsets_p_p = args.array<int>("csrColumnOffsets_p_p");
4788  xt::pyarray<int>& csrRowIndeces_p_u = args.array<int>("csrRowIndeces_p_u");
4789  xt::pyarray<int>& csrColumnOffsets_p_u = args.array<int>("csrColumnOffsets_p_u");
4790  xt::pyarray<int>& csrRowIndeces_p_v = args.array<int>("csrRowIndeces_p_v");
4791  xt::pyarray<int>& csrColumnOffsets_p_v = args.array<int>("csrColumnOffsets_p_v");
4792  xt::pyarray<int>& csrRowIndeces_p_w = args.array<int>("csrRowIndeces_p_w");
4793  xt::pyarray<int>& csrColumnOffsets_p_w = args.array<int>("csrColumnOffsets_p_w");
4794  xt::pyarray<int>& csrRowIndeces_u_p = args.array<int>("csrRowIndeces_u_p");
4795  xt::pyarray<int>& csrColumnOffsets_u_p = args.array<int>("csrColumnOffsets_u_p");
4796  xt::pyarray<int>& csrRowIndeces_u_u = args.array<int>("csrRowIndeces_u_u");
4797  xt::pyarray<int>& csrColumnOffsets_u_u = args.array<int>("csrColumnOffsets_u_u");
4798  xt::pyarray<int>& csrRowIndeces_u_v = args.array<int>("csrRowIndeces_u_v");
4799  xt::pyarray<int>& csrColumnOffsets_u_v = args.array<int>("csrColumnOffsets_u_v");
4800  xt::pyarray<int>& csrRowIndeces_u_w = args.array<int>("csrRowIndeces_u_w");
4801  xt::pyarray<int>& csrColumnOffsets_u_w = args.array<int>("csrColumnOffsets_u_w");
4802  xt::pyarray<int>& csrRowIndeces_v_p = args.array<int>("csrRowIndeces_v_p");
4803  xt::pyarray<int>& csrColumnOffsets_v_p = args.array<int>("csrColumnOffsets_v_p");
4804  xt::pyarray<int>& csrRowIndeces_v_u = args.array<int>("csrRowIndeces_v_u");
4805  xt::pyarray<int>& csrColumnOffsets_v_u = args.array<int>("csrColumnOffsets_v_u");
4806  xt::pyarray<int>& csrRowIndeces_v_v = args.array<int>("csrRowIndeces_v_v");
4807  xt::pyarray<int>& csrColumnOffsets_v_v = args.array<int>("csrColumnOffsets_v_v");
4808  xt::pyarray<int>& csrRowIndeces_v_w = args.array<int>("csrRowIndeces_v_w");
4809  xt::pyarray<int>& csrColumnOffsets_v_w = args.array<int>("csrColumnOffsets_v_w");
4810  xt::pyarray<int>& csrRowIndeces_w_p = args.array<int>("csrRowIndeces_w_p");
4811  xt::pyarray<int>& csrColumnOffsets_w_p = args.array<int>("csrColumnOffsets_w_p");
4812  xt::pyarray<int>& csrRowIndeces_w_u = args.array<int>("csrRowIndeces_w_u");
4813  xt::pyarray<int>& csrColumnOffsets_w_u = args.array<int>("csrColumnOffsets_w_u");
4814  xt::pyarray<int>& csrRowIndeces_w_v = args.array<int>("csrRowIndeces_w_v");
4815  xt::pyarray<int>& csrColumnOffsets_w_v = args.array<int>("csrColumnOffsets_w_v");
4816  xt::pyarray<int>& csrRowIndeces_w_w = args.array<int>("csrRowIndeces_w_w");
4817  xt::pyarray<int>& csrColumnOffsets_w_w = args.array<int>("csrColumnOffsets_w_w");
4818  xt::pyarray<double>& globalJacobian = args.array<double>("globalJacobian");
4819  int nExteriorElementBoundaries_global = args.scalar<int>("nExteriorElementBoundaries_global");
4820  xt::pyarray<int>& exteriorElementBoundariesArray = args.array<int>("exteriorElementBoundariesArray");
4821  xt::pyarray<int>& elementBoundariesArray = args.array<int>("elementBoundariesArray");
4822  xt::pyarray<int>& elementBoundaryElementsArray = args.array<int>("elementBoundaryElementsArray");
4823  xt::pyarray<int>& elementBoundaryLocalElementBoundariesArray = args.array<int>("elementBoundaryLocalElementBoundariesArray");
4824  xt::pyarray<double>& ebqe_vf_ext = args.array<double>("ebqe_vf_ext");
4825  xt::pyarray<double>& bc_ebqe_vf_ext = args.array<double>("bc_ebqe_vf_ext");
4826  xt::pyarray<double>& ebqe_phi_ext = args.array<double>("ebqe_phi_ext");
4827  xt::pyarray<double>& bc_ebqe_phi_ext = args.array<double>("bc_ebqe_phi_ext");
4828  xt::pyarray<double>& ebqe_normal_phi_ext = args.array<double>("ebqe_normal_phi_ext");
4829  xt::pyarray<double>& ebqe_kappa_phi_ext = args.array<double>("ebqe_kappa_phi_ext");
4830  const xt::pyarray<double>& ebqe_vos_ext = args.array<double>("ebqe_vos_ext");
4831  const xt::pyarray<double>& ebqe_turb_var_0 = args.array<double>("ebqe_turb_var_0");
4832  const xt::pyarray<double>& ebqe_turb_var_1 = args.array<double>("ebqe_turb_var_1");
4833  xt::pyarray<int>& isDOFBoundary_p = args.array<int>("isDOFBoundary_p");
4834  xt::pyarray<int>& isDOFBoundary_u = args.array<int>("isDOFBoundary_u");
4835  xt::pyarray<int>& isDOFBoundary_v = args.array<int>("isDOFBoundary_v");
4836  xt::pyarray<int>& isDOFBoundary_w = args.array<int>("isDOFBoundary_w");
4837  xt::pyarray<int>& isAdvectiveFluxBoundary_p = args.array<int>("isAdvectiveFluxBoundary_p");
4838  xt::pyarray<int>& isAdvectiveFluxBoundary_u = args.array<int>("isAdvectiveFluxBoundary_u");
4839  xt::pyarray<int>& isAdvectiveFluxBoundary_v = args.array<int>("isAdvectiveFluxBoundary_v");
4840  xt::pyarray<int>& isAdvectiveFluxBoundary_w = args.array<int>("isAdvectiveFluxBoundary_w");
4841  xt::pyarray<int>& isDiffusiveFluxBoundary_u = args.array<int>("isDiffusiveFluxBoundary_u");
4842  xt::pyarray<int>& isDiffusiveFluxBoundary_v = args.array<int>("isDiffusiveFluxBoundary_v");
4843  xt::pyarray<int>& isDiffusiveFluxBoundary_w = args.array<int>("isDiffusiveFluxBoundary_w");
4844  xt::pyarray<double>& ebqe_bc_p_ext = args.array<double>("ebqe_bc_p_ext");
4845  xt::pyarray<double>& ebqe_bc_flux_mass_ext = args.array<double>("ebqe_bc_flux_mass_ext");
4846  xt::pyarray<double>& ebqe_bc_flux_mom_u_adv_ext = args.array<double>("ebqe_bc_flux_mom_u_adv_ext");
4847  xt::pyarray<double>& ebqe_bc_flux_mom_v_adv_ext = args.array<double>("ebqe_bc_flux_mom_v_adv_ext");
4848  xt::pyarray<double>& ebqe_bc_flux_mom_w_adv_ext = args.array<double>("ebqe_bc_flux_mom_w_adv_ext");
4849  xt::pyarray<double>& ebqe_bc_u_ext = args.array<double>("ebqe_bc_u_ext");
4850  xt::pyarray<double>& ebqe_bc_flux_u_diff_ext = args.array<double>("ebqe_bc_flux_u_diff_ext");
4851  xt::pyarray<double>& ebqe_penalty_ext = args.array<double>("ebqe_penalty_ext");
4852  xt::pyarray<double>& ebqe_bc_v_ext = args.array<double>("ebqe_bc_v_ext");
4853  xt::pyarray<double>& ebqe_bc_flux_v_diff_ext = args.array<double>("ebqe_bc_flux_v_diff_ext");
4854  xt::pyarray<double>& ebqe_bc_w_ext = args.array<double>("ebqe_bc_w_ext");
4855  xt::pyarray<double>& ebqe_bc_flux_w_diff_ext = args.array<double>("ebqe_bc_flux_w_diff_ext");
4856  xt::pyarray<int>& csrColumnOffsets_eb_p_p = args.array<int>("csrColumnOffsets_eb_p_p");
4857  xt::pyarray<int>& csrColumnOffsets_eb_p_u = args.array<int>("csrColumnOffsets_eb_p_u");
4858  xt::pyarray<int>& csrColumnOffsets_eb_p_v = args.array<int>("csrColumnOffsets_eb_p_v");
4859  xt::pyarray<int>& csrColumnOffsets_eb_p_w = args.array<int>("csrColumnOffsets_eb_p_w");
4860  xt::pyarray<int>& csrColumnOffsets_eb_u_p = args.array<int>("csrColumnOffsets_eb_u_p");
4861  xt::pyarray<int>& csrColumnOffsets_eb_u_u = args.array<int>("csrColumnOffsets_eb_u_u");
4862  xt::pyarray<int>& csrColumnOffsets_eb_u_v = args.array<int>("csrColumnOffsets_eb_u_v");
4863  xt::pyarray<int>& csrColumnOffsets_eb_u_w = args.array<int>("csrColumnOffsets_eb_u_w");
4864  xt::pyarray<int>& csrColumnOffsets_eb_v_p = args.array<int>("csrColumnOffsets_eb_v_p");
4865  xt::pyarray<int>& csrColumnOffsets_eb_v_u = args.array<int>("csrColumnOffsets_eb_v_u");
4866  xt::pyarray<int>& csrColumnOffsets_eb_v_v = args.array<int>("csrColumnOffsets_eb_v_v");
4867  xt::pyarray<int>& csrColumnOffsets_eb_v_w = args.array<int>("csrColumnOffsets_eb_v_w");
4868  xt::pyarray<int>& csrColumnOffsets_eb_w_p = args.array<int>("csrColumnOffsets_eb_w_p");
4869  xt::pyarray<int>& csrColumnOffsets_eb_w_u = args.array<int>("csrColumnOffsets_eb_w_u");
4870  xt::pyarray<int>& csrColumnOffsets_eb_w_v = args.array<int>("csrColumnOffsets_eb_w_v");
4871  xt::pyarray<int>& csrColumnOffsets_eb_w_w = args.array<int>("csrColumnOffsets_eb_w_w");
4872  xt::pyarray<int>& elementFlags = args.array<int>("elementFlags");
4873  int nParticles = args.scalar<int>("nParticles");
4874  double particle_epsFact = args.scalar<double>("particle_epsFact");
4875  double particle_alpha = args.scalar<double>("particle_alpha");
4876  double particle_beta = args.scalar<double>("particle_beta");
4877  double particle_penalty_constant = args.scalar<double>("particle_penalty_constant");
4878  xt::pyarray<double>& particle_signed_distances = args.array<double>("particle_signed_distances");
4879  xt::pyarray<double>& particle_signed_distance_normals = args.array<double>("particle_signed_distance_normals");
4880  xt::pyarray<double>& particle_velocities = args.array<double>("particle_velocities");
4881  xt::pyarray<double>& particle_centroids = args.array<double>("particle_centroids");
4882  double particle_nitsche = args.scalar<double>("particle_nitsche");
4883  int use_ball_as_particle = args.scalar<int>("use_ball_as_particle");
4884  xt::pyarray<double>& ball_center = args.array<double>("ball_center");
4885  xt::pyarray<double>& ball_radius = args.array<double>("ball_radius");
4886  xt::pyarray<double>& ball_velocity = args.array<double>("ball_velocity");
4887  xt::pyarray<double>& ball_angular_velocity = args.array<double>("ball_angular_velocity");
4888  int USE_SUPG = args.scalar<int>("USE_SUPG");
4889  int KILL_PRESSURE_TERM = args.scalar<int>("KILL_PRESSURE_TERM");
4890  double dt = args.scalar<double>("dt");
4891  int MATERIAL_PARAMETERS_AS_FUNCTION = args.scalar<int>("MATERIAL_PARAMETERS_AS_FUNCTION");
4892  xt::pyarray<double>& density_as_function = args.array<double>("density_as_function");
4893  xt::pyarray<double>& dynamic_viscosity_as_function = args.array<double>("dynamic_viscosity_as_function");
4894  xt::pyarray<double>& ebqe_density_as_function = args.array<double>("ebqe_density_as_function");
4895  xt::pyarray<double>& ebqe_dynamic_viscosity_as_function = args.array<double>("ebqe_dynamic_viscosity_as_function");
4896  int USE_SBM = args.scalar<int>("USE_SBM");
4897  int ARTIFICIAL_VISCOSITY = args.scalar<int>("ARTIFICIAL_VISCOSITY");
4898  xt::pyarray<double>& uStar_dMatrix = args.array<double>("uStar_dMatrix");
4899  xt::pyarray<double>& vStar_dMatrix = args.array<double>("vStar_dMatrix");
4900  xt::pyarray<double>& wStar_dMatrix = args.array<double>("wStar_dMatrix");
4901  int numDOFs_1D = args.scalar<int>("numDOFs_1D");
4902  int offset_u = args.scalar<int>("offset_u");
4903  int offset_v = args.scalar<int>("offset_v");
4904  int offset_w = args.scalar<int>("offset_w");
4905  int stride_u = args.scalar<int>("stride_u");
4906  int stride_v = args.scalar<int>("stride_v");
4907  int stride_w = args.scalar<int>("stride_w");
4908  xt::pyarray<int>& rowptr_1D = args.array<int>("rowptr_1D");
4909  xt::pyarray<int>& colind_1D = args.array<int>("colind_1D");
4910  xt::pyarray<int>& rowptr = args.array<int>("rowptr");
4911  xt::pyarray<int>& colind = args.array<int>("colind");
4912  int INT_BY_PARTS_PRESSURE = args.scalar<int>("INT_BY_PARTS_PRESSURE");
4913  //
4914  //loop over elements to compute volume integrals and load them into the element Jacobians and global Jacobian
4915  //
4916  std::valarray<double> particle_surfaceArea(nParticles), particle_netForces(nParticles*3*3), particle_netMoments(nParticles*3);
4917  const int nQuadraturePoints_global(nElements_global*nQuadraturePoints_element);
4918  for(int eN=0;eN<nElements_global;eN++)
4919  {
4920  register double eps_rho,eps_mu;
4921  double element_active=1.0;//value 1 is because it is ibm by default
4922 
4923  register double elementJacobian_p_p[nDOF_test_element][nDOF_trial_element],
4924  elementJacobian_p_u[nDOF_test_element][nDOF_trial_element],
4925  elementJacobian_p_v[nDOF_test_element][nDOF_trial_element],
4926  elementJacobian_p_w[nDOF_test_element][nDOF_trial_element],
4927  elementJacobian_u_p[nDOF_test_element][nDOF_trial_element],
4928  elementJacobian_u_u[nDOF_test_element][nDOF_trial_element],
4929  elementJacobian_u_v[nDOF_test_element][nDOF_trial_element],
4930  elementJacobian_u_w[nDOF_test_element][nDOF_trial_element],
4931  elementJacobian_v_p[nDOF_test_element][nDOF_trial_element],
4932  elementJacobian_v_u[nDOF_test_element][nDOF_trial_element],
4933  elementJacobian_v_v[nDOF_test_element][nDOF_trial_element],
4934  elementJacobian_v_w[nDOF_test_element][nDOF_trial_element],
4935  elementJacobian_w_p[nDOF_test_element][nDOF_trial_element],
4936  elementJacobian_w_u[nDOF_test_element][nDOF_trial_element],
4937  elementJacobian_w_v[nDOF_test_element][nDOF_trial_element],
4938  elementJacobian_w_w[nDOF_test_element][nDOF_trial_element];
4939  for (int i=0;i<nDOF_test_element;i++)
4940  for (int j=0;j<nDOF_trial_element;j++)
4941  {
4942  elementJacobian_p_p[i][j]=0.0;
4943  elementJacobian_p_u[i][j]=0.0;
4944  elementJacobian_p_v[i][j]=0.0;
4945  elementJacobian_p_w[i][j]=0.0;
4946  elementJacobian_u_p[i][j]=0.0;
4947  elementJacobian_u_u[i][j]=0.0;
4948  elementJacobian_u_v[i][j]=0.0;
4949  elementJacobian_u_w[i][j]=0.0;
4950  elementJacobian_v_p[i][j]=0.0;
4951  elementJacobian_v_u[i][j]=0.0;
4952  elementJacobian_v_v[i][j]=0.0;
4953  elementJacobian_v_w[i][j]=0.0;
4954  elementJacobian_w_p[i][j]=0.0;
4955  elementJacobian_w_u[i][j]=0.0;
4956  elementJacobian_w_v[i][j]=0.0;
4957  elementJacobian_w_w[i][j]=0.0;
4958  }
4959  //
4960  //detect cut cells
4961  //
4962  //if(0)
4963  if(USE_SBM>0)
4964  {
4965  //
4966  //detect cut cells
4967  //
4968  double _distance[nDOF_mesh_trial_element]={0.0};
4969  int pos_counter=0;
4970  for (int I=0;I<nDOF_mesh_trial_element;I++)
4971  {
4972  if(use_ball_as_particle==1)
4973  {
4974  get_distance_to_ball(nParticles, ball_center.data(), ball_radius.data(),
4975  mesh_dof[3*mesh_l2g[eN*nDOF_mesh_trial_element+I]+0],
4976  mesh_dof[3*mesh_l2g[eN*nDOF_mesh_trial_element+I]+1],
4977  mesh_dof[3*mesh_l2g[eN*nDOF_mesh_trial_element+I]+2],
4978  _distance[I]);
4979  }
4980  else
4981  {
4982  _distance[I] = phi_solid_nodes[mesh_l2g[eN*nDOF_mesh_trial_element+I]];
4983  }
4984  if ( _distance[I] >= 0)
4985  pos_counter++;
4986  }
4987  if (pos_counter == 2)
4988  {
4989  element_active=0.0;
4990  //std::cout<<"Identified cut cell"<<std::endl;
4991  int opp_node=-1;
4992  for (int I=0;I<nDOF_mesh_trial_element;I++)
4993  {
4994  if (_distance[I] < 0)
4995  opp_node = I;
4996  }
4997  assert(opp_node >=0);
4998  assert(opp_node <nDOF_mesh_trial_element);
4999  }
5000  else if (pos_counter == 3)
5001  {
5002  element_active=1.0;
5003  }
5004  else
5005  {
5006  element_active=0.0;
5007  }
5008  }
5009  if(use_ball_as_particle==1)
5010  {
5011  for (int I=0;I<nDOF_mesh_trial_element;I++)
5012  get_distance_to_ball(nParticles, ball_center.data(), ball_radius.data(),
5013  mesh_dof[3*mesh_l2g[eN*nDOF_mesh_trial_element+I]+0],
5014  mesh_dof[3*mesh_l2g[eN*nDOF_mesh_trial_element+I]+1],
5015  mesh_dof[3*mesh_l2g[eN*nDOF_mesh_trial_element+I]+2],
5016  phi_solid_nodes[mesh_l2g[eN*nDOF_mesh_trial_element+I]]);
5017  }
5018  double element_phi[nDOF_mesh_trial_element], element_phi_s[nDOF_mesh_trial_element];
5019  for (int j=0;j<nDOF_mesh_trial_element;j++)
5020  {
5021  register int eN_j = eN*nDOF_mesh_trial_element+j;
5022  element_phi[j] = phi_dof[p_l2g[eN_j]];
5023  element_phi_s[j] = phi_solid_nodes[p_l2g[eN_j]];
5024  }
5025  double element_nodes[nDOF_mesh_trial_element*3];
5026  for (int i=0;i<nDOF_mesh_trial_element;i++)
5027  {
5028  register int eN_i=eN*nDOF_mesh_trial_element+i;
5029  for(int I=0;I<3;I++)
5030  element_nodes[i*3 + I] = mesh_dof[mesh_l2g[eN_i]*3 + I];
5031  }//i
5032  gf_s.calculate(element_phi_s, element_nodes, x_ref.data(), false);
5033  gf.calculate(element_phi, element_nodes, x_ref.data(), false);
5034  for (int k=0;k<nQuadraturePoints_element;k++)
5035  {
5036  gf.set_quad(k);
5037  gf_s.set_quad(k);
5038  int eN_k = eN*nQuadraturePoints_element+k, //index to a scalar at a quadrature point
5039  eN_k_nSpace = eN_k*nSpace,
5040  eN_k_3d = eN_k*3,
5041  eN_nDOF_trial_element = eN*nDOF_trial_element; //index to a vector at a quadrature point
5042 
5043  //declare local storage
5044  register double p=0.0,u=0.0,v=0.0,w=0.0,
5045  grad_p[nSpace],grad_u[nSpace],grad_v[nSpace],grad_w[nSpace],
5046  hess_u[nSpace2],hess_v[nSpace2],
5047  mom_u_acc=0.0,
5048  dmom_u_acc_u=0.0,
5049  mom_v_acc=0.0,
5050  dmom_v_acc_v=0.0,
5051  mom_w_acc=0.0,
5052  dmom_w_acc_w=0.0,
5053  mass_adv[nSpace],
5054  dmass_adv_u[nSpace],
5055  dmass_adv_v[nSpace],
5056  dmass_adv_w[nSpace],
5057  mom_u_adv[nSpace],
5058  dmom_u_adv_u[nSpace],
5059  dmom_u_adv_v[nSpace],
5060  dmom_u_adv_w[nSpace],
5061  mom_v_adv[nSpace],
5062  dmom_v_adv_u[nSpace],
5063  dmom_v_adv_v[nSpace],
5064  dmom_v_adv_w[nSpace],
5065  mom_w_adv[nSpace],
5066  dmom_w_adv_u[nSpace],
5067  dmom_w_adv_v[nSpace],
5068  dmom_w_adv_w[nSpace],
5069  mom_uu_diff_ten[nSpace],
5070  mom_vv_diff_ten[nSpace],
5071  mom_ww_diff_ten[nSpace],
5072  mom_uv_diff_ten[1],
5073  mom_uw_diff_ten[1],
5074  mom_vu_diff_ten[1],
5075  mom_vw_diff_ten[1],
5076  mom_wu_diff_ten[1],
5077  mom_wv_diff_ten[1],
5078  mom_u_source=0.0,
5079  mom_v_source=0.0,
5080  mom_w_source=0.0,
5081  mom_u_ham=0.0,
5082  dmom_u_ham_grad_p[nSpace],
5083  dmom_u_ham_grad_u[nSpace],
5084  mom_v_ham=0.0,
5085  dmom_v_ham_grad_p[nSpace],
5086  dmom_v_ham_grad_v[nSpace],
5087  mom_w_ham=0.0,
5088  dmom_w_ham_grad_p[nSpace],
5089  dmom_w_ham_grad_w[nSpace],
5090  mom_u_acc_t=0.0,
5091  dmom_u_acc_u_t=0.0,
5092  mom_v_acc_t=0.0,
5093  dmom_v_acc_v_t=0.0,
5094  mom_w_acc_t=0.0,
5095  dmom_w_acc_w_t=0.0,
5096  pdeResidual_p=0.0,
5097  pdeResidual_u=0.0,
5098  pdeResidual_v=0.0,
5099  pdeResidual_w=0.0,
5100  dpdeResidual_p_u[nDOF_trial_element],dpdeResidual_p_v[nDOF_trial_element],dpdeResidual_p_w[nDOF_trial_element],
5101  dpdeResidual_u_p[nDOF_trial_element],dpdeResidual_u_u[nDOF_trial_element],
5102  dpdeResidual_v_p[nDOF_trial_element],dpdeResidual_v_v[nDOF_trial_element],
5103  dpdeResidual_w_p[nDOF_trial_element],dpdeResidual_w_w[nDOF_trial_element],
5104  Lstar_u_p[nDOF_test_element],
5105  Lstar_v_p[nDOF_test_element],
5106  Lstar_w_p[nDOF_test_element],
5107  Lstar_u_u[nDOF_test_element],
5108  Lstar_v_v[nDOF_test_element],
5109  Lstar_w_w[nDOF_test_element],
5110  Lstar_p_u[nDOF_test_element],
5111  Lstar_p_v[nDOF_test_element],
5112  Lstar_p_w[nDOF_test_element],
5113  subgridError_p=0.0,
5114  subgridError_u=0.0,
5115  subgridError_v=0.0,
5116  subgridError_w=0.0,
5117  dsubgridError_p_u[nDOF_trial_element],
5118  dsubgridError_p_v[nDOF_trial_element],
5119  dsubgridError_p_w[nDOF_trial_element],
5120  dsubgridError_u_p[nDOF_trial_element],
5121  dsubgridError_u_u[nDOF_trial_element],
5122  dsubgridError_v_p[nDOF_trial_element],
5123  dsubgridError_v_v[nDOF_trial_element],
5124  dsubgridError_w_p[nDOF_trial_element],
5125  dsubgridError_w_w[nDOF_trial_element],
5126  tau_p=0.0,tau_p0=0.0,tau_p1=0.0,
5127  tau_v=0.0,tau_v0=0.0,tau_v1=0.0,
5128  jac[nSpace*nSpace],
5129  jacDet,
5130  jacInv[nSpace*nSpace],
5131  p_grad_trial[nDOF_trial_element*nSpace],vel_grad_trial[nDOF_trial_element*nSpace],
5132  vel_hess_trial[nDOF_trial_element*nSpace2],
5133  dV,
5134  p_test_dV[nDOF_test_element],vel_test_dV[nDOF_test_element],
5135  p_grad_test_dV[nDOF_test_element*nSpace],vel_grad_test_dV[nDOF_test_element*nSpace],
5136  x,y,z,xt,yt,zt,
5137  //VRANS
5138  porosity,
5139  //meanGrainSize,
5140  dmom_u_source[nSpace],
5141  dmom_v_source[nSpace],
5142  dmom_w_source[nSpace],
5143  mass_source,
5144  //
5145  G[nSpace*nSpace],G_dd_G,tr_G,h_phi, dmom_adv_star[nSpace], dmom_adv_sge[nSpace];
5146  //get jacobian, etc for mapping reference element
5147  ck.calculateMapping_element(eN,
5148  k,
5149  mesh_dof.data(),
5150  mesh_l2g.data(),
5151  mesh_trial_ref.data(),
5152  mesh_grad_trial_ref.data(),
5153  jac,
5154  jacDet,
5155  jacInv,
5156  x,y,z);
5157  ck.calculateH_element(eN,
5158  k,
5159  nodeDiametersArray.data(),
5160  mesh_l2g.data(),
5161  mesh_trial_ref.data(),
5162  h_phi);
5163  ck.calculateMappingVelocity_element(eN,
5164  k,
5165  mesh_velocity_dof.data(),
5166  mesh_l2g.data(),
5167  mesh_trial_ref.data(),
5168  xt,yt,zt);
5169  //xt=0.0;yt=0.0;zt=0.0;
5170  //std::cout<<"xt "<<xt<<'\t'<<yt<<'\t'<<zt<<std::endl;
5171  //get the physical integration weight
5172  dV = fabs(jacDet)*dV_ref[k];
5173  ck.calculateG(jacInv,G,G_dd_G,tr_G);
5174  //ck.calculateGScale(G,&normal_phi[eN_k_nSpace],h_phi);
5175 
5176  eps_rho = epsFact_rho*(useMetrics*h_phi+(1.0-useMetrics)*elementDiameter[eN]);
5177  eps_mu = epsFact_mu *(useMetrics*h_phi+(1.0-useMetrics)*elementDiameter[eN]);
5178  const double particle_eps = particle_epsFact*(useMetrics*h_phi+(1.0-useMetrics)*elementDiameter[eN]);
5179 
5180  //get the trial function gradients
5181  /* ck.gradTrialFromRef(&p_grad_trial_ref[k*nDOF_trial_element*nSpace],jacInv,p_grad_trial); */
5182  ck.gradTrialFromRef(&vel_grad_trial_ref[k*nDOF_trial_element*nSpace],jacInv,vel_grad_trial);
5183  ck.hessTrialFromRef(&vel_hess_trial_ref[k*nDOF_trial_element*nSpace2],jacInv,vel_hess_trial);
5184  //get the solution
5185  /* ck.valFromDOF(p_dof,&p_l2g[eN_nDOF_trial_element],&p_trial_ref[k*nDOF_trial_element],p); */
5186  p = q_p[eN_k];
5187  ck.valFromDOF(u_dof.data(),&vel_l2g[eN_nDOF_trial_element],&vel_trial_ref[k*nDOF_trial_element],u);
5188  ck.valFromDOF(v_dof.data(),&vel_l2g[eN_nDOF_trial_element],&vel_trial_ref[k*nDOF_trial_element],v);
5189  /* ck.valFromDOF(w_dof,&vel_l2g[eN_nDOF_trial_element],&vel_trial_ref[k*nDOF_trial_element],w); */
5190  //get the solution gradients
5191  /* ck.gradFromDOF(p_dof,&p_l2g[eN_nDOF_trial_element],p_grad_trial,grad_p); */
5192  for (int I=0;I<nSpace;I++)
5193  grad_p[I] = q_grad_p[eN_k_nSpace+I];
5194  ck.gradFromDOF(u_dof.data(),&vel_l2g[eN_nDOF_trial_element],vel_grad_trial,grad_u);
5195  ck.gradFromDOF(v_dof.data(),&vel_l2g[eN_nDOF_trial_element],vel_grad_trial,grad_v);
5196  ck.hessFromDOF(u_dof.data(),&vel_l2g[eN_nDOF_trial_element],vel_hess_trial,hess_u);
5197  ck.hessFromDOF(v_dof.data(),&vel_l2g[eN_nDOF_trial_element],vel_hess_trial,hess_v);
5198  /* ck.gradFromDOF(w_dof,&vel_l2g[eN_nDOF_trial_element],vel_grad_trial,grad_w); */
5199  //precalculate test function products with integration weights
5200  for (int j=0;j<nDOF_trial_element;j++)
5201  {
5202  /* p_test_dV[j] = p_test_ref[k*nDOF_trial_element+j]*dV; */
5203  vel_test_dV[j] = vel_test_ref[k*nDOF_trial_element+j]*dV;
5204  for (int I=0;I<nSpace;I++)
5205  {
5206  /* p_grad_test_dV[j*nSpace+I] = p_grad_trial[j*nSpace+I]*dV;//cek warning won't work for Petrov-Galerkin */
5207  vel_grad_test_dV[j*nSpace+I] = vel_grad_trial[j*nSpace+I]*dV;//cek warning won't work for Petrov-Galerkin}
5208  }
5209  }
5210  //cek hack
5211  double div_mesh_velocity=0.0;
5212  int NDOF_MESH_TRIAL_ELEMENT=3;
5213  for (int j=0;j<NDOF_MESH_TRIAL_ELEMENT;j++)
5214  {
5215  int eN_j=eN*NDOF_MESH_TRIAL_ELEMENT+j;
5216  div_mesh_velocity +=
5217  mesh_velocity_dof[mesh_l2g[eN_j]*3+0]*vel_grad_trial[j*2+0] +
5218  mesh_velocity_dof[mesh_l2g[eN_j]*3+1]*vel_grad_trial[j*2+1];
5219  }
5220  div_mesh_velocity = DM3*div_mesh_velocity + (1.0-DM3)*alphaBDF*(dV-q_dV_last[eN_k])/dV;
5221  //
5222  //VRANS
5223  porosity = 1.0 - q_vos[eN_k];
5224  //
5225  //
5226  //calculate pde coefficients and derivatives at quadrature points
5227  //
5228  double distance_to_omega_solid = phi_solid[eN_k];//computed in getResidual
5229  double eddy_viscosity(0.),rhoSave,nuSave;//not really interested in saving eddy_viscosity in jacobian
5230  evaluateCoefficients(eps_rho,
5231  eps_mu,
5232  particle_eps,
5233  sigma,
5234  rho_0,
5235  nu_0,
5236  rho_1,
5237  nu_1,
5238  elementDiameter[eN],
5239  smagorinskyConstant,
5240  turbulenceClosureModel,
5241  g.data(),
5242  useVF,
5243  vf[eN_k],
5244  phi[eN_k],
5245  &normal_phi[eN_k_nSpace],
5246  distance_to_omega_solid,
5247  kappa_phi[eN_k],
5248  //VRANS
5249  porosity,
5250  //
5251  p,
5252  grad_p,
5253  grad_u,
5254  grad_v,
5255  grad_w,
5256  u,
5257  v,
5258  w,
5259  q_velocity_sge[eN_k_nSpace+0],
5260  q_velocity_sge[eN_k_nSpace+1],
5261  q_velocity_sge[eN_k_nSpace+1],//hack, shouldn't be used
5262  eddy_viscosity,
5263  mom_u_acc,
5264  dmom_u_acc_u,
5265  mom_v_acc,
5266  dmom_v_acc_v,
5267  mom_w_acc,
5268  dmom_w_acc_w,
5269  mass_adv,
5270  dmass_adv_u,
5271  dmass_adv_v,
5272  dmass_adv_w,
5273  mom_u_adv,
5274  dmom_u_adv_u,
5275  dmom_u_adv_v,
5276  dmom_u_adv_w,
5277  mom_v_adv,
5278  dmom_v_adv_u,
5279  dmom_v_adv_v,
5280  dmom_v_adv_w,
5281  mom_w_adv,
5282  dmom_w_adv_u,
5283  dmom_w_adv_v,
5284  dmom_w_adv_w,
5285  mom_uu_diff_ten,
5286  mom_vv_diff_ten,
5287  mom_ww_diff_ten,
5288  mom_uv_diff_ten,
5289  mom_uw_diff_ten,
5290  mom_vu_diff_ten,
5291  mom_vw_diff_ten,
5292  mom_wu_diff_ten,
5293  mom_wv_diff_ten,
5294  mom_u_source,
5295  mom_v_source,
5296  mom_w_source,
5297  mom_u_ham,
5298  dmom_u_ham_grad_p,
5299  dmom_u_ham_grad_u,
5300  mom_v_ham,
5301  dmom_v_ham_grad_p,
5302  dmom_v_ham_grad_v,
5303  mom_w_ham,
5304  dmom_w_ham_grad_p,
5305  dmom_w_ham_grad_w,
5306  rhoSave,
5307  nuSave,
5308  KILL_PRESSURE_TERM,
5309  0,
5310  0., // mql: the force term doesn't play a role in the Jacobian
5311  0.,
5312  0.,
5313  MATERIAL_PARAMETERS_AS_FUNCTION,
5314  density_as_function[eN_k],
5315  dynamic_viscosity_as_function[eN_k],
5316  USE_SBM,
5317  x,y,z,
5318  use_ball_as_particle,
5319  ball_center.data(),
5320  ball_radius.data(),
5321  ball_velocity.data(),
5322  ball_angular_velocity.data(),
5323  INT_BY_PARTS_PRESSURE);
5324  //VRANS
5325  mass_source = q_mass_source[eN_k];
5326  for (int I=0;I<nSpace;I++)
5327  {
5328  dmom_u_source[I] = 0.0;
5329  dmom_v_source[I] = 0.0;
5330  dmom_w_source[I] = 0.0;
5331  }
5332  updateDarcyForchheimerTerms_Ergun(/* linearDragFactor, */
5333  /* nonlinearDragFactor, */
5334  /* porosity, */
5335  /* meanGrainSize, */
5336  q_dragAlpha[eN_k],
5337  q_dragBeta[eN_k],
5338  eps_rho,
5339  eps_mu,
5340  rho_0,
5341  nu_0,
5342  rho_1,
5343  nu_1,
5344  eddy_viscosity,
5345  useVF,
5346  vf[eN_k],
5347  phi[eN_k],
5348  u,
5349  v,
5350  w,
5351  q_velocity_sge[eN_k_nSpace+0],
5352  q_velocity_sge[eN_k_nSpace+1],
5353  q_velocity_sge[eN_k_nSpace+1],//hack, shouldn't be used
5354  eps_solid[elementFlags[eN]],
5355  porosity,
5356  q_velocity_solid[eN_k_nSpace+0],
5357  q_velocity_solid[eN_k_nSpace+1],
5358  q_velocity_solid[eN_k_nSpace+1],//cek hack, should not be used
5359  q_velocityStar_solid[eN_k_nSpace+0],
5360  q_velocityStar_solid[eN_k_nSpace+1],
5361  q_velocityStar_solid[eN_k_nSpace+1],//cek hack, should not be used
5362  mom_u_source,
5363  mom_v_source,
5364  mom_w_source,
5365  dmom_u_source,
5366  dmom_v_source,
5367  dmom_w_source,
5368  q_grad_vos[eN_k_nSpace+0],
5369  q_grad_vos[eN_k_nSpace+1],
5370  q_grad_vos[eN_k_nSpace+1]);//cek hack, should not be used
5371 
5372  double C_particles=0.0;
5373  if(nParticles > 0 && USE_SBM==0)
5374  updateSolidParticleTerms(eN < nElements_owned,
5375  particle_nitsche,
5376  dV,
5377  nParticles,
5378  nQuadraturePoints_global,
5379  &particle_signed_distances[eN_k],
5380  &particle_signed_distance_normals[eN_k_3d],
5381  &particle_velocities[eN_k_3d],
5382  particle_centroids.data(),
5383  use_ball_as_particle,
5384  ball_center.data(),
5385  ball_radius.data(),
5386  ball_velocity.data(),
5387  ball_angular_velocity.data(),
5388  porosity,
5389  particle_penalty_constant/h_phi,
5390  particle_alpha/h_phi,
5391  particle_beta/h_phi,
5392  eps_rho,
5393  eps_mu,
5394  rho_0,
5395  nu_0,
5396  rho_1,
5397  nu_1,
5398  useVF,
5399  vf[eN_k],
5400  phi[eN_k],
5401  x,
5402  y,
5403  z,
5404  p,
5405  u,
5406  v,
5407  w,
5408  q_velocity_sge[eN_k_nSpace+0],
5409  q_velocity_sge[eN_k_nSpace+1],
5410  q_velocity_sge[eN_k_nSpace+1],
5411  particle_eps,
5412  grad_u,
5413  grad_v,
5414  grad_w,
5415  mom_u_source,
5416  mom_v_source,
5417  mom_w_source,
5418  dmom_u_source,
5419  dmom_v_source,
5420  dmom_w_source,
5421  mom_u_adv,
5422  mom_v_adv,
5423  mom_w_adv,
5424  dmom_u_adv_u,
5425  dmom_v_adv_v,
5426  dmom_w_adv_w,
5427  mom_u_ham,
5428  dmom_u_ham_grad_u,
5429  mom_v_ham,
5430  dmom_v_ham_grad_v,
5431  mom_w_ham,
5432  dmom_w_ham_grad_w,
5433  &particle_netForces[0],
5434  &particle_netMoments[0],
5435  &particle_surfaceArea[0]);
5436  //Turbulence closure model
5437  if (turbulenceClosureModel >= 3)
5438  {
5439  const double c_mu = 0.09;//mwf hack
5440  updateTurbulenceClosure(turbulenceClosureModel,
5441  eps_rho,
5442  eps_mu,
5443  rho_0,
5444  nu_0,
5445  rho_1,
5446  nu_1,
5447  useVF,
5448  vf[eN_k],
5449  phi[eN_k],
5450  porosity,
5451  c_mu, //mwf hack
5452  q_turb_var_0[eN_k],
5453  q_turb_var_1[eN_k],
5454  &q_turb_var_grad_0[eN_k_nSpace],
5455  eddy_viscosity,
5456  mom_uu_diff_ten,
5457  mom_vv_diff_ten,
5458  mom_ww_diff_ten,
5459  mom_uv_diff_ten,
5460  mom_uw_diff_ten,
5461  mom_vu_diff_ten,
5462  mom_vw_diff_ten,
5463  mom_wu_diff_ten,
5464  mom_wv_diff_ten,
5465  mom_u_source,
5466  mom_v_source,
5467  mom_w_source);
5468 
5469  }
5470  //
5471  //
5472  //moving mesh
5473  //
5474  mom_u_adv[0] -= MOVING_DOMAIN*dmom_u_acc_u*mom_u_acc*xt; // multiply by rho*porosity. mql. CHECK.
5475  mom_u_adv[1] -= MOVING_DOMAIN*dmom_u_acc_u*mom_u_acc*yt;
5476  /* mom_u_adv[2] -= MOVING_DOMAIN*dmom_u_acc_u*mom_u_acc*zt; */
5477  dmom_u_adv_u[0] -= MOVING_DOMAIN*dmom_u_acc_u*xt;
5478  dmom_u_adv_u[1] -= MOVING_DOMAIN*dmom_u_acc_u*yt;
5479  /* dmom_u_adv_u[2] -= MOVING_DOMAIN*dmom_u_acc_u*zt; */
5480 
5481  mom_v_adv[0] -= MOVING_DOMAIN*dmom_v_acc_v*mom_v_acc*xt;
5482  mom_v_adv[1] -= MOVING_DOMAIN*dmom_v_acc_v*mom_v_acc*yt;
5483  /* mom_v_adv[2] -= MOVING_DOMAIN*dmom_v_acc_v*mom_v_acc*zt; */
5484  dmom_v_adv_v[0] -= MOVING_DOMAIN*dmom_v_acc_v*xt;
5485  dmom_v_adv_v[1] -= MOVING_DOMAIN*dmom_v_acc_v*yt;
5486  /* dmom_v_adv_v[2] -= MOVING_DOMAIN*dmom_v_acc_v*zt; */
5487 
5488  /* mom_w_adv[0] -= MOVING_DOMAIN*dmom_w_acc_w*mom_w_acc*xt; */
5489  /* mom_w_adv[1] -= MOVING_DOMAIN*dmom_w_acc_w*mom_w_acc*yt; */
5490  /* mom_w_adv[2] -= MOVING_DOMAIN*dmom_w_acc_w*mom_w_acc*zt; */
5491  /* dmom_w_adv_w[0] -= MOVING_DOMAIN*dmom_w_acc_w*xt; */
5492  /* dmom_w_adv_w[1] -= MOVING_DOMAIN*dmom_w_acc_w*yt; */
5493  /* dmom_w_adv_w[2] -= MOVING_DOMAIN*dmom_w_acc_w*zt; */
5494  //
5495  //calculate time derivatives
5496  //
5497  ck.bdf(alphaBDF,
5498  q_mom_u_acc_beta_bdf[eN_k]*q_dV_last[eN_k]/dV,
5499  mom_u_acc,
5500  dmom_u_acc_u,
5501  mom_u_acc_t,
5502  dmom_u_acc_u_t);
5503  ck.bdf(alphaBDF,
5504  q_mom_v_acc_beta_bdf[eN_k]*q_dV_last[eN_k]/dV,
5505  mom_v_acc,
5506  dmom_v_acc_v,
5507  mom_v_acc_t,
5508  dmom_v_acc_v_t);
5509  /* ck.bdf(alphaBDF, */
5510  /* q_mom_w_acc_beta_bdf[eN_k]*q_dV_last[eN_k]/dV, */
5511  /* mom_w_acc, */
5512  /* dmom_w_acc_w, */
5513  /* mom_w_acc_t, */
5514  /* dmom_w_acc_w_t); */
5515  //
5516  //calculate subgrid error contribution to the Jacobian (strong residual, adjoint, jacobian of strong residual)
5517 
5518  mom_u_acc_t *= dmom_u_acc_u; //multiply by porosity*rho. mql. CHECK.
5519  mom_v_acc_t *= dmom_v_acc_v;
5520 
5521  //
5522  dmom_adv_sge[0] = dmom_u_acc_u*(q_velocity_sge[eN_k_nSpace+0] - MOVING_DOMAIN*xt);
5523  dmom_adv_sge[1] = dmom_u_acc_u*(q_velocity_sge[eN_k_nSpace+1] - MOVING_DOMAIN*yt);
5524  /* dmom_adv_sge[2] = dmom_u_acc_u*(q_velocity_sge[eN_k_nSpace+2] - MOVING_DOMAIN*zt); */
5525  //
5526  //calculate strong residual
5527  //
5528  pdeResidual_p =
5529  ck.Mass_strong(-q_dvos_dt[eN_k]) + // mql. CHECK.
5530  ck.Advection_strong(dmass_adv_u,grad_u) +
5531  ck.Advection_strong(dmass_adv_v,grad_v) +
5532  /* ck.Advection_strong(dmass_adv_w,grad_w) + */
5533  DM2*MOVING_DOMAIN*ck.Reaction_strong(alphaBDF*(dV-q_dV_last[eN_k])/dV - div_mesh_velocity) +
5534  //VRANS
5535  ck.Reaction_strong(mass_source);
5536  //
5537 
5538  pdeResidual_u =
5539  ck.Mass_strong(mom_u_acc_t) +
5540  ck.Advection_strong(dmom_adv_sge,grad_u) +
5541  ck.Hamiltonian_strong(dmom_u_ham_grad_p,grad_p) +
5542  ck.Reaction_strong(mom_u_source) -
5543  ck.Reaction_strong(u*div_mesh_velocity);
5544 
5545  pdeResidual_v =
5546  ck.Mass_strong(mom_v_acc_t) +
5547  ck.Advection_strong(dmom_adv_sge,grad_v) +
5548  ck.Hamiltonian_strong(dmom_v_ham_grad_p,grad_p) +
5549  ck.Reaction_strong(mom_v_source) -
5550  ck.Reaction_strong(v*div_mesh_velocity);
5551 
5552  /* pdeResidual_w =
5553  ck.Mass_strong(mom_w_acc_t) + */
5554  /* ck.Advection_strong(dmom_adv_sge,grad_w) + */
5555  /* ck.Hamiltonian_strong(dmom_w_ham_grad_p,grad_p) + */
5556  /* ck.Reaction_strong(mom_w_source) - */
5557  /* ck.Reaction_strong(w*div_mesh_velocity); */
5558 
5559  //calculate the Jacobian of strong residual
5560  for (int j=0;j<nDOF_trial_element;j++)
5561  {
5562  register int j_nSpace = j*nSpace;
5563  dpdeResidual_p_u[j]=ck.AdvectionJacobian_strong(dmass_adv_u,&vel_grad_trial[j_nSpace]);
5564  dpdeResidual_p_v[j]=ck.AdvectionJacobian_strong(dmass_adv_v,&vel_grad_trial[j_nSpace]);
5565  /* dpdeResidual_p_w[j]=ck.AdvectionJacobian_strong(dmass_adv_w,&vel_grad_trial[j_nSpace]); */
5566 
5567  dpdeResidual_u_p[j]=ck.HamiltonianJacobian_strong(dmom_u_ham_grad_p,&p_grad_trial[j_nSpace]);
5568  dpdeResidual_u_u[j]=ck.MassJacobian_strong(dmom_u_acc_u_t,vel_trial_ref[k*nDOF_trial_element+j]) +
5569  ck.AdvectionJacobian_strong(dmom_adv_sge,&vel_grad_trial[j_nSpace]) -
5570  ck.ReactionJacobian_strong(div_mesh_velocity,vel_trial_ref[k*nDOF_trial_element+j]);
5571 
5572  dpdeResidual_v_p[j]=ck.HamiltonianJacobian_strong(dmom_v_ham_grad_p,&p_grad_trial[j_nSpace]);
5573  dpdeResidual_v_v[j]=ck.MassJacobian_strong(dmom_v_acc_v_t,vel_trial_ref[k*nDOF_trial_element+j]) +
5574  ck.AdvectionJacobian_strong(dmom_adv_sge,&vel_grad_trial[j_nSpace]) -
5575  ck.ReactionJacobian_strong(div_mesh_velocity,vel_trial_ref[k*nDOF_trial_element+j]);
5576 
5577  /* dpdeResidual_w_p[j]=ck.HamiltonianJacobian_strong(dmom_w_ham_grad_p,&p_grad_trial[j_nSpace]); */
5578  /* dpdeResidual_w_w[j]=ck.MassJacobian_strong(dmom_w_acc_w_t,vel_trial_ref[k*nDOF_trial_element+j]) + */
5579  /* ck.AdvectionJacobian_strong(dmom_adv_sge,&vel_grad_trial[j_nSpace]) -
5580  ck.ReactionJacobian_strong(div_mesh_velocity,vel_trial_ref[k*nDOF_trial_element+j]); */
5581 
5582  //VRANS account for drag terms, diagonal only here ... decide if need off diagonal terms too
5583  dpdeResidual_u_u[j]+= ck.ReactionJacobian_strong(dmom_u_source[0],vel_trial_ref[k*nDOF_trial_element+j]);
5584  dpdeResidual_v_v[j]+= ck.ReactionJacobian_strong(dmom_v_source[1],vel_trial_ref[k*nDOF_trial_element+j]);
5585  /* dpdeResidual_w_w[j]+= ck.ReactionJacobian_strong(dmom_w_source[2],vel_trial_ref[k*nDOF_trial_element+j]); */
5586  //
5587  }
5588  //calculate tau and tau*Res
5589  //cek debug
5590  double tmpR=dmom_u_acc_u_t + dmom_u_source[0];
5591  calculateSubgridError_tau(hFactor,
5592  elementDiameter[eN],
5593  tmpR,//dmom_u_acc_u_t,
5594  dmom_u_acc_u,
5595  dmom_adv_sge,
5596  mom_uu_diff_ten[1],
5597  dmom_u_ham_grad_p[0],
5598  tau_v0,
5599  tau_p0,
5600  q_cfl[eN_k]);
5601 
5602  calculateSubgridError_tau(Ct_sge,Cd_sge,
5603  G,G_dd_G,tr_G,
5604  tmpR,//dmom_u_acc_u_t,
5605  dmom_adv_sge,
5606  mom_uu_diff_ten[1],
5607  dmom_u_ham_grad_p[0],
5608  tau_v1,
5609  tau_p1,
5610  q_cfl[eN_k]);
5611 
5612 
5613  tau_v = useMetrics*tau_v1+(1.0-useMetrics)*tau_v0;
5614  tau_p = KILL_PRESSURE_TERM == 1 ? 0. : PSTAB*(useMetrics*tau_p1+(1.0-useMetrics)*tau_p0);
5616  tau_v,
5617  pdeResidual_p,
5618  pdeResidual_u,
5619  pdeResidual_v,
5620  pdeResidual_w,
5621  subgridError_p,
5622  subgridError_u,
5623  subgridError_v,
5624  subgridError_w);
5625 
5627  tau_v,
5628  dpdeResidual_p_u,
5629  dpdeResidual_p_v,
5630  dpdeResidual_p_w,
5631  dpdeResidual_u_p,
5632  dpdeResidual_u_u,
5633  dpdeResidual_v_p,
5634  dpdeResidual_v_v,
5635  dpdeResidual_w_p,
5636  dpdeResidual_w_w,
5637  dsubgridError_p_u,
5638  dsubgridError_p_v,
5639  dsubgridError_p_w,
5640  dsubgridError_u_p,
5641  dsubgridError_u_u,
5642  dsubgridError_v_p,
5643  dsubgridError_v_v,
5644  dsubgridError_w_p,
5645  dsubgridError_w_w);
5646  // velocity used in adjoint (VMS or RBLES, with or without lagging the grid scale velocity)
5647  dmom_adv_star[0] = dmom_u_acc_u*(q_velocity_sge[eN_k_nSpace+0] - MOVING_DOMAIN*xt + useRBLES*subgridError_u);
5648  dmom_adv_star[1] = dmom_u_acc_u*(q_velocity_sge[eN_k_nSpace+1] - MOVING_DOMAIN*yt + useRBLES*subgridError_v);
5649  /* dmom_adv_star[2] = dmom_u_acc_u*(q_velocity_sge[eN_k_nSpace+2] - MOVING_DOMAIN*zt + useRBLES*subgridError_w); */
5650 
5651  //calculate the adjoint times the test functions
5652  for (int i=0;i<nDOF_test_element;i++)
5653  {
5654  register int i_nSpace = i*nSpace;
5655  Lstar_u_p[i]=ck.Advection_adjoint(dmass_adv_u,&p_grad_test_dV[i_nSpace]);
5656  Lstar_v_p[i]=ck.Advection_adjoint(dmass_adv_v,&p_grad_test_dV[i_nSpace]);
5657  /* Lstar_w_p[i]=ck.Advection_adjoint(dmass_adv_w,&p_grad_test_dV[i_nSpace]); */
5658  Lstar_u_u[i]=ck.Advection_adjoint(dmom_adv_star,&vel_grad_test_dV[i_nSpace]);
5659  Lstar_v_v[i]=ck.Advection_adjoint(dmom_adv_star,&vel_grad_test_dV[i_nSpace]);
5660  /* Lstar_w_w[i]=ck.Advection_adjoint(dmom_adv_star,&vel_grad_test_dV[i_nSpace]); */
5661  Lstar_p_u[i]=ck.Hamiltonian_adjoint(dmom_u_ham_grad_p,&vel_grad_test_dV[i_nSpace]);
5662  Lstar_p_v[i]=ck.Hamiltonian_adjoint(dmom_v_ham_grad_p,&vel_grad_test_dV[i_nSpace]);
5663  /* Lstar_p_w[i]=ck.Hamiltonian_adjoint(dmom_w_ham_grad_p,&vel_grad_test_dV[i_nSpace]); */
5664  //VRANS account for drag terms, diagonal only here ... decide if need off diagonal terms too
5665  Lstar_u_u[i]+=ck.Reaction_adjoint(dmom_u_source[0],vel_test_dV[i]);
5666  Lstar_v_v[i]+=ck.Reaction_adjoint(dmom_v_source[1],vel_test_dV[i]);
5667  /* Lstar_w_w[i]+=ck.Reaction_adjoint(dmom_w_source[2],vel_test_dV[i]); */
5668  }
5669 
5670  // Assumes non-lagged subgrid velocity
5671  dmom_u_adv_u[0] += dmom_u_acc_u*(useRBLES*subgridError_u);
5672  dmom_u_adv_u[1] += dmom_u_acc_u*(useRBLES*subgridError_v);
5673  /* dmom_u_adv_u[2] += dmom_u_acc_u*(useRBLES*subgridError_w); */
5674 
5675  dmom_v_adv_v[0] += dmom_u_acc_u*(useRBLES*subgridError_u);
5676  dmom_v_adv_v[1] += dmom_u_acc_u*(useRBLES*subgridError_v);
5677  /* dmom_v_adv_v[2] += dmom_u_acc_u*(useRBLES*subgridError_w); */
5678 
5679  /* dmom_w_adv_w[0] += dmom_u_acc_u*(useRBLES*subgridError_u); */
5680  /* dmom_w_adv_w[1] += dmom_u_acc_u*(useRBLES*subgridError_v); */
5681  /* dmom_w_adv_w[2] += dmom_u_acc_u*(useRBLES*subgridError_w); */
5682 
5683  // SURFACE TENSION //
5684  double unit_normal[nSpace];
5685  double norm_grad_phi = 0.;
5686  for (int I=0;I<nSpace;I++)
5687  norm_grad_phi += normal_phi[eN_k_nSpace+I]*normal_phi[eN_k_nSpace+I];
5688  norm_grad_phi = std::sqrt(norm_grad_phi) + 1E-10;
5689  for (int I=0;I<nSpace;I++)
5690  unit_normal[I] = normal_phi[eN_k_nSpace+I]/norm_grad_phi;
5691  double delta = gf.D(eps_mu,phi[eN_k]); //use eps_rho instead?
5692  register double vel_tgrad_test_i[nSpace], vel_tgrad_test_j[nSpace];
5693  // END OF SURFACE TENSION //
5694 
5695  //cek todo add RBLES terms consistent to residual modifications or ignore the partials w.r.t the additional RBLES terms
5696  for(int i=0;i<nDOF_test_element;i++)
5697  {
5698  register int i_nSpace = i*nSpace;
5699  calculateTangentialGradient(unit_normal,
5700  &vel_grad_trial[i_nSpace],
5701  vel_tgrad_test_i);
5702  for(int j=0;j<nDOF_trial_element;j++)
5703  {
5704  register int j_nSpace = j*nSpace;
5705  calculateTangentialGradient(unit_normal,
5706  &vel_grad_trial[j_nSpace],
5707  vel_tgrad_test_j);
5708 
5709  /* elementJacobian_p_p[i][j] += ck.SubgridErrorJacobian(dsubgridError_u_p[j],Lstar_u_p[i]) + */
5710  /* ck.SubgridErrorJacobian(dsubgridError_v_p[j],Lstar_v_p[i]);// + */
5711  /* /\* ck.SubgridErrorJacobian(dsubgridError_w_p[j],Lstar_w_p[i]); *\/ */
5712 
5713  /* elementJacobian_p_u[i][j] += ck.AdvectionJacobian_weak(dmass_adv_u,vel_trial_ref[k*nDOF_trial_element+j],&p_grad_test_dV[i_nSpace]) + */
5714  /* ck.SubgridErrorJacobian(dsubgridError_u_u[j],Lstar_u_p[i]); */
5715  /* elementJacobian_p_v[i][j] += ck.AdvectionJacobian_weak(dmass_adv_v,vel_trial_ref[k*nDOF_trial_element+j],&p_grad_test_dV[i_nSpace]) + */
5716  /* ck.SubgridErrorJacobian(dsubgridError_v_v[j],Lstar_v_p[i]); */
5717  /* elementJacobian_p_w[i][j] += ck.AdvectionJacobian_weak(dmass_adv_w,vel_trial_ref[k*nDOF_trial_element+j],&p_grad_test_dV[i_nSpace]) + */
5718  /* ck.SubgridErrorJacobian(dsubgridError_w_w[j],Lstar_w_p[i]); */
5719 
5720  /* elementJacobian_u_p[i][j] += ck.HamiltonianJacobian_weak(dmom_u_ham_grad_p,&p_grad_trial[j_nSpace],vel_test_dV[i]) + */
5721  /* ck.SubgridErrorJacobian(dsubgridError_u_p[j],Lstar_u_u[i]); */
5722  elementJacobian_u_u[i][j] +=
5723  ck.MassJacobian_weak(dmom_u_acc_u_t,vel_trial_ref[k*nDOF_trial_element+j],vel_test_dV[i]) +
5724  ck.HamiltonianJacobian_weak(dmom_u_ham_grad_u,&vel_grad_trial[j_nSpace],vel_test_dV[i]) +
5725  ck.AdvectionJacobian_weak(dmom_u_adv_u,vel_trial_ref[k*nDOF_trial_element+j],&vel_grad_test_dV[i_nSpace]) +
5726  ck.SimpleDiffusionJacobian_weak(sdInfo_u_u_rowptr.data(),sdInfo_u_u_colind.data(),mom_uu_diff_ten,&vel_grad_trial[j_nSpace],&vel_grad_test_dV[i_nSpace]) +
5727  //VRANS
5728  ck.ReactionJacobian_weak(dmom_u_source[0],vel_trial_ref[k*nDOF_trial_element+j],vel_test_dV[i]) +
5729  //
5730  //ck.SubgridErrorJacobian(dsubgridError_p_u[j],Lstar_p_u[i]) +
5731  USE_SUPG*ck.SubgridErrorJacobian(dsubgridError_u_u[j],Lstar_u_u[i]) +
5732  ck.NumericalDiffusionJacobian(q_numDiff_u_last[eN_k],&vel_grad_trial[j_nSpace],&vel_grad_test_dV[i_nSpace]) +
5733  // surface tension
5734  ck.NumericalDiffusion(dt*delta*sigma*dV,
5735  vel_tgrad_test_i,
5736  vel_tgrad_test_j);
5737 
5738  elementJacobian_u_v[i][j] +=
5739  ck.AdvectionJacobian_weak(dmom_u_adv_v,vel_trial_ref[k*nDOF_trial_element+j],&vel_grad_test_dV[i_nSpace]) +
5740  ck.SimpleDiffusionJacobian_weak(sdInfo_u_v_rowptr.data(),sdInfo_u_v_colind.data(),mom_uv_diff_ten,&vel_grad_trial[j_nSpace],&vel_grad_test_dV[i_nSpace]) +
5741  //VRANS
5742  ck.ReactionJacobian_weak(dmom_u_source[1],vel_trial_ref[k*nDOF_trial_element+j],vel_test_dV[i])
5743  //+ck.SubgridErrorJacobian(dsubgridError_p_v[j],Lstar_p_u[i])
5744  ;
5745  /* elementJacobian_u_w[i][j] += ck.AdvectionJacobian_weak(dmom_u_adv_w,vel_trial_ref[k*nDOF_trial_element+j],&vel_grad_test_dV[i_nSpace]) + */
5746  /* ck.SimpleDiffusionJacobian_weak(sdInfo_u_w_rowptr,sdInfo_u_w_colind,mom_uw_diff_ten,&vel_grad_trial[j_nSpace],&vel_grad_test_dV[i_nSpace]) + */
5747  /* //VRANS */
5748  /* ck.ReactionJacobian_weak(dmom_u_source[2],vel_trial_ref[k*nDOF_trial_element+j],vel_test_dV[i]) + */
5749  /* // */
5750  /* ck.SubgridErrorJacobian(dsubgridError_p_w[j],Lstar_p_u[i]); */
5751 
5752  /* elementJacobian_v_p[i][j] += ck.HamiltonianJacobian_weak(dmom_v_ham_grad_p,&p_grad_trial[j_nSpace],vel_test_dV[i]) + */
5753  /* ck.SubgridErrorJacobian(dsubgridError_v_p[j],Lstar_v_v[i]); */
5754  elementJacobian_v_u[i][j] +=
5755  ck.AdvectionJacobian_weak(dmom_v_adv_u,vel_trial_ref[k*nDOF_trial_element+j],&vel_grad_test_dV[i_nSpace]) +
5756  ck.SimpleDiffusionJacobian_weak(sdInfo_v_u_rowptr.data(),sdInfo_v_u_colind.data(),mom_vu_diff_ten,&vel_grad_trial[j_nSpace],&vel_grad_test_dV[i_nSpace]) +
5757  //VRANS
5758  ck.ReactionJacobian_weak(dmom_v_source[0],vel_trial_ref[k*nDOF_trial_element+j],vel_test_dV[i])
5759  //+ck.SubgridErrorJacobian(dsubgridError_p_u[j],Lstar_p_v[i])
5760  ;
5761  elementJacobian_v_v[i][j] +=
5762  ck.MassJacobian_weak(dmom_v_acc_v_t,vel_trial_ref[k*nDOF_trial_element+j],vel_test_dV[i]) +
5763  ck.HamiltonianJacobian_weak(dmom_v_ham_grad_v,&vel_grad_trial[j_nSpace],vel_test_dV[i]) +
5764  ck.AdvectionJacobian_weak(dmom_v_adv_v,vel_trial_ref[k*nDOF_trial_element+j],&vel_grad_test_dV[i_nSpace]) +
5765  ck.SimpleDiffusionJacobian_weak(sdInfo_v_v_rowptr.data(),sdInfo_v_v_colind.data(),mom_vv_diff_ten,&vel_grad_trial[j_nSpace],&vel_grad_test_dV[i_nSpace]) +
5766  //VRANS
5767  ck.ReactionJacobian_weak(dmom_v_source[1],vel_trial_ref[k*nDOF_trial_element+j],vel_test_dV[i]) +
5768  //
5769  //ck.SubgridErrorJacobian(dsubgridError_p_v[j],Lstar_p_v[i]) +
5770  USE_SUPG*ck.SubgridErrorJacobian(dsubgridError_v_v[j],Lstar_v_v[i]) +
5771  ck.NumericalDiffusionJacobian(q_numDiff_v_last[eN_k],&vel_grad_trial[j_nSpace],&vel_grad_test_dV[i_nSpace]) +
5772  // surface tension
5773  ck.NumericalDiffusion(dt*delta*sigma*dV,
5774  vel_tgrad_test_i,
5775  vel_tgrad_test_j);
5776 
5777  /* elementJacobian_v_w[i][j] += ck.AdvectionJacobian_weak(dmom_v_adv_w,vel_trial_ref[k*nDOF_trial_element+j],&vel_grad_test_dV[i_nSpace]) + */
5778  /* ck.SimpleDiffusionJacobian_weak(sdInfo_v_w_rowptr,sdInfo_v_w_colind,mom_vw_diff_ten,&vel_grad_trial[j_nSpace],&vel_grad_test_dV[i_nSpace]) + */
5779  /* //VRANS */
5780  /* ck.ReactionJacobian_weak(dmom_v_source[2],vel_trial_ref[k*nDOF_trial_element+j],vel_test_dV[i]) + */
5781  /* // */
5782  /* ck.SubgridErrorJacobian(dsubgridError_p_w[j],Lstar_p_v[i]); */
5783 
5784  /* elementJacobian_w_p[i][j] += ck.HamiltonianJacobian_weak(dmom_w_ham_grad_p,&p_grad_trial[j_nSpace],vel_test_dV[i]) + */
5785  /* ck.SubgridErrorJacobian(dsubgridError_w_p[j],Lstar_w_w[i]); */
5786  /* elementJacobian_w_u[i][j] += ck.AdvectionJacobian_weak(dmom_w_adv_u,vel_trial_ref[k*nDOF_trial_element+j],&vel_grad_test_dV[i_nSpace]) + */
5787  /* ck.SimpleDiffusionJacobian_weak(sdInfo_w_u_rowptr,sdInfo_w_u_colind,mom_wu_diff_ten,&vel_grad_trial[j_nSpace],&vel_grad_test_dV[i_nSpace]) + */
5788  /* //VRANS */
5789  /* ck.ReactionJacobian_weak(dmom_w_source[0],vel_trial_ref[k*nDOF_trial_element+j],vel_test_dV[i]) + */
5790  /* // */
5791  /* ck.SubgridErrorJacobian(dsubgridError_p_u[j],Lstar_p_w[i]); */
5792  /* elementJacobian_w_v[i][j] += ck.AdvectionJacobian_weak(dmom_w_adv_v,vel_trial_ref[k*nDOF_trial_element+j],&vel_grad_test_dV[i_nSpace]) + */
5793  /* ck.SimpleDiffusionJacobian_weak(sdInfo_w_v_rowptr,sdInfo_w_v_colind,mom_wv_diff_ten,&vel_grad_trial[j_nSpace],&vel_grad_test_dV[i_nSpace]) + */
5794  /* //VRANS */
5795  /* ck.ReactionJacobian_weak(dmom_w_source[1],vel_trial_ref[k*nDOF_trial_element+j],vel_test_dV[i]) + */
5796  /* // */
5797  /* ck.SubgridErrorJacobian(dsubgridError_p_v[j],Lstar_p_w[i]); */
5798  /* elementJacobian_w_w[i][j] += ck.MassJacobian_weak(dmom_w_acc_w_t,vel_trial_ref[k*nDOF_trial_element+j],vel_test_dV[i]) + */
5799  /* ck.HamiltonianJacobian_weak(dmom_w_ham_grad_w,&vel_grad_trial[j_nSpace],vel_test_dV[i]) + */
5800  /* ck.AdvectionJacobian_weak(dmom_w_adv_w,vel_trial_ref[k*nDOF_trial_element+j],&vel_grad_test_dV[i_nSpace]) + */
5801  /* ck.SimpleDiffusionJacobian_weak(sdInfo_w_w_rowptr,sdInfo_w_w_colind,mom_ww_diff_ten,&vel_grad_trial[j_nSpace],&vel_grad_test_dV[i_nSpace]) + */
5802  /* //VRANS */
5803  /* ck.ReactionJacobian_weak(dmom_w_source[2],vel_trial_ref[k*nDOF_trial_element+j],vel_test_dV[i]) + */
5804  /* // */
5805  /* ck.SubgridErrorJacobian(dsubgridError_p_w[j],Lstar_p_w[i]) + */
5806  /* ck.SubgridErrorJacobian(dsubgridError_w_w[j],Lstar_w_w[i]) + */
5807  /* ck.NumericalDiffusionJacobian(q_numDiff_w_last[eN_k],&vel_grad_trial[j_nSpace],&vel_grad_test_dV[i_nSpace]); */
5808  }//j
5809  }//i
5810  }//k
5811  //
5812  //load into element Jacobian into global Jacobian
5813  //
5814  for (int i=0;i<nDOF_test_element;i++)
5815  {
5816  register int eN_i = eN*nDOF_test_element+i;
5817  for (int j=0;j<nDOF_trial_element;j++)
5818  {
5819  register int eN_i_j = eN_i*nDOF_trial_element+j;
5820  /* globalJacobian[csrRowIndeces_p_p[eN_i] + csrColumnOffsets_p_p[eN_i_j]] += elementJacobian_p_p[i][j]; */
5821  /* globalJacobian[csrRowIndeces_p_u[eN_i] + csrColumnOffsets_p_u[eN_i_j]] += elementJacobian_p_u[i][j]; */
5822  /* globalJacobian[csrRowIndeces_p_v[eN_i] + csrColumnOffsets_p_v[eN_i_j]] += elementJacobian_p_v[i][j]; */
5823  /* globalJacobian[csrRowIndeces_p_w[eN_i] + csrColumnOffsets_p_w[eN_i_j]] += elementJacobian_p_w[i][j]; */
5824 
5825  /* globalJacobian[csrRowIndeces_u_p[eN_i] + csrColumnOffsets_u_p[eN_i_j]] += elementJacobian_u_p[i][j]; */
5826  globalJacobian[csrRowIndeces_u_u[eN_i] + csrColumnOffsets_u_u[eN_i_j]] += element_active*elementJacobian_u_u[i][j];
5827  globalJacobian[csrRowIndeces_u_v[eN_i] + csrColumnOffsets_u_v[eN_i_j]] += element_active*elementJacobian_u_v[i][j];
5828  /* globalJacobian[csrRowIndeces_u_w[eN_i] + csrColumnOffsets_u_w[eN_i_j]] += elementJacobian_u_w[i][j]; */
5829 
5830  /* globalJacobian[csrRowIndeces_v_p[eN_i] + csrColumnOffsets_v_p[eN_i_j]] += elementJacobian_v_p[i][j]; */
5831  globalJacobian[csrRowIndeces_v_u[eN_i] + csrColumnOffsets_v_u[eN_i_j]] += element_active*elementJacobian_v_u[i][j];
5832  globalJacobian[csrRowIndeces_v_v[eN_i] + csrColumnOffsets_v_v[eN_i_j]] += element_active*elementJacobian_v_v[i][j];
5833  /* globalJacobian[csrRowIndeces_v_w[eN_i] + csrColumnOffsets_v_w[eN_i_j]] += elementJacobian_v_w[i][j]; */
5834 
5835  /* globalJacobian[csrRowIndeces_w_p[eN_i] + csrColumnOffsets_w_p[eN_i_j]] += elementJacobian_w_p[i][j]; */
5836  /* globalJacobian[csrRowIndeces_w_u[eN_i] + csrColumnOffsets_w_u[eN_i_j]] += elementJacobian_w_u[i][j]; */
5837  /* globalJacobian[csrRowIndeces_w_v[eN_i] + csrColumnOffsets_w_v[eN_i_j]] += elementJacobian_w_v[i][j]; */
5838  /* globalJacobian[csrRowIndeces_w_w[eN_i] + csrColumnOffsets_w_w[eN_i_j]] += elementJacobian_w_w[i][j]; */
5839  }//j
5840  }//i
5841  }//elements
5842 
5843  // loop in DOFs for discrete upwinding
5844  if (ARTIFICIAL_VISCOSITY==3 || ARTIFICIAL_VISCOSITY==4)
5845  {
5846  int ij=0;
5847  for (int i=0; i<numDOFs_1D; i++)
5848  {
5849  // global index for each component
5850  int u_gi = offset_u+stride_u*i;
5851  int v_gi = offset_v+stride_v*i;
5852 
5853  // pointer to first entry in the ith row for each component
5854  int u_ith_row_ptr = rowptr[u_gi];
5855  int v_ith_row_ptr = rowptr[v_gi];
5856 
5857  // number of DOFs in the ith row (of the small matrix dMatrix)
5858  int numDOFs_ith_row = rowptr_1D[i+1]-rowptr_1D[i];
5859  for (int counter = 0; counter < numDOFs_ith_row; counter++)
5860  {
5861  // ij pointer for each component
5862  int uu_ij = u_ith_row_ptr + (offset_u + counter*stride_u);
5863  int vv_ij = v_ith_row_ptr + (offset_v + counter*stride_v);
5864 
5865  // read ij component of dissipative matrix
5866  double uStar_dij = uStar_dMatrix[ij];
5867  double vStar_dij = vStar_dMatrix[ij];
5868 
5869  // update global Jacobian
5870  globalJacobian[uu_ij] -= uStar_dij;
5871  globalJacobian[vv_ij] -= vStar_dij;
5872 
5873  // update ij
5874  ij++;
5875  }
5876  }
5877  }
5878 
5879  if(USE_SBM>0)
5880  {
5881  //loop over the surrogate boundaries in SB method and assembly into jacobian
5882  //
5883  for (int ebN_s=0;ebN_s < surrogate_boundaries.size();ebN_s++)
5884  {
5885  register int ebN = surrogate_boundaries[ebN_s],
5886  eN = elementBoundaryElementsArray[ebN*2+surrogate_boundary_elements[ebN_s]],
5887  ebN_local = elementBoundaryLocalElementBoundariesArray[ebN*2+surrogate_boundary_elements[ebN_s]],
5888  eN_nDOF_trial_element = eN*nDOF_trial_element;
5889  register double eps_rho,eps_mu;
5890  //This assumption is wrong for parallel: If one of nodes of this edge is owned by this processor,
5891  //then the integral over this edge has contribution to the residual and Jacobian.
5892  //if (ebN >= nElementBoundaries_owned) continue;
5893  for (int kb=0;kb<nQuadraturePoints_elementBoundary;kb++)
5894  {
5895  register int ebN_kb = ebN*nQuadraturePoints_elementBoundary+kb,
5896  ebN_kb_nSpace = ebN_kb*nSpace,
5897  ebN_local_kb = ebN_local*nQuadraturePoints_elementBoundary+kb,
5898  ebN_local_kb_nSpace = ebN_local_kb*nSpace;
5899 
5900  register double u_ext=0.0,
5901  v_ext=0.0,
5902  bc_u_ext=0.0,
5903  bc_v_ext=0.0,
5904  grad_u_ext[nSpace],
5905  grad_v_ext[nSpace],
5906  jac_ext[nSpace*nSpace],
5907  jacDet_ext,
5908  jacInv_ext[nSpace*nSpace],
5909  boundaryJac[nSpace*(nSpace-1)],
5910  metricTensor[(nSpace-1)*(nSpace-1)],
5911  metricTensorDetSqrt,
5912  vel_grad_trial_trace[nDOF_trial_element*nSpace],
5913  dS,
5914  vel_test_dS[nDOF_test_element],
5915  normal[2],
5916  x_ext,y_ext,z_ext,xt_ext,yt_ext,zt_ext,integralScaling,
5917  vel_grad_test_dS[nDOF_trial_element*nSpace],
5918  G[nSpace*nSpace],G_dd_G,tr_G,h_phi,h_penalty,penalty;
5919  ck.calculateMapping_elementBoundary(eN,
5920  ebN_local,
5921  kb,
5922  ebN_local_kb,
5923  mesh_dof.data(),
5924  mesh_l2g.data(),
5925  mesh_trial_trace_ref.data(),
5926  mesh_grad_trial_trace_ref.data(),
5927  boundaryJac_ref.data(),
5928  jac_ext,
5929  jacDet_ext,
5930  jacInv_ext,
5931  boundaryJac,
5932  metricTensor,
5933  metricTensorDetSqrt,
5934  normal_ref.data(),
5935  normal,
5936  x_ext,y_ext,z_ext);
5937  ck.calculateMappingVelocity_elementBoundary(eN,
5938  ebN_local,
5939  kb,
5940  ebN_local_kb,
5941  mesh_velocity_dof.data(),
5942  mesh_l2g.data(),
5943  mesh_trial_trace_ref.data(),
5944  xt_ext,yt_ext,zt_ext,
5945  normal,
5946  boundaryJac,
5947  metricTensor,
5948  integralScaling);
5949  dS = metricTensorDetSqrt*dS_ref[kb];
5950  ck.calculateG(jacInv_ext,G,G_dd_G,tr_G);
5951  //compute shape and solution information
5952  //shape
5953  ck.gradTrialFromRef(&vel_grad_trial_trace_ref[ebN_local_kb_nSpace*nDOF_trial_element],jacInv_ext,vel_grad_trial_trace);
5954  //solution and gradients
5955  ck.valFromDOF(u_dof.data(),&vel_l2g[eN_nDOF_trial_element],&vel_trial_trace_ref[ebN_local_kb*nDOF_test_element],u_ext);
5956  ck.valFromDOF(v_dof.data(),&vel_l2g[eN_nDOF_trial_element],&vel_trial_trace_ref[ebN_local_kb*nDOF_test_element],v_ext);
5957 
5958  ck.gradFromDOF(u_dof.data(),&vel_l2g[eN_nDOF_trial_element],vel_grad_trial_trace,grad_u_ext);
5959  ck.gradFromDOF(v_dof.data(),&vel_l2g[eN_nDOF_trial_element],vel_grad_trial_trace,grad_v_ext);
5960  //precalculate test function products with integration weights
5961  for (int j=0;j<nDOF_trial_element;j++)
5962  {
5963  vel_test_dS[j] = vel_test_trace_ref[ebN_local_kb*nDOF_test_element+j]*dS;
5964  for (int I=0;I<nSpace;I++)
5965  vel_grad_test_dS[j*nSpace+I] = vel_grad_trial_trace[j*nSpace+I]*dS;
5966  }
5967  //
5968  //load the boundary values
5969  //
5970  bc_u_ext = 0.0;
5971  bc_v_ext = 0.0;
5972  ck.calculateGScale(G,normal,h_penalty);
5973  //
5974  //update the global Jacobian from the flux Jacobian
5975  //
5976 
5977  double dist = 0.0;
5978  double distance[2], P_normal[2], P_tangent[2]; // distance vector, normal and tangent of the physical boundary
5979 
5980  if(use_ball_as_particle==1)
5981  {
5982  get_distance_to_ball(nParticles,ball_center.data(),ball_radius.data(),
5983  x_ext,y_ext,z_ext,
5984  dist);
5985  get_normal_to_ith_ball(nParticles,ball_center.data(),ball_radius.data(),
5987  x_ext,y_ext,z_ext,
5988  P_normal[0],P_normal[1]);
5989  get_velocity_to_ith_ball(nParticles,ball_center.data(),ball_radius.data(),
5990  ball_velocity.data(), ball_angular_velocity.data(),
5992  x_ext-dist*P_normal[0],
5993  y_ext-dist*P_normal[1],
5994  0.0,//z_ext,
5995  bc_u_ext,bc_v_ext);
5996  }
5997  else
5998  {
5999  dist = ebq_global_phi_solid[ebN_kb];
6000  P_normal[0] = ebq_global_grad_phi_solid[ebN_kb*3+0];
6001  P_normal[1] = ebq_global_grad_phi_solid[ebN_kb*3+1];
6002  bc_u_ext = ebq_particle_velocity_solid [ebN_kb*3+0];
6003  bc_v_ext = ebq_particle_velocity_solid [ebN_kb*3+1];
6004  }
6005  distance[0] = -P_normal[0]*dist;//distance=vector from \tilde{x} to x. It holds also when dist<0.0
6006  distance[1] = -P_normal[1]*dist;
6007  P_tangent[0]= -P_normal[1];
6008  P_tangent[1]= P_normal[0];
6009  assert(h_penalty>0.0);
6010  if (h_penalty < std::abs(dist))
6011  h_penalty = std::abs(dist);
6012  //hack: this won't work for two-phase flow, need mixture viscosity
6013  double visco = nu_0*rho_0;
6014  double C_adim = C_sbm*visco/h_penalty;
6015  double beta_adim = beta_sbm*visco/h_penalty;
6016 
6017  for (int i=0;i<nDOF_test_element;i++)
6018  {
6019  register int eN_i = eN*nDOF_test_element+i;
6020  double phi_i = vel_test_dS[i];
6021  double* grad_phi_i = &vel_grad_test_dS[i*nSpace+0];
6022  const double grad_phi_i_dot_d = get_dot_product(grad_phi_i,distance);
6023  const double grad_phi_i_dot_t = get_dot_product(P_tangent,grad_phi_i);
6024 
6025  double res[2];
6026  const double zero_vec[2]={0.,0.};
6027  for (int j=0;j<nDOF_trial_element;j++)
6028  {
6029  register int ebN_i_j = ebN*4*nDOF_test_X_trial_element
6032  + i*nDOF_trial_element
6033  + j;
6034 
6035  double phi_j = vel_test_dS[j]/dS;
6036  const double grad_phi_j[2]={vel_grad_test_dS[j*nSpace+0]/dS,
6037  vel_grad_test_dS[j*nSpace+1]/dS};
6038  const double grad_phi_j_dot_d = get_dot_product(distance, grad_phi_j);
6039  const double grad_phi_j_dot_t = get_dot_product(P_tangent,grad_phi_j);
6040 
6041  // Classical Nitsche
6042  // (1)
6043  globalJacobian[csrRowIndeces_u_u[eN_i] + csrColumnOffsets_eb_u_u[ebN_i_j]] +=
6044  phi_i*phi_j*C_adim;
6045  globalJacobian[csrRowIndeces_v_v[eN_i] + csrColumnOffsets_eb_v_v[ebN_i_j]] +=
6046  phi_i*phi_j*C_adim;
6047 
6048  // (2)
6049  get_symmetric_gradient_dot_vec(grad_phi_j,zero_vec,normal,res);
6050  globalJacobian[csrRowIndeces_u_u[eN_i] + csrColumnOffsets_eb_u_u[ebN_i_j]] -=
6051  visco * phi_i * res[0];
6052  globalJacobian[csrRowIndeces_u_v[eN_i] + csrColumnOffsets_eb_u_v[ebN_i_j]] -=
6053  visco * phi_i * res[1];
6054 
6055  get_symmetric_gradient_dot_vec(zero_vec,grad_phi_j,normal,res);
6056  globalJacobian[csrRowIndeces_v_u[eN_i] + csrColumnOffsets_eb_v_u[ebN_i_j]] -=
6057  visco * phi_i * res[0];
6058  globalJacobian[csrRowIndeces_v_v[eN_i] + csrColumnOffsets_eb_v_v[ebN_i_j]] -=
6059  visco * phi_i * res[1];
6060 
6061  // (3)
6062  get_symmetric_gradient_dot_vec(grad_phi_i,zero_vec,normal,res);
6063  globalJacobian[csrRowIndeces_u_u[eN_i] + csrColumnOffsets_eb_u_u[ebN_i_j]] -=
6064  visco * phi_j * res[0];
6065  globalJacobian[csrRowIndeces_u_v[eN_i] + csrColumnOffsets_eb_u_v[ebN_i_j]] -=
6066  visco * phi_j * res[1];
6067  get_symmetric_gradient_dot_vec(zero_vec,grad_phi_i,normal,res);
6068  globalJacobian[csrRowIndeces_v_u[eN_i] + csrColumnOffsets_eb_v_u[ebN_i_j]] -=
6069  visco * phi_j * res[0];
6070  globalJacobian[csrRowIndeces_v_v[eN_i] + csrColumnOffsets_eb_v_v[ebN_i_j]] -=
6071  visco * phi_j * res[1];
6072 
6073  // (4)
6074  globalJacobian[csrRowIndeces_u_u[eN_i] + csrColumnOffsets_eb_u_u[ebN_i_j]] +=
6075  C_adim*grad_phi_i_dot_d*phi_j;
6076  globalJacobian[csrRowIndeces_v_v[eN_i] + csrColumnOffsets_eb_v_v[ebN_i_j]] +=
6077  C_adim*grad_phi_i_dot_d*phi_j;
6078 
6079  // (5)
6080  globalJacobian[csrRowIndeces_u_u[eN_i] + csrColumnOffsets_eb_u_u[ebN_i_j]] +=
6081  C_adim*grad_phi_i_dot_d*grad_phi_j_dot_d;
6082  globalJacobian[csrRowIndeces_v_v[eN_i] + csrColumnOffsets_eb_v_v[ebN_i_j]] +=
6083  C_adim*grad_phi_i_dot_d*grad_phi_j_dot_d;
6084 
6085  // (6)
6086  globalJacobian[csrRowIndeces_u_u[eN_i] + csrColumnOffsets_eb_u_u[ebN_i_j]] +=
6087  C_adim*grad_phi_j_dot_d*phi_i;
6088  globalJacobian[csrRowIndeces_v_v[eN_i] + csrColumnOffsets_eb_v_v[ebN_i_j]] +=
6089  C_adim*grad_phi_j_dot_d*phi_i;
6090 
6091  // (7)
6092  get_symmetric_gradient_dot_vec(grad_phi_i,zero_vec,normal,res);
6093  globalJacobian[csrRowIndeces_u_u[eN_i] + csrColumnOffsets_eb_u_u[ebN_i_j]] -=
6094  visco * grad_phi_j_dot_d * res[0];
6095  globalJacobian[csrRowIndeces_u_v[eN_i] + csrColumnOffsets_eb_u_v[ebN_i_j]] -=
6096  visco * grad_phi_j_dot_d * res[1];
6097 
6098  get_symmetric_gradient_dot_vec(zero_vec,grad_phi_i,normal,res);
6099  globalJacobian[csrRowIndeces_v_u[eN_i] + csrColumnOffsets_eb_v_u[ebN_i_j]] -=
6100  visco * grad_phi_j_dot_d * res[0] ;
6101  globalJacobian[csrRowIndeces_v_v[eN_i] + csrColumnOffsets_eb_v_v[ebN_i_j]] -=
6102  visco * grad_phi_j_dot_d * res[1];
6103 
6104  // (8)
6105  // the penalization on the tangential derivative
6106  // B < Gw t , (Gu - GuD) t >
6107  globalJacobian[csrRowIndeces_u_u[eN_i] + csrColumnOffsets_eb_u_u[ebN_i_j]] +=
6108  beta_adim*grad_phi_j_dot_t*grad_phi_i_dot_t;
6109  globalJacobian[csrRowIndeces_v_v[eN_i] + csrColumnOffsets_eb_v_v[ebN_i_j]] +=
6110  beta_adim*grad_phi_j_dot_t*grad_phi_i_dot_t;
6111 
6112  }//j
6113  }//i
6114  }//kb
6115  }//ebN_s
6116  }
6117  //
6118  //loop over exterior element boundaries to compute the surface integrals and load them into the global Jacobian
6119  //
6120  //exact generalized function integration not implemented for boundaries yet
6121  gf.useExact=false;
6122  gf_s.useExact=false;
6123  for (int ebNE = 0; ebNE < nExteriorElementBoundaries_global; ebNE++)
6124  {
6125  register int ebN = exteriorElementBoundariesArray[ebNE],
6126  eN = elementBoundaryElementsArray[ebN*2+0],
6127  eN_nDOF_trial_element = eN*nDOF_trial_element,
6128  ebN_local = elementBoundaryLocalElementBoundariesArray[ebN*2+0];
6129  register double eps_rho,eps_mu;
6130  for (int kb=0;kb<nQuadraturePoints_elementBoundary;kb++)
6131  {
6132  register int ebNE_kb = ebNE*nQuadraturePoints_elementBoundary+kb,
6133  ebNE_kb_nSpace = ebNE_kb*nSpace,
6134  ebN_local_kb = ebN_local*nQuadraturePoints_elementBoundary+kb,
6135  ebN_local_kb_nSpace = ebN_local_kb*nSpace;
6136 
6137  register double p_ext=0.0,
6138  u_ext=0.0,
6139  v_ext=0.0,
6140  w_ext=0.0,
6141  grad_p_ext[nSpace],
6142  grad_u_ext[nSpace],
6143  grad_v_ext[nSpace],
6144  grad_w_ext[nSpace],
6145  mom_u_acc_ext=0.0,
6146  dmom_u_acc_u_ext=0.0,
6147  mom_v_acc_ext=0.0,
6148  dmom_v_acc_v_ext=0.0,
6149  mom_w_acc_ext=0.0,
6150  dmom_w_acc_w_ext=0.0,
6151  mass_adv_ext[nSpace],
6152  dmass_adv_u_ext[nSpace],
6153  dmass_adv_v_ext[nSpace],
6154  dmass_adv_w_ext[nSpace],
6155  mom_u_adv_ext[nSpace],
6156  dmom_u_adv_u_ext[nSpace],
6157  dmom_u_adv_v_ext[nSpace],
6158  dmom_u_adv_w_ext[nSpace],
6159  mom_v_adv_ext[nSpace],
6160  dmom_v_adv_u_ext[nSpace],
6161  dmom_v_adv_v_ext[nSpace],
6162  dmom_v_adv_w_ext[nSpace],
6163  mom_w_adv_ext[nSpace],
6164  dmom_w_adv_u_ext[nSpace],
6165  dmom_w_adv_v_ext[nSpace],
6166  dmom_w_adv_w_ext[nSpace],
6167  mom_uu_diff_ten_ext[nSpace],
6168  mom_vv_diff_ten_ext[nSpace],
6169  mom_ww_diff_ten_ext[nSpace],
6170  mom_uv_diff_ten_ext[1],
6171  mom_uw_diff_ten_ext[1],
6172  mom_vu_diff_ten_ext[1],
6173  mom_vw_diff_ten_ext[1],
6174  mom_wu_diff_ten_ext[1],
6175  mom_wv_diff_ten_ext[1],
6176  mom_u_source_ext=0.0,
6177  mom_v_source_ext=0.0,
6178  mom_w_source_ext=0.0,
6179  mom_u_ham_ext=0.0,
6180  dmom_u_ham_grad_p_ext[nSpace],
6181  dmom_u_ham_grad_u_ext[nSpace],
6182  mom_v_ham_ext=0.0,
6183  dmom_v_ham_grad_p_ext[nSpace],
6184  dmom_v_ham_grad_v_ext[nSpace],
6185  mom_w_ham_ext=0.0,
6186  dmom_w_ham_grad_p_ext[nSpace],
6187  dmom_w_ham_grad_w_ext[nSpace],
6188  dmom_u_adv_p_ext[nSpace],
6189  dmom_v_adv_p_ext[nSpace],
6190  dmom_w_adv_p_ext[nSpace],
6191  dflux_mass_u_ext=0.0,
6192  dflux_mass_v_ext=0.0,
6193  dflux_mass_w_ext=0.0,
6194  dflux_mom_u_adv_p_ext=0.0,
6195  dflux_mom_u_adv_u_ext=0.0,
6196  dflux_mom_u_adv_v_ext=0.0,
6197  dflux_mom_u_adv_w_ext=0.0,
6198  dflux_mom_v_adv_p_ext=0.0,
6199  dflux_mom_v_adv_u_ext=0.0,
6200  dflux_mom_v_adv_v_ext=0.0,
6201  dflux_mom_v_adv_w_ext=0.0,
6202  dflux_mom_w_adv_p_ext=0.0,
6203  dflux_mom_w_adv_u_ext=0.0,
6204  dflux_mom_w_adv_v_ext=0.0,
6205  dflux_mom_w_adv_w_ext=0.0,
6206  bc_p_ext=0.0,
6207  bc_u_ext=0.0,
6208  bc_v_ext=0.0,
6209  bc_w_ext=0.0,
6210  bc_mom_u_acc_ext=0.0,
6211  bc_dmom_u_acc_u_ext=0.0,
6212  bc_mom_v_acc_ext=0.0,
6213  bc_dmom_v_acc_v_ext=0.0,
6214  bc_mom_w_acc_ext=0.0,
6215  bc_dmom_w_acc_w_ext=0.0,
6216  bc_mass_adv_ext[nSpace],
6217  bc_dmass_adv_u_ext[nSpace],
6218  bc_dmass_adv_v_ext[nSpace],
6219  bc_dmass_adv_w_ext[nSpace],
6220  bc_mom_u_adv_ext[nSpace],
6221  bc_dmom_u_adv_u_ext[nSpace],
6222  bc_dmom_u_adv_v_ext[nSpace],
6223  bc_dmom_u_adv_w_ext[nSpace],
6224  bc_mom_v_adv_ext[nSpace],
6225  bc_dmom_v_adv_u_ext[nSpace],
6226  bc_dmom_v_adv_v_ext[nSpace],
6227  bc_dmom_v_adv_w_ext[nSpace],
6228  bc_mom_w_adv_ext[nSpace],
6229  bc_dmom_w_adv_u_ext[nSpace],
6230  bc_dmom_w_adv_v_ext[nSpace],
6231  bc_dmom_w_adv_w_ext[nSpace],
6232  bc_mom_uu_diff_ten_ext[nSpace],
6233  bc_mom_vv_diff_ten_ext[nSpace],
6234  bc_mom_ww_diff_ten_ext[nSpace],
6235  bc_mom_uv_diff_ten_ext[1],
6236  bc_mom_uw_diff_ten_ext[1],
6237  bc_mom_vu_diff_ten_ext[1],
6238  bc_mom_vw_diff_ten_ext[1],
6239  bc_mom_wu_diff_ten_ext[1],
6240  bc_mom_wv_diff_ten_ext[1],
6241  bc_mom_u_source_ext=0.0,
6242  bc_mom_v_source_ext=0.0,
6243  bc_mom_w_source_ext=0.0,
6244  bc_mom_u_ham_ext=0.0,
6245  bc_dmom_u_ham_grad_p_ext[nSpace],
6246  bc_dmom_u_ham_grad_u_ext[nSpace],
6247  bc_mom_v_ham_ext=0.0,
6248  bc_dmom_v_ham_grad_p_ext[nSpace],
6249  bc_dmom_v_ham_grad_v_ext[nSpace],
6250  bc_mom_w_ham_ext=0.0,
6251  bc_dmom_w_ham_grad_p_ext[nSpace],
6252  bc_dmom_w_ham_grad_w_ext[nSpace],
6253  fluxJacobian_p_p[nDOF_trial_element],
6254  fluxJacobian_p_u[nDOF_trial_element],
6255  fluxJacobian_p_v[nDOF_trial_element],
6256  fluxJacobian_p_w[nDOF_trial_element],
6257  fluxJacobian_u_p[nDOF_trial_element],
6258  fluxJacobian_u_u[nDOF_trial_element],
6259  fluxJacobian_u_v[nDOF_trial_element],
6260  fluxJacobian_u_w[nDOF_trial_element],
6261  fluxJacobian_v_p[nDOF_trial_element],
6262  fluxJacobian_v_u[nDOF_trial_element],
6263  fluxJacobian_v_v[nDOF_trial_element],
6264  fluxJacobian_v_w[nDOF_trial_element],
6265  fluxJacobian_w_p[nDOF_trial_element],
6266  fluxJacobian_w_u[nDOF_trial_element],
6267  fluxJacobian_w_v[nDOF_trial_element],
6268  fluxJacobian_w_w[nDOF_trial_element],
6269  jac_ext[nSpace*nSpace],
6270  jacDet_ext,
6271  jacInv_ext[nSpace*nSpace],
6272  boundaryJac[nSpace*(nSpace-1)],
6273  metricTensor[(nSpace-1)*(nSpace-1)],
6274  metricTensorDetSqrt,
6275  p_grad_trial_trace[nDOF_trial_element*nSpace],
6276  vel_grad_trial_trace[nDOF_trial_element*nSpace],
6277  dS,
6278  p_test_dS[nDOF_test_element],
6279  vel_test_dS[nDOF_test_element],
6280  normal[2],
6281  x_ext,y_ext,z_ext,xt_ext,yt_ext,zt_ext,integralScaling,
6282  vel_grad_test_dS[nDOF_trial_element*nSpace],
6283  //VRANS
6284  porosity_ext,
6285  //
6286  G[nSpace*nSpace],G_dd_G,tr_G,h_phi,h_penalty,penalty;
6287  ck.calculateMapping_elementBoundary(eN,
6288  ebN_local,
6289  kb,
6290  ebN_local_kb,
6291  mesh_dof.data(),
6292  mesh_l2g.data(),
6293  mesh_trial_trace_ref.data(),
6294  mesh_grad_trial_trace_ref.data(),
6295  boundaryJac_ref.data(),
6296  jac_ext,
6297  jacDet_ext,
6298  jacInv_ext,
6299  boundaryJac,
6300  metricTensor,
6301  metricTensorDetSqrt,
6302  normal_ref.data(),
6303  normal,
6304  x_ext,y_ext,z_ext);
6305  ck.calculateMappingVelocity_elementBoundary(eN,
6306  ebN_local,
6307  kb,
6308  ebN_local_kb,
6309  mesh_velocity_dof.data(),
6310  mesh_l2g.data(),
6311  mesh_trial_trace_ref.data(),
6312  xt_ext,yt_ext,zt_ext,
6313  normal,
6314  boundaryJac,
6315  metricTensor,
6316  integralScaling);
6317  //dS = ((1.0-MOVING_DOMAIN)*metricTensorDetSqrt + MOVING_DOMAIN*integralScaling)*dS_ref[kb];
6318  dS = metricTensorDetSqrt*dS_ref[kb];
6319  ck.calculateG(jacInv_ext,G,G_dd_G,tr_G);
6320  ck.calculateGScale(G,&ebqe_normal_phi_ext[ebNE_kb_nSpace],h_phi);
6321 
6322  eps_rho = epsFact_rho*(useMetrics*h_phi+(1.0-useMetrics)*elementDiameter[eN]);
6323  eps_mu = epsFact_mu *(useMetrics*h_phi+(1.0-useMetrics)*elementDiameter[eN]);
6324  const double particle_eps = particle_epsFact * (useMetrics * h_phi + (1.0 - useMetrics) * elementDiameter[eN]);
6325 
6326  //compute shape and solution information
6327  //shape
6328  /* ck.gradTrialFromRef(&p_grad_trial_trace_ref[ebN_local_kb_nSpace*nDOF_trial_element],jacInv_ext,p_grad_trial_trace); */
6329  ck.gradTrialFromRef(&vel_grad_trial_trace_ref[ebN_local_kb_nSpace*nDOF_trial_element],jacInv_ext,vel_grad_trial_trace);
6330  //solution and gradients
6331  /* ck.valFromDOF(p_dof,&p_l2g[eN_nDOF_trial_element],&p_trial_trace_ref[ebN_local_kb*nDOF_test_element],p_ext); */
6332  p_ext = ebqe_p[ebNE_kb];
6333  ck.valFromDOF(u_dof.data(),&vel_l2g[eN_nDOF_trial_element],&vel_trial_trace_ref[ebN_local_kb*nDOF_test_element],u_ext);
6334  ck.valFromDOF(v_dof.data(),&vel_l2g[eN_nDOF_trial_element],&vel_trial_trace_ref[ebN_local_kb*nDOF_test_element],v_ext);
6335  /* ck.valFromDOF(w_dof,&vel_l2g[eN_nDOF_trial_element],&vel_trial_trace_ref[ebN_local_kb*nDOF_test_element],w_ext); */
6336  /* ck.gradFromDOF(p_dof,&p_l2g[eN_nDOF_trial_element],p_grad_trial_trace,grad_p_ext); */
6337  for (int I=0;I<nSpace;I++)
6338  grad_p_ext[I] = ebqe_grad_p[ebNE_kb_nSpace+I];
6339  ck.gradFromDOF(u_dof.data(),&vel_l2g[eN_nDOF_trial_element],vel_grad_trial_trace,grad_u_ext);
6340  ck.gradFromDOF(v_dof.data(),&vel_l2g[eN_nDOF_trial_element],vel_grad_trial_trace,grad_v_ext);
6341  /* ck.gradFromDOF(w_dof,&vel_l2g[eN_nDOF_trial_element],vel_grad_trial_trace,grad_w_ext); */
6342  //precalculate test function products with integration weights
6343  for (int j=0;j<nDOF_trial_element;j++)
6344  {
6345  /* p_test_dS[j] = p_test_trace_ref[ebN_local_kb*nDOF_test_element+j]*dS; */
6346  vel_test_dS[j] = vel_test_trace_ref[ebN_local_kb*nDOF_test_element+j]*dS;
6347  for (int I=0;I<nSpace;I++)
6348  vel_grad_test_dS[j*nSpace+I] = vel_grad_trial_trace[j*nSpace+I]*dS;//cek hack, using trial
6349  }
6350  //
6351  //load the boundary values
6352  //
6353  bc_p_ext = isDOFBoundary_p[ebNE_kb]*ebqe_bc_p_ext[ebNE_kb]+(1-isDOFBoundary_p[ebNE_kb])*p_ext;
6354  //bc values at moving boundaries are specified relative to boundary motion so we need to add it here
6355  bc_u_ext = isDOFBoundary_u[ebNE_kb]*(ebqe_bc_u_ext[ebNE_kb] + MOVING_DOMAIN*xt_ext) + (1-isDOFBoundary_u[ebNE_kb])*u_ext;
6356  bc_v_ext = isDOFBoundary_v[ebNE_kb]*(ebqe_bc_v_ext[ebNE_kb] + MOVING_DOMAIN*yt_ext) + (1-isDOFBoundary_v[ebNE_kb])*v_ext;
6357  /* bc_w_ext = isDOFBoundary_w[ebNE_kb]*(ebqe_bc_w_ext[ebNE_kb] + MOVING_DOMAIN*zt_ext) + (1-isDOFBoundary_w[ebNE_kb])*w_ext; */
6358  //VRANS
6359  porosity_ext = 1.0 - ebqe_vos_ext[ebNE_kb];
6360  //
6361  //calculate the internal and external trace of the pde coefficients
6362  //
6363  double distance_to_omega_solid = 1e10;
6364  if (use_ball_as_particle == 1)
6365  {
6366  get_distance_to_ball(nParticles, ball_center.data(), ball_radius.data(), x_ext, y_ext, z_ext, distance_to_omega_solid);
6367  }
6368  else
6369  {
6370  distance_to_omega_solid = ebq_global_phi_solid[ebN*nQuadraturePoints_elementBoundary+kb];
6371  }
6372  double eddy_viscosity_ext(0.),bc_eddy_viscosity_ext(0.),rhoSave, nuSave;//not interested in saving boundary eddy viscosity for now
6373  evaluateCoefficients(eps_rho,
6374  eps_mu,
6375  particle_eps,
6376  sigma,
6377  rho_0,
6378  nu_0,
6379  rho_1,
6380  nu_1,
6381  elementDiameter[eN],
6382  smagorinskyConstant,
6383  turbulenceClosureModel,
6384  g.data(),
6385  useVF,
6386  ebqe_vf_ext[ebNE_kb],
6387  ebqe_phi_ext[ebNE_kb],
6388  &ebqe_normal_phi_ext[ebNE_kb_nSpace],
6389  distance_to_omega_solid,
6390  ebqe_kappa_phi_ext[ebNE_kb],
6391  //VRANS
6392  porosity_ext,
6393  //
6394  p_ext,
6395  grad_p_ext,
6396  grad_u_ext,
6397  grad_v_ext,
6398  grad_w_ext,
6399  u_ext,
6400  v_ext,
6401  w_ext,
6402  ebqe_velocity_star[ebNE_kb_nSpace+0],
6403  ebqe_velocity_star[ebNE_kb_nSpace+1],
6404  ebqe_velocity_star[ebNE_kb_nSpace+1],//hack,not used
6405  eddy_viscosity_ext,
6406  mom_u_acc_ext,
6407  dmom_u_acc_u_ext,
6408  mom_v_acc_ext,
6409  dmom_v_acc_v_ext,
6410  mom_w_acc_ext,
6411  dmom_w_acc_w_ext,
6412  mass_adv_ext,
6413  dmass_adv_u_ext,
6414  dmass_adv_v_ext,
6415  dmass_adv_w_ext,
6416  mom_u_adv_ext,
6417  dmom_u_adv_u_ext,
6418  dmom_u_adv_v_ext,
6419  dmom_u_adv_w_ext,
6420  mom_v_adv_ext,
6421  dmom_v_adv_u_ext,
6422  dmom_v_adv_v_ext,
6423  dmom_v_adv_w_ext,
6424  mom_w_adv_ext,
6425  dmom_w_adv_u_ext,
6426  dmom_w_adv_v_ext,
6427  dmom_w_adv_w_ext,
6428  mom_uu_diff_ten_ext,
6429  mom_vv_diff_ten_ext,
6430  mom_ww_diff_ten_ext,
6431  mom_uv_diff_ten_ext,
6432  mom_uw_diff_ten_ext,
6433  mom_vu_diff_ten_ext,
6434  mom_vw_diff_ten_ext,
6435  mom_wu_diff_ten_ext,
6436  mom_wv_diff_ten_ext,
6437  mom_u_source_ext,
6438  mom_v_source_ext,
6439  mom_w_source_ext,
6440  mom_u_ham_ext,
6441  dmom_u_ham_grad_p_ext,
6442  dmom_u_ham_grad_u_ext,
6443  mom_v_ham_ext,
6444  dmom_v_ham_grad_p_ext,
6445  dmom_v_ham_grad_v_ext,
6446  mom_w_ham_ext,
6447  dmom_w_ham_grad_p_ext,
6448  dmom_w_ham_grad_w_ext,
6449  rhoSave,
6450  nuSave,
6451  KILL_PRESSURE_TERM,
6452  0,
6453  0., // mql: zero force term at boundary
6454  0.,
6455  0.,
6456  MATERIAL_PARAMETERS_AS_FUNCTION,
6457  ebqe_density_as_function[ebNE_kb],
6458  ebqe_dynamic_viscosity_as_function[ebNE_kb],
6459  USE_SBM,
6460  x_ext,y_ext,z_ext,
6461  use_ball_as_particle,
6462  ball_center.data(),
6463  ball_radius.data(),
6464  ball_velocity.data(),
6465  ball_angular_velocity.data(),
6466  INT_BY_PARTS_PRESSURE);
6467  evaluateCoefficients(eps_rho,
6468  eps_mu,
6469  particle_eps,
6470  sigma,
6471  rho_0,
6472  nu_0,
6473  rho_1,
6474  nu_1,
6475  elementDiameter[eN],
6476  smagorinskyConstant,
6477  turbulenceClosureModel,
6478  g.data(),
6479  useVF,
6480  bc_ebqe_vf_ext[ebNE_kb],
6481  bc_ebqe_phi_ext[ebNE_kb],
6482  &ebqe_normal_phi_ext[ebNE_kb_nSpace],
6483  distance_to_omega_solid,
6484  ebqe_kappa_phi_ext[ebNE_kb],
6485  //VRANS
6486  porosity_ext,
6487  //
6488  bc_p_ext,
6489  grad_p_ext,
6490  grad_u_ext,
6491  grad_v_ext,
6492  grad_w_ext,
6493  bc_u_ext,
6494  bc_v_ext,
6495  bc_w_ext,
6496  ebqe_velocity_star[ebNE_kb_nSpace+0],
6497  ebqe_velocity_star[ebNE_kb_nSpace+1],
6498  ebqe_velocity_star[ebNE_kb_nSpace+1],//hack,not used
6499  bc_eddy_viscosity_ext,
6500  bc_mom_u_acc_ext,
6501  bc_dmom_u_acc_u_ext,
6502  bc_mom_v_acc_ext,
6503  bc_dmom_v_acc_v_ext,
6504  bc_mom_w_acc_ext,
6505  bc_dmom_w_acc_w_ext,
6506  bc_mass_adv_ext,
6507  bc_dmass_adv_u_ext,
6508  bc_dmass_adv_v_ext,
6509  bc_dmass_adv_w_ext,
6510  bc_mom_u_adv_ext,
6511  bc_dmom_u_adv_u_ext,
6512  bc_dmom_u_adv_v_ext,
6513  bc_dmom_u_adv_w_ext,
6514  bc_mom_v_adv_ext,
6515  bc_dmom_v_adv_u_ext,
6516  bc_dmom_v_adv_v_ext,
6517  bc_dmom_v_adv_w_ext,
6518  bc_mom_w_adv_ext,
6519  bc_dmom_w_adv_u_ext,
6520  bc_dmom_w_adv_v_ext,
6521  bc_dmom_w_adv_w_ext,
6522  bc_mom_uu_diff_ten_ext,
6523  bc_mom_vv_diff_ten_ext,
6524  bc_mom_ww_diff_ten_ext,
6525  bc_mom_uv_diff_ten_ext,
6526  bc_mom_uw_diff_ten_ext,
6527  bc_mom_vu_diff_ten_ext,
6528  bc_mom_vw_diff_ten_ext,
6529  bc_mom_wu_diff_ten_ext,
6530  bc_mom_wv_diff_ten_ext,
6531  bc_mom_u_source_ext,
6532  bc_mom_v_source_ext,
6533  bc_mom_w_source_ext,
6534  bc_mom_u_ham_ext,
6535  bc_dmom_u_ham_grad_p_ext,
6536  bc_dmom_u_ham_grad_u_ext,
6537  bc_mom_v_ham_ext,
6538  bc_dmom_v_ham_grad_p_ext,
6539  bc_dmom_v_ham_grad_v_ext,
6540  bc_mom_w_ham_ext,
6541  bc_dmom_w_ham_grad_p_ext,
6542  bc_dmom_w_ham_grad_w_ext,
6543  rhoSave,
6544  nuSave,
6545  KILL_PRESSURE_TERM,
6546  0,
6547  0., // mql: zero force term at boundary
6548  0.,
6549  0.,
6550  MATERIAL_PARAMETERS_AS_FUNCTION,
6551  ebqe_density_as_function[ebNE_kb],
6552  ebqe_dynamic_viscosity_as_function[ebNE_kb],
6553  USE_SBM,
6554  x_ext,y_ext,z_ext,
6555  use_ball_as_particle,
6556  ball_center.data(),
6557  ball_radius.data(),
6558  ball_velocity.data(),
6559  ball_angular_velocity.data(),
6560  INT_BY_PARTS_PRESSURE);
6561  //Turbulence closure model
6562  if (turbulenceClosureModel >= 3)
6563  {
6564  const double turb_var_grad_0_dummy[2] = {0.,0.};
6565  const double c_mu = 0.09;//mwf hack
6566  updateTurbulenceClosure(turbulenceClosureModel,
6567  eps_rho,
6568  eps_mu,
6569  rho_0,
6570  nu_0,
6571  rho_1,
6572  nu_1,
6573  useVF,
6574  ebqe_vf_ext[ebNE_kb],
6575  ebqe_phi_ext[ebNE_kb],
6576  porosity_ext,
6577  c_mu, //mwf hack
6578  ebqe_turb_var_0[ebNE_kb],
6579  ebqe_turb_var_1[ebNE_kb],
6580  turb_var_grad_0_dummy, //not needed
6581  eddy_viscosity_ext,
6582  mom_uu_diff_ten_ext,
6583  mom_vv_diff_ten_ext,
6584  mom_ww_diff_ten_ext,
6585  mom_uv_diff_ten_ext,
6586  mom_uw_diff_ten_ext,
6587  mom_vu_diff_ten_ext,
6588  mom_vw_diff_ten_ext,
6589  mom_wu_diff_ten_ext,
6590  mom_wv_diff_ten_ext,
6591  mom_u_source_ext,
6592  mom_v_source_ext,
6593  mom_w_source_ext);
6594 
6595  updateTurbulenceClosure(turbulenceClosureModel,
6596  eps_rho,
6597  eps_mu,
6598  rho_0,
6599  nu_0,
6600  rho_1,
6601  nu_1,
6602  useVF,
6603  ebqe_vf_ext[ebNE_kb],
6604  ebqe_phi_ext[ebNE_kb],
6605  porosity_ext,
6606  c_mu, //mwf hack
6607  ebqe_turb_var_0[ebNE_kb],
6608  ebqe_turb_var_1[ebNE_kb],
6609  turb_var_grad_0_dummy, //not needed
6610  bc_eddy_viscosity_ext,
6611  bc_mom_uu_diff_ten_ext,
6612  bc_mom_vv_diff_ten_ext,
6613  bc_mom_ww_diff_ten_ext,
6614  bc_mom_uv_diff_ten_ext,
6615  bc_mom_uw_diff_ten_ext,
6616  bc_mom_vu_diff_ten_ext,
6617  bc_mom_vw_diff_ten_ext,
6618  bc_mom_wu_diff_ten_ext,
6619  bc_mom_wv_diff_ten_ext,
6620  bc_mom_u_source_ext,
6621  bc_mom_v_source_ext,
6622  bc_mom_w_source_ext);
6623  }
6624  //
6625  //moving domain
6626  //
6627  mom_u_adv_ext[0] -= MOVING_DOMAIN*dmom_u_acc_u_ext*mom_u_acc_ext*xt_ext; //times rho*porosity. mql. CHECK.
6628  mom_u_adv_ext[1] -= MOVING_DOMAIN*dmom_u_acc_u_ext*mom_u_acc_ext*yt_ext;
6629  /* mom_u_adv_ext[2] -= MOVING_DOMAIN*dmom_u_acc_u_ext*mom_u_acc_ext*zt_ext; */
6630  dmom_u_adv_u_ext[0] -= MOVING_DOMAIN*dmom_u_acc_u_ext*xt_ext;
6631  dmom_u_adv_u_ext[1] -= MOVING_DOMAIN*dmom_u_acc_u_ext*yt_ext;
6632  /* dmom_u_adv_u_ext[2] -= MOVING_DOMAIN*dmom_u_acc_u_ext*zt_ext; */
6633 
6634  mom_v_adv_ext[0] -= MOVING_DOMAIN*dmom_v_acc_v_ext*mom_v_acc_ext*xt_ext;
6635  mom_v_adv_ext[1] -= MOVING_DOMAIN*dmom_v_acc_v_ext*mom_v_acc_ext*yt_ext;
6636  /* mom_v_adv_ext[2] -= MOVING_DOMAIN*dmom_v_acc_v_ext*mom_v_acc_ext*zt_ext; */
6637  dmom_v_adv_v_ext[0] -= MOVING_DOMAIN*dmom_v_acc_v_ext*xt_ext;
6638  dmom_v_adv_v_ext[1] -= MOVING_DOMAIN*dmom_v_acc_v_ext*yt_ext;
6639  /* dmom_v_adv_v_ext[2] -= MOVING_DOMAIN*dmom_v_acc_v_ext*zt_ext; */
6640 
6641  /* mom_w_adv_ext[0] -= MOVING_DOMAIN*dmom_w_acc_w_ext*mom_w_acc_ext*xt_ext; */
6642  /* mom_w_adv_ext[1] -= MOVING_DOMAIN*dmom_w_acc_w_ext*mom_w_acc_ext*yt_ext; */
6643  /* mom_w_adv_ext[2] -= MOVING_DOMAIN*dmom_w_acc_w_ext*mom_w_acc_ext*zt_ext; */
6644  /* dmom_w_adv_w_ext[0] -= MOVING_DOMAIN*dmom_w_acc_w_ext*xt_ext; */
6645  /* dmom_w_adv_w_ext[1] -= MOVING_DOMAIN*dmom_w_acc_w_ext*yt_ext; */
6646  /* dmom_w_adv_w_ext[2] -= MOVING_DOMAIN*dmom_w_acc_w_ext*zt_ext; */
6647 
6648  //moving domain bc's
6649  // mql. CHECK.
6650  bc_mom_u_adv_ext[0] -= MOVING_DOMAIN*dmom_u_acc_u_ext*bc_mom_u_acc_ext*xt_ext; //times rho*porosity
6651  bc_mom_u_adv_ext[1] -= MOVING_DOMAIN*dmom_u_acc_u_ext*bc_mom_u_acc_ext*yt_ext;
6652  /* bc_mom_u_adv_ext[2] -= MOVING_DOMAIN*dmom_u_acc_u_ext*bc_mom_u_acc_ext*zt_ext; */
6653 
6654  bc_mom_v_adv_ext[0] -= MOVING_DOMAIN*dmom_v_acc_v_ext*bc_mom_v_acc_ext*xt_ext;
6655  bc_mom_v_adv_ext[1] -= MOVING_DOMAIN*dmom_v_acc_v_ext*bc_mom_v_acc_ext*yt_ext;
6656  /* bc_mom_v_adv_ext[2] -= MOVING_DOMAIN*dmom_v_acc_v_ext*bc_mom_v_acc_ext*zt_ext; */
6657 
6658  /* bc_mom_w_adv_ext[0] -= MOVING_DOMAIN*dmom_w_acc_w_ext*bc_mom_w_acc_ext*xt_ext; */
6659  /* bc_mom_w_adv_ext[1] -= MOVING_DOMAIN*dmom_w_acc_w_ext*bc_mom_w_acc_ext*yt_ext; */
6660  /* bc_mom_w_adv_ext[2] -= MOVING_DOMAIN*dmom_w_acc_w_ext*bc_mom_w_acc_ext*zt_ext; */
6661  //
6662  //calculate the numerical fluxes
6663  //
6664  exteriorNumericalAdvectiveFluxDerivatives(isDOFBoundary_p[ebNE_kb],
6665  isDOFBoundary_u[ebNE_kb],
6666  isDOFBoundary_v[ebNE_kb],
6667  isDOFBoundary_w[ebNE_kb],
6668  isAdvectiveFluxBoundary_p[ebNE_kb],
6669  isAdvectiveFluxBoundary_u[ebNE_kb],
6670  isAdvectiveFluxBoundary_v[ebNE_kb],
6671  isAdvectiveFluxBoundary_w[ebNE_kb],
6672  dmom_u_ham_grad_p_ext[0],//=1/rho
6673  normal,
6674  porosity_ext*dmom_u_acc_u_ext, //multiply by rho. mql. CHECK.
6675  bc_p_ext,
6676  bc_u_ext,
6677  bc_v_ext,
6678  bc_w_ext,
6679  bc_mass_adv_ext,
6680  bc_mom_u_adv_ext,
6681  bc_mom_v_adv_ext,
6682  bc_mom_w_adv_ext,
6683  ebqe_bc_flux_mass_ext[ebNE_kb]+MOVING_DOMAIN*(xt_ext*normal[0]+yt_ext*normal[1]),//bc is relative mass flux
6684  ebqe_bc_flux_mom_u_adv_ext[ebNE_kb],
6685  ebqe_bc_flux_mom_v_adv_ext[ebNE_kb],
6686  ebqe_bc_flux_mom_w_adv_ext[ebNE_kb],
6687  p_ext,
6688  u_ext,
6689  v_ext,
6690  w_ext,
6691  mass_adv_ext,
6692  mom_u_adv_ext,
6693  mom_v_adv_ext,
6694  mom_w_adv_ext,
6695  dmass_adv_u_ext,
6696  dmass_adv_v_ext,
6697  dmass_adv_w_ext,
6698  dmom_u_adv_p_ext,
6699  dmom_u_adv_u_ext,
6700  dmom_u_adv_v_ext,
6701  dmom_u_adv_w_ext,
6702  dmom_v_adv_p_ext,
6703  dmom_v_adv_u_ext,
6704  dmom_v_adv_v_ext,
6705  dmom_v_adv_w_ext,
6706  dmom_w_adv_p_ext,
6707  dmom_w_adv_u_ext,
6708  dmom_w_adv_v_ext,
6709  dmom_w_adv_w_ext,
6710  dflux_mass_u_ext,
6711  dflux_mass_v_ext,
6712  dflux_mass_w_ext,
6713  dflux_mom_u_adv_p_ext,
6714  dflux_mom_u_adv_u_ext,
6715  dflux_mom_u_adv_v_ext,
6716  dflux_mom_u_adv_w_ext,
6717  dflux_mom_v_adv_p_ext,
6718  dflux_mom_v_adv_u_ext,
6719  dflux_mom_v_adv_v_ext,
6720  dflux_mom_v_adv_w_ext,
6721  dflux_mom_w_adv_p_ext,
6722  dflux_mom_w_adv_u_ext,
6723  dflux_mom_w_adv_v_ext,
6724  dflux_mom_w_adv_w_ext,
6725  &ebqe_velocity_star[ebNE_kb_nSpace]);
6726  //
6727  //calculate the flux jacobian
6728  //
6729  ck.calculateGScale(G,normal,h_penalty);
6730  penalty = useMetrics*C_b/h_penalty + (1.0-useMetrics)*ebqe_penalty_ext[ebNE_kb];
6731  for (int j=0;j<nDOF_trial_element;j++)
6732  {
6733  register int j_nSpace = j*nSpace,ebN_local_kb_j=ebN_local_kb*nDOF_trial_element+j;
6734  /* fluxJacobian_p_p[j]=0.0; */
6735  /* fluxJacobian_p_u[j]=ck.ExteriorNumericalAdvectiveFluxJacobian(dflux_mass_u_ext,vel_trial_trace_ref[ebN_local_kb_j]); */
6736  /* fluxJacobian_p_v[j]=ck.ExteriorNumericalAdvectiveFluxJacobian(dflux_mass_v_ext,vel_trial_trace_ref[ebN_local_kb_j]); */
6737  /* fluxJacobian_p_w[j]=ck.ExteriorNumericalAdvectiveFluxJacobian(dflux_mass_w_ext,vel_trial_trace_ref[ebN_local_kb_j]); */
6738 
6739  /* fluxJacobian_u_p[j]=ck.ExteriorNumericalAdvectiveFluxJacobian(dflux_mom_u_adv_p_ext,p_trial_trace_ref[ebN_local_kb_j]); */
6740  fluxJacobian_u_u[j] =
6741  ck.ExteriorNumericalAdvectiveFluxJacobian(dflux_mom_u_adv_u_ext,vel_trial_trace_ref[ebN_local_kb_j]) +
6743  ebqe_phi_ext[ebNE_kb],
6744  sdInfo_u_u_rowptr.data(),
6745  sdInfo_u_u_colind.data(),
6746  isDOFBoundary_u[ebNE_kb],
6747  isDiffusiveFluxBoundary_u[ebNE_kb],
6748  normal,
6749  mom_uu_diff_ten_ext,
6750  vel_trial_trace_ref[ebN_local_kb_j],
6751  &vel_grad_trial_trace[j_nSpace],
6752  penalty);//ebqe_penalty_ext[ebNE_kb]);
6753  fluxJacobian_u_v[j]=
6754  ck.ExteriorNumericalAdvectiveFluxJacobian(dflux_mom_u_adv_v_ext,vel_trial_trace_ref[ebN_local_kb_j]) +
6756  ebqe_phi_ext[ebNE_kb],
6757  sdInfo_u_v_rowptr.data(),
6758  sdInfo_u_v_colind.data(),
6759  isDOFBoundary_v[ebNE_kb],
6760  isDiffusiveFluxBoundary_v[ebNE_kb],
6761  normal,
6762  mom_uv_diff_ten_ext,
6763  vel_trial_trace_ref[ebN_local_kb_j],
6764  &vel_grad_trial_trace[j_nSpace],
6765  penalty);//ebqe_penalty_ext[ebNE_kb]);
6766  /*fluxJacobian_u_w[j]=
6767  ck.ExteriorNumericalAdvectiveFluxJacobian(dflux_mom_u_adv_w_ext,vel_trial_trace_ref[ebN_local_kb_j])+*/
6768  /* ExteriorNumericalDiffusiveFluxJacobian(eps_rho, */
6769  /* ebqe_phi_ext[ebNE_kb], */
6770  /* sdInfo_u_w_rowptr, */
6771  /* sdInfo_u_w_colind, */
6772  /* isDOFBoundary_w[ebNE_kb], */
6773  /* isDiffusiveFluxBoundary_u[ebNE_kb], */
6774  /* normal, */
6775  /* mom_uw_diff_ten_ext, */
6776  /* vel_trial_trace_ref[ebN_local_kb_j], */
6777  /* &vel_grad_trial_trace[j_nSpace], */
6778  /* penalty);//ebqe_penalty_ext[ebNE_kb]); */
6779 
6780  /* fluxJacobian_v_p[j]=ck.ExteriorNumericalAdvectiveFluxJacobian(dflux_mom_v_adv_p_ext,p_trial_trace_ref[ebN_local_kb_j]); */
6781  fluxJacobian_v_u[j]=
6782  ck.ExteriorNumericalAdvectiveFluxJacobian(dflux_mom_v_adv_u_ext,vel_trial_trace_ref[ebN_local_kb_j]) +
6784  ebqe_phi_ext[ebNE_kb],
6785  sdInfo_v_u_rowptr.data(),
6786  sdInfo_v_u_colind.data(),
6787  isDOFBoundary_u[ebNE_kb],
6788  isDiffusiveFluxBoundary_u[ebNE_kb],
6789  normal,
6790  mom_vu_diff_ten_ext,
6791  vel_trial_trace_ref[ebN_local_kb_j],
6792  &vel_grad_trial_trace[j_nSpace],
6793  penalty);//ebqe_penalty_ext[ebNE_kb]);
6794  fluxJacobian_v_v[j]=
6795  ck.ExteriorNumericalAdvectiveFluxJacobian(dflux_mom_v_adv_v_ext,vel_trial_trace_ref[ebN_local_kb_j]) +
6797  ebqe_phi_ext[ebNE_kb],
6798  sdInfo_v_v_rowptr.data(),
6799  sdInfo_v_v_colind.data(),
6800  isDOFBoundary_v[ebNE_kb],
6801  isDiffusiveFluxBoundary_v[ebNE_kb],
6802  normal,
6803  mom_vv_diff_ten_ext,
6804  vel_trial_trace_ref[ebN_local_kb_j],
6805  &vel_grad_trial_trace[j_nSpace],
6806  penalty);//ebqe_penalty_ext[ebNE_kb]);
6807  /* fluxJacobian_v_w[j]=
6808  ck.ExteriorNumericalAdvectiveFluxJacobian(dflux_mom_v_adv_w_ext,vel_trial_trace_ref[ebN_local_kb_j]) + */
6809  /* ExteriorNumericalDiffusiveFluxJacobian(eps_rho, */
6810  /* ebqe_phi_ext[ebNE_kb], */
6811  /* sdInfo_v_w_rowptr, */
6812  /* sdInfo_v_w_colind, */
6813  /* isDOFBoundary_w[ebNE_kb], */
6814  /* isDiffusiveFluxBoundary_v[ebNE_kb], */
6815  /* normal, */
6816  /* mom_vw_diff_ten_ext, */
6817  /* vel_trial_trace_ref[ebN_local_kb_j], */
6818  /* &vel_grad_trial_trace[j_nSpace], */
6819  /* penalty);//ebqe_penalty_ext[ebNE_kb]); */
6820 
6821  /* fluxJacobian_w_p[j]=ck.ExteriorNumericalAdvectiveFluxJacobian(dflux_mom_w_adv_p_ext,p_trial_trace_ref[ebN_local_kb_j]); */
6822  /* fluxJacobian_w_u[j]=ck.ExteriorNumericalAdvectiveFluxJacobian(dflux_mom_w_adv_u_ext,vel_trial_trace_ref[ebN_local_kb_j]) + */
6823  /* ExteriorNumericalDiffusiveFluxJacobian(eps_rho, */
6824  /* ebqe_phi_ext[ebNE_kb], */
6825  /* sdInfo_w_u_rowptr, */
6826  /* sdInfo_w_u_colind, */
6827  /* isDOFBoundary_u[ebNE_kb], */
6828  /* isDiffusiveFluxBoundary_w[ebNE_kb], */
6829  /* normal, */
6830  /* mom_wu_diff_ten_ext, */
6831  /* vel_trial_trace_ref[ebN_local_kb_j], */
6832  /* &vel_grad_trial_trace[j_nSpace], */
6833  /* penalty);//ebqe_penalty_ext[ebNE_kb]); */
6834  /* fluxJacobian_w_v[j]=ck.ExteriorNumericalAdvectiveFluxJacobian(dflux_mom_w_adv_v_ext,vel_trial_trace_ref[ebN_local_kb_j]) + */
6835  /* ExteriorNumericalDiffusiveFluxJacobian(eps_rho, */
6836  /* ebqe_phi_ext[ebNE_kb], */
6837  /* sdInfo_w_v_rowptr, */
6838  /* sdInfo_w_v_colind, */
6839  /* isDOFBoundary_v[ebNE_kb], */
6840  /* isDiffusiveFluxBoundary_w[ebNE_kb], */
6841  /* normal, */
6842  /* mom_wv_diff_ten_ext, */
6843  /* vel_trial_trace_ref[ebN_local_kb_j], */
6844  /* &vel_grad_trial_trace[j_nSpace], */
6845  /* penalty);//ebqe_penalty_ext[ebNE_kb]); */
6846  /* fluxJacobian_w_w[j]=ck.ExteriorNumericalAdvectiveFluxJacobian(dflux_mom_w_adv_w_ext,vel_trial_trace_ref[ebN_local_kb_j]) + */
6847  /* ExteriorNumericalDiffusiveFluxJacobian(eps_rho, */
6848  /* ebqe_phi_ext[ebNE_kb], */
6849  /* sdInfo_w_w_rowptr, */
6850  /* sdInfo_w_w_colind, */
6851  /* isDOFBoundary_w[ebNE_kb], */
6852  /* isDiffusiveFluxBoundary_w[ebNE_kb], */
6853  /* normal, */
6854  /* mom_ww_diff_ten_ext, */
6855  /* vel_trial_trace_ref[ebN_local_kb_j], */
6856  /* &vel_grad_trial_trace[j_nSpace], */
6857  /* penalty);//ebqe_penalty_ext[ebNE_kb]); */
6858  }//j
6859  //
6860  //update the global Jacobian from the flux Jacobian
6861  //
6862  for (int i=0;i<nDOF_test_element;i++)
6863  {
6864  register int eN_i = eN*nDOF_test_element+i;
6865  for (int j=0;j<nDOF_trial_element;j++)
6866  {
6867  register int ebN_i_j = ebN*4*nDOF_test_X_trial_element + i*nDOF_trial_element + j,ebN_local_kb_j=ebN_local_kb*nDOF_trial_element+j;
6868 
6869  /* globalJacobian[csrRowIndeces_p_p[eN_i] + csrColumnOffsets_eb_p_p[ebN_i_j]] += fluxJacobian_p_p[j]*p_test_dS[i]; */
6870  /* globalJacobian[csrRowIndeces_p_u[eN_i] + csrColumnOffsets_eb_p_u[ebN_i_j]] += fluxJacobian_p_u[j]*p_test_dS[i]; */
6871  /* globalJacobian[csrRowIndeces_p_v[eN_i] + csrColumnOffsets_eb_p_v[ebN_i_j]] += fluxJacobian_p_v[j]*p_test_dS[i]; */
6872  /* globalJacobian[csrRowIndeces_p_w[eN_i] + csrColumnOffsets_eb_p_w[ebN_i_j]] += fluxJacobian_p_w[j]*p_test_dS[i]; */
6873 
6874  /* globalJacobian[csrRowIndeces_u_p[eN_i] + csrColumnOffsets_eb_u_p[ebN_i_j]] += fluxJacobian_u_p[j]*vel_test_dS[i]; */
6875  globalJacobian[csrRowIndeces_u_u[eN_i] + csrColumnOffsets_eb_u_u[ebN_i_j]] += fluxJacobian_u_u[j]*vel_test_dS[i]+
6876  ck.ExteriorElementBoundaryDiffusionAdjointJacobian(isDOFBoundary_u[ebNE_kb],
6877  isDiffusiveFluxBoundary_u[ebNE_kb],
6878  eb_adjoint_sigma,
6879  vel_trial_trace_ref[ebN_local_kb_j],
6880  normal,
6881  sdInfo_u_u_rowptr.data(),
6882  sdInfo_u_u_colind.data(),
6883  mom_uu_diff_ten_ext,
6884  &vel_grad_test_dS[i*nSpace]);
6885  globalJacobian[csrRowIndeces_u_v[eN_i] + csrColumnOffsets_eb_u_v[ebN_i_j]] += fluxJacobian_u_v[j]*vel_test_dS[i]+
6886  ck.ExteriorElementBoundaryDiffusionAdjointJacobian(isDOFBoundary_v[ebNE_kb],
6887  isDiffusiveFluxBoundary_u[ebNE_kb],
6888  eb_adjoint_sigma,
6889  vel_trial_trace_ref[ebN_local_kb_j],
6890  normal,
6891  sdInfo_u_v_rowptr.data(),
6892  sdInfo_u_v_colind.data(),
6893  mom_uv_diff_ten_ext,
6894  &vel_grad_test_dS[i*nSpace]);
6895  /* globalJacobian[csrRowIndeces_u_w[eN_i] + csrColumnOffsets_eb_u_w[ebN_i_j]] += fluxJacobian_u_w[j]*vel_test_dS[i]+ */
6896  /* ck.ExteriorElementBoundaryDiffusionAdjointJacobian(isDOFBoundary_w[ebNE_kb], */
6897  /* isDiffusiveFluxBoundary_u[ebNE_kb], */
6898  /* eb_adjoint_sigma, */
6899  /* vel_trial_trace_ref[ebN_local_kb_j], */
6900  /* normal, */
6901  /* sdInfo_u_w_rowptr, */
6902  /* sdInfo_u_w_colind, */
6903  /* mom_uw_diff_ten_ext, */
6904  /* &vel_grad_test_dS[i*nSpace]); */
6905 
6906  /* globalJacobian[csrRowIndeces_v_p[eN_i] + csrColumnOffsets_eb_v_p[ebN_i_j]] += fluxJacobian_v_p[j]*vel_test_dS[i]; */
6907  globalJacobian[csrRowIndeces_v_u[eN_i] + csrColumnOffsets_eb_v_u[ebN_i_j]] += fluxJacobian_v_u[j]*vel_test_dS[i]+
6908  ck.ExteriorElementBoundaryDiffusionAdjointJacobian(isDOFBoundary_u[ebNE_kb],
6909  isDiffusiveFluxBoundary_v[ebNE_kb],
6910  eb_adjoint_sigma,
6911  vel_trial_trace_ref[ebN_local_kb_j],
6912  normal,
6913  sdInfo_v_u_rowptr.data(),
6914  sdInfo_v_u_colind.data(),
6915  mom_vu_diff_ten_ext,
6916  &vel_grad_test_dS[i*nSpace]);
6917  globalJacobian[csrRowIndeces_v_v[eN_i] + csrColumnOffsets_eb_v_v[ebN_i_j]] += fluxJacobian_v_v[j]*vel_test_dS[i]+
6918  ck.ExteriorElementBoundaryDiffusionAdjointJacobian(isDOFBoundary_v[ebNE_kb],
6919  isDiffusiveFluxBoundary_v[ebNE_kb],
6920  eb_adjoint_sigma,
6921  vel_trial_trace_ref[ebN_local_kb_j],
6922  normal,
6923  sdInfo_v_v_rowptr.data(),
6924  sdInfo_v_v_colind.data(),
6925  mom_vv_diff_ten_ext,
6926  &vel_grad_test_dS[i*nSpace]);
6927  /* globalJacobian[csrRowIndeces_v_w[eN_i] + csrColumnOffsets_eb_v_w[ebN_i_j]] += fluxJacobian_v_w[j]*vel_test_dS[i]+ */
6928  /* ck.ExteriorElementBoundaryDiffusionAdjointJacobian(isDOFBoundary_w[ebNE_kb], */
6929  /* isDiffusiveFluxBoundary_v[ebNE_kb], */
6930  /* eb_adjoint_sigma, */
6931  /* vel_trial_trace_ref[ebN_local_kb_j], */
6932  /* normal, */
6933  /* sdInfo_v_w_rowptr, */
6934  /* sdInfo_v_w_colind, */
6935  /* mom_vw_diff_ten_ext, */
6936  /* &vel_grad_test_dS[i*nSpace]); */
6937 
6938  /* globalJacobian[csrRowIndeces_w_p[eN_i] + csrColumnOffsets_eb_w_p[ebN_i_j]] += fluxJacobian_w_p[j]*vel_test_dS[i]; */
6939  /* globalJacobian[csrRowIndeces_w_u[eN_i] + csrColumnOffsets_eb_w_u[ebN_i_j]] += fluxJacobian_w_u[j]*vel_test_dS[i]+ */
6940  /* ck.ExteriorElementBoundaryDiffusionAdjointJacobian(isDOFBoundary_u[ebNE_kb], */
6941  /* isDiffusiveFluxBoundary_w[ebNE_kb], */
6942  /* eb_adjoint_sigma, */
6943  /* vel_trial_trace_ref[ebN_local_kb_j], */
6944  /* normal, */
6945  /* sdInfo_w_u_rowptr, */
6946  /* sdInfo_w_u_colind, */
6947  /* mom_wu_diff_ten_ext, */
6948  /* &vel_grad_test_dS[i*nSpace]); */
6949  /* globalJacobian[csrRowIndeces_w_v[eN_i] + csrColumnOffsets_eb_w_v[ebN_i_j]] += fluxJacobian_w_v[j]*vel_test_dS[i]+ */
6950  /* ck.ExteriorElementBoundaryDiffusionAdjointJacobian(isDOFBoundary_v[ebNE_kb], */
6951  /* isDiffusiveFluxBoundary_w[ebNE_kb], */
6952  /* eb_adjoint_sigma, */
6953  /* vel_trial_trace_ref[ebN_local_kb_j], */
6954  /* normal, */
6955  /* sdInfo_w_v_rowptr, */
6956  /* sdInfo_w_v_colind, */
6957  /* mom_wv_diff_ten_ext, */
6958  /* &vel_grad_test_dS[i*nSpace]); */
6959  /* globalJacobian[csrRowIndeces_w_w[eN_i] + csrColumnOffsets_eb_w_w[ebN_i_j]] += fluxJacobian_w_w[j]*vel_test_dS[i]+ */
6960  /* ck.ExteriorElementBoundaryDiffusionAdjointJacobian(isDOFBoundary_w[ebNE_kb], */
6961  /* isDiffusiveFluxBoundary_w[ebNE_kb], */
6962  /* eb_adjoint_sigma, */
6963  /* vel_trial_trace_ref[ebN_local_kb_j], */
6964  /* normal, */
6965  /* sdInfo_w_w_rowptr, */
6966  /* sdInfo_w_w_colind, */
6967  /* mom_ww_diff_ten_ext, */
6968  /* &vel_grad_test_dS[i*nSpace]); */
6969  }//j
6970  }//i
6971  }//kb
6972  }//ebNE
6973  gf.useExact=useExact;
6974  gf_s.useExact=useExact;
6975  }//computeJacobian
6976 
6978  {
6979  int nExteriorElementBoundaries_global = args.scalar<int>("nExteriorElementBoundaries_global");
6980  xt::pyarray<int>& exteriorElementBoundariesArray = args.array<int>("exteriorElementBoundariesArray");
6981  int nInteriorElementBoundaries_global = args.scalar<int>("nInteriorElementBoundaries_global");
6982  xt::pyarray<int>& interiorElementBoundariesArray = args.array<int>("interiorElementBoundariesArray");
6983  xt::pyarray<int>& elementBoundaryElementsArray = args.array<int>("elementBoundaryElementsArray");
6984  xt::pyarray<int>& elementBoundaryLocalElementBoundariesArray = args.array<int>("elementBoundaryLocalElementBoundariesArray");
6985  xt::pyarray<double>& mesh_dof = args.array<double>("mesh_dof");
6986  xt::pyarray<double>& mesh_velocity_dof = args.array<double>("mesh_velocity_dof");
6987  double MOVING_DOMAIN = args.scalar<double>("MOVING_DOMAIN");
6988  xt::pyarray<int>& mesh_l2g = args.array<int>("mesh_l2g");
6989  xt::pyarray<double>& mesh_trial_trace_ref = args.array<double>("mesh_trial_trace_ref");
6990  xt::pyarray<double>& mesh_grad_trial_trace_ref = args.array<double>("mesh_grad_trial_trace_ref");
6991  xt::pyarray<double>& normal_ref = args.array<double>("normal_ref");
6992  xt::pyarray<double>& boundaryJac_ref = args.array<double>("boundaryJac_ref");
6993  xt::pyarray<int>& vel_l2g = args.array<int>("vel_l2g");
6994  xt::pyarray<double>& u_dof = args.array<double>("u_dof");
6995  xt::pyarray<double>& v_dof = args.array<double>("v_dof");
6996  xt::pyarray<double>& w_dof = args.array<double>("w_dof");
6997  xt::pyarray<double>& vos_dof = args.array<double>("vos_dof");
6998  xt::pyarray<double>& vel_trial_trace_ref = args.array<double>("vel_trial_trace_ref");
6999  xt::pyarray<double>& ebqe_velocity = args.array<double>("ebqe_velocity");
7000  xt::pyarray<double>& velocityAverage = args.array<double>("velocityAverage");
7001  int permutations[nQuadraturePoints_elementBoundary];
7002  double xArray_left[nQuadraturePoints_elementBoundary*2],
7003  xArray_right[nQuadraturePoints_elementBoundary*2];
7004  for (int i=0;i<nQuadraturePoints_elementBoundary;i++)
7005  permutations[i]=i;//just to initialize
7006  for (int ebNE = 0; ebNE < nExteriorElementBoundaries_global; ebNE++)
7007  {
7008  register int ebN = exteriorElementBoundariesArray[ebNE];
7009  for (int kb=0;kb<nQuadraturePoints_elementBoundary;kb++)
7010  {
7011  register int ebN_kb_nSpace = ebN*nQuadraturePoints_elementBoundary*nSpace+kb*nSpace,
7012  ebNE_kb_nSpace = ebNE*nQuadraturePoints_elementBoundary*nSpace+kb*nSpace;
7013  velocityAverage[ebN_kb_nSpace+0]=ebqe_velocity[ebNE_kb_nSpace+0];
7014  velocityAverage[ebN_kb_nSpace+1]=ebqe_velocity[ebNE_kb_nSpace+1];
7015  }//ebNE
7016  }
7017  for (int ebNI = 0; ebNI < nInteriorElementBoundaries_global; ebNI++)
7018  {
7019  register int ebN = interiorElementBoundariesArray[ebNI],
7020  left_eN_global = elementBoundaryElementsArray[ebN*2+0],
7021  left_ebN_element = elementBoundaryLocalElementBoundariesArray[ebN*2+0],
7022  right_eN_global = elementBoundaryElementsArray[ebN*2+1],
7023  right_ebN_element = elementBoundaryLocalElementBoundariesArray[ebN*2+1],
7024  left_eN_nDOF_trial_element = left_eN_global*nDOF_trial_element,
7025  right_eN_nDOF_trial_element = right_eN_global*nDOF_trial_element;
7026  double jac[nSpace*nSpace],
7027  jacDet,
7028  jacInv[nSpace*nSpace],
7029  boundaryJac[nSpace*(nSpace-1)],
7030  metricTensor[(nSpace-1)*(nSpace-1)],
7031  metricTensorDetSqrt,
7032  normal[2],
7033  x,y,z,
7034  xt,yt,zt,integralScaling;
7035 
7036  for (int kb=0;kb<nQuadraturePoints_elementBoundary;kb++)
7037  {
7038  ck.calculateMapping_elementBoundary(left_eN_global,
7039  left_ebN_element,
7040  kb,
7041  left_ebN_element*nQuadraturePoints_elementBoundary+kb,
7042  mesh_dof.data(),
7043  mesh_l2g.data(),
7044  mesh_trial_trace_ref.data(),
7045  mesh_grad_trial_trace_ref.data(),
7046  boundaryJac_ref.data(),
7047  jac,
7048  jacDet,
7049  jacInv,
7050  boundaryJac,
7051  metricTensor,
7052  metricTensorDetSqrt,
7053  normal_ref.data(),
7054  normal,
7055  x,y,z);
7056  xArray_left[kb*2+0] = x;
7057  xArray_left[kb*2+1] = y;
7058  /* xArray_left[kb*3+2] = z; */
7059  ck.calculateMapping_elementBoundary(right_eN_global,
7060  right_ebN_element,
7061  kb,
7062  right_ebN_element*nQuadraturePoints_elementBoundary+kb,
7063  mesh_dof.data(),
7064  mesh_l2g.data(),
7065  mesh_trial_trace_ref.data(),
7066  mesh_grad_trial_trace_ref.data(),
7067  boundaryJac_ref.data(),
7068  jac,
7069  jacDet,
7070  jacInv,
7071  boundaryJac,
7072  metricTensor,
7073  metricTensorDetSqrt,
7074  normal_ref.data(),
7075  normal,
7076  x,y,z);
7077  ck.calculateMappingVelocity_elementBoundary(left_eN_global,
7078  left_ebN_element,
7079  kb,
7080  left_ebN_element*nQuadraturePoints_elementBoundary+kb,
7081  mesh_velocity_dof.data(),
7082  mesh_l2g.data(),
7083  mesh_trial_trace_ref.data(),
7084  xt,yt,zt,
7085  normal,
7086  boundaryJac,
7087  metricTensor,
7088  integralScaling);
7089  xArray_right[kb*2+0] = x;
7090  xArray_right[kb*2+1] = y;
7091  /* xArray_right[kb*3+2] = z; */
7092  }
7093  for (int kb_left=0;kb_left<nQuadraturePoints_elementBoundary;kb_left++)
7094  {
7095  double errorNormMin = 1.0;
7096  for (int kb_right=0;kb_right<nQuadraturePoints_elementBoundary;kb_right++)
7097  {
7098  double errorNorm=0.0;
7099  for (int I=0;I<nSpace;I++)
7100  {
7101  errorNorm += fabs(xArray_left[kb_left*2+I]
7102  -
7103  xArray_right[kb_right*2+I]);
7104  }
7105  if (errorNorm < errorNormMin)
7106  {
7107  permutations[kb_right] = kb_left;
7108  errorNormMin = errorNorm;
7109  }
7110  }
7111  }
7112  for (int kb=0;kb<nQuadraturePoints_elementBoundary;kb++)
7113  {
7114  register int ebN_kb_nSpace = ebN*nQuadraturePoints_elementBoundary*nSpace+kb*nSpace;
7115  register double u_left=0.0,
7116  v_left=0.0,
7117  w_left=0.0,
7118  u_right=0.0,
7119  v_right=0.0,
7120  w_right=0.0,
7121  vos_left=0.0,
7122  vos_right=0.0,
7123  porosity_left=0.0,
7124  porosity_right=0.0;
7125  register int left_kb = kb,
7126  right_kb = permutations[kb],
7127  left_ebN_element_kb_nDOF_test_element=(left_ebN_element*nQuadraturePoints_elementBoundary+left_kb)*nDOF_test_element,
7128  right_ebN_element_kb_nDOF_test_element=(right_ebN_element*nQuadraturePoints_elementBoundary+right_kb)*nDOF_test_element;
7129  //
7130  //calculate the velocity solution at quadrature points on left and right
7131  //
7132  ck.valFromDOF(vos_dof.data(),&vel_l2g[left_eN_nDOF_trial_element],&vel_trial_trace_ref[left_ebN_element_kb_nDOF_test_element],vos_left);
7133  ck.valFromDOF(u_dof.data(),&vel_l2g[left_eN_nDOF_trial_element],&vel_trial_trace_ref[left_ebN_element_kb_nDOF_test_element],u_left);
7134  ck.valFromDOF(v_dof.data(),&vel_l2g[left_eN_nDOF_trial_element],&vel_trial_trace_ref[left_ebN_element_kb_nDOF_test_element],v_left);
7135  /* ck.valFromDOF(w_dof,&vel_l2g[left_eN_nDOF_trial_element],&vel_trial_trace_ref[left_ebN_element_kb_nDOF_test_element],w_left); */
7136  //
7137  ck.valFromDOF(vos_dof.data(),&vel_l2g[right_eN_nDOF_trial_element],&vel_trial_trace_ref[right_ebN_element_kb_nDOF_test_element],vos_right);
7138  ck.valFromDOF(u_dof.data(),&vel_l2g[right_eN_nDOF_trial_element],&vel_trial_trace_ref[right_ebN_element_kb_nDOF_test_element],u_right);
7139  ck.valFromDOF(v_dof.data(),&vel_l2g[right_eN_nDOF_trial_element],&vel_trial_trace_ref[right_ebN_element_kb_nDOF_test_element],v_right);
7140  /* ck.valFromDOF(w_dof,&vel_l2g[right_eN_nDOF_trial_element],&vel_trial_trace_ref[right_ebN_element_kb_nDOF_test_element],w_right); */
7141  //
7142  /* porosity_left = 1.0 - vos_left; */
7143  /* porosity_right = 1.0 - vos_right; */
7144  velocityAverage[ebN_kb_nSpace+0]=0.5*(u_left + u_right);
7145  velocityAverage[ebN_kb_nSpace+1]=0.5*(v_left + v_right);
7146  /* velocityAverage[ebN_kb_nSpace+2]=0.5*(w_left + w_right); */
7147  }//ebNI
7148  }
7149  }
7150 
7151 
7153  {
7154  xt::pyarray<double>& mesh_dof = args.array<double>("mesh_dof");
7155  xt::pyarray<int>& mesh_l2g = args.array<int>("mesh_l2g");
7156  xt::pyarray<double>& mesh_trial_trace_ref = args.array<double>("mesh_trial_trace_ref");
7157  xt::pyarray<double>& mesh_grad_trial_trace_ref = args.array<double>("mesh_grad_trial_trace_ref");
7158  xt::pyarray<double>& dS_ref = args.array<double>("dS_ref");
7159  xt::pyarray<double>& vel_test_trace_ref = args.array<double>("vel_test_trace_ref");
7160  xt::pyarray<double>& normal_ref = args.array<double>("normal_ref");
7161  xt::pyarray<double>& boundaryJac_ref = args.array<double>("boundaryJac_ref");
7162  xt::pyarray<int>& vel_l2g = args.array<int>("vel_l2g");
7163  int nExteriorElementBoundaries_global = args.scalar<int>("nExteriorElementBoundaries_global");
7164  xt::pyarray<int>& exteriorElementBoundariesArray = args.array<int>("exteriorElementBoundariesArray");
7165  xt::pyarray<int>& elementBoundaryElementsArray = args.array<int>("elementBoundaryElementsArray");
7166  xt::pyarray<int>& elementBoundaryLocalElementBoundariesArray = args.array<int>("elementBoundaryLocalElementBoundariesArray");
7167  xt::pyarray<double>& isBoundary_1D = args.array<double>("isBoundary_1D");
7168  //
7169  //loop over exterior element boundaries to calculate surface integrals and load into element and global residuals
7170  //
7171  //ebNE is the Exterior element boundary INdex
7172  //ebN is the element boundary INdex
7173  //eN is the element index
7174  for (int ebNE = 0; ebNE < nExteriorElementBoundaries_global; ebNE++)
7175  {
7176  register int ebN = exteriorElementBoundariesArray[ebNE],
7177  eN = elementBoundaryElementsArray[ebN*2+0],
7178  ebN_local = elementBoundaryLocalElementBoundariesArray[ebN*2+0],
7179  eN_nDOF_trial_element = eN*nDOF_trial_element;
7180  register double
7181  elementIsBoundary[nDOF_test_element];
7182  const double* elementResidual_w(NULL);
7183  for (int i=0;i<nDOF_test_element;i++)
7184  elementIsBoundary[i]=0.0;
7185  for (int kb=0;kb<nQuadraturePoints_elementBoundary;kb++)
7186  {
7187  register int ebNE_kb = ebNE*nQuadraturePoints_elementBoundary+kb,
7188  ebNE_kb_nSpace = ebNE_kb*nSpace,
7189  ebN_local_kb = ebN_local*nQuadraturePoints_elementBoundary+kb,
7190  ebN_local_kb_nSpace = ebN_local_kb*nSpace;
7191  register double
7192  jac_ext[nSpace*nSpace],
7193  jacDet_ext,
7194  jacInv_ext[nSpace*nSpace],
7195  boundaryJac[nSpace*(nSpace-1)],
7196  metricTensor[(nSpace-1)*(nSpace-1)],
7197  metricTensorDetSqrt,
7198  dS, vel_test_dS[nDOF_test_element],
7199  normal[2],x_ext,y_ext,z_ext;
7200  //compute information about mapping from reference element to physical element
7201  ck.calculateMapping_elementBoundary(eN,
7202  ebN_local,
7203  kb,
7204  ebN_local_kb,
7205  mesh_dof.data(),
7206  mesh_l2g.data(),
7207  mesh_trial_trace_ref.data(),
7208  mesh_grad_trial_trace_ref.data(),
7209  boundaryJac_ref.data(),
7210  jac_ext,
7211  jacDet_ext,
7212  jacInv_ext,
7213  boundaryJac,
7214  metricTensor,
7215  metricTensorDetSqrt,
7216  normal_ref.data(),
7217  normal,
7218  x_ext,y_ext,z_ext);
7219  dS = metricTensorDetSqrt*dS_ref[kb];
7220  //precalculate test function products with integration weights
7221  for (int j=0;j<nDOF_trial_element;j++)
7222  vel_test_dS[j] = fabs(vel_test_trace_ref[ebN_local_kb*nDOF_test_element+j])*dS;
7223  //
7224  //update residuals
7225  //
7226  for (int i=0;i<nDOF_test_element;i++)
7227  elementIsBoundary[i] += vel_test_dS[i];
7228  }//kb
7229  //
7230  //update the element and global residual storage
7231  //
7232  for (int i=0;i<nDOF_test_element;i++)
7233  {
7234  int eN_i = eN*nDOF_test_element+i;
7235  isBoundary_1D[vel_l2g[eN_i]] += elementIsBoundary[i];
7236  }//i
7237  }//ebNE
7238  }
7239  };//RANS3PF2D
7240 
7241  inline cppRANS3PF2D_base* newRANS3PF2D(int nSpaceIn,
7242  int nQuadraturePoints_elementIn,
7243  int nDOF_mesh_trial_elementIn,
7244  int nDOF_trial_elementIn,
7245  int nDOF_test_elementIn,
7246  int nQuadraturePoints_elementBoundaryIn,
7247  int CompKernelFlag,
7248  double aDarcy,
7249  double betaForch,
7250  double grain,
7251  double packFraction,
7252  double packMargin,
7253  double maxFraction,
7254  double frFraction,
7255  double sigmaC,
7256  double C3e,
7257  double C4e,
7258  double eR,
7259  double fContact,
7260  double mContact,
7261  double nContact,
7262  double angFriction, double vos_limiter, double mu_fr_limiter )
7263  {
7264  cppRANS3PF2D_base *rvalue = proteus::chooseAndAllocateDiscretization2D<cppRANS3PF2D_base, cppRANS3PF2D, CompKernel>(nSpaceIn,
7265  nQuadraturePoints_elementIn,
7266  nDOF_mesh_trial_elementIn,
7267  nDOF_trial_elementIn,
7268  nDOF_test_elementIn,
7269  nQuadraturePoints_elementBoundaryIn,
7270  CompKernelFlag);
7271  rvalue->setSedClosure(aDarcy,
7272  betaForch,
7273  grain,
7274  packFraction,
7275  packMargin,
7276  maxFraction,
7277  frFraction,
7278  sigmaC,
7279  C3e,
7280  C4e,
7281  eR,
7282  fContact,
7283  mContact,
7284  nContact,
7285  angFriction, vos_limiter, mu_fr_limiter );
7286  return rvalue;
7287  }
7288 } //proteus
7289 
7290 #endif
proteus::cppRANS3PF2D_base::getBoundaryDOFs
virtual void getBoundaryDOFs(arguments_dict &args)=0
C_FOR_GAMMA_INDICATOR
#define C_FOR_GAMMA_INDICATOR
Definition: RANS3PF2D.h:40
proteus::cppRANS3PF2D::psi
std::valarray< double > psi
Definition: RANS3PF2D.h:109
proteus::cppRANS3PF2D::ExteriorNumericalDiffusiveFluxJacobian
double ExteriorNumericalDiffusiveFluxJacobian(const double &eps, const double &phi, int *rowptr, int *colind, const int &isDOFBoundary, const int &isFluxBoundary, const double n[nSpace], double *a, const double &v, const double grad_v[nSpace], const double &penalty)
Definition: RANS3PF2D.h:1473
proteus::cppRANS3PF2D::Dot
double Dot(const double vec1[nSpace], const double vec2[nSpace])
Definition: RANS3PF2D.h:189
EPS_FOR_GAMMA_INDICATOR
#define EPS_FOR_GAMMA_INDICATOR
Definition: RANS3PF2D.h:39
USE_GAMMA_INDICATOR
#define USE_GAMMA_INDICATOR
Definition: RANS3PF2D.h:41
w
#define w(x)
Definition: jf.h:22
proteus::cppRANS3PF2D::exteriorNumericalDiffusiveFlux
void exteriorNumericalDiffusiveFlux(const double &eps, const double &phi, int *rowptr, int *colind, const int &isDOFBoundary, const int &isFluxBoundary, const double n[nSpace], double *bc_a, const double &bc_u, const double &bc_flux, double *a, const double grad_potential[nSpace], const double &u, const double &penalty, double &flux)
Definition: RANS3PF2D.h:1425
proteus::cppRANS3PF2D::get_distance_to_ith_ball
void get_distance_to_ith_ball(int n_balls, double *ball_center, double *ball_radius, int I, double x, double y, double z, double &distance)
Definition: RANS3PF2D.h:1539
proteus::cppRANS3PF2D::get_cross_product
double get_cross_product(const double *u, const double *v)
Definition: RANS3PF2D.h:1512
DM2
const double DM2
Definition: RANS3PF2D.h:15
CELL_BASED_EV_COEFF
#define CELL_BASED_EV_COEFF
Definition: RANS3PF2D.h:37
proteus::cppRANS3PF2D::calculateTangentialGradient
void calculateTangentialGradient(const double normal[nSpace], const double vel_grad[nSpace], double vel_tgrad[nSpace])
Definition: RANS3PF2D.h:198
proteus::cppRANS3PF2D::C_sbm
double C_sbm
Definition: RANS3PF2D.h:110
sgn
double sgn(double val)
Definition: RANS3PF2D.h:20
DM3
const double DM3
Definition: RANS3PF2D.h:16
proteus::cppRANS3PF2D_base::vStar_min_hiHe
std::valarray< double > vStar_min_hiHe
Definition: RANS3PF2D.h:67
proteus::cppRANS3PF2D::updateDarcyForchheimerTerms_Ergun
void updateDarcyForchheimerTerms_Ergun(const double alpha, const double beta, const double eps_rho, const double eps_mu, const double rho_0, const double nu_0, const double rho_1, const double nu_1, double nu_t, const double useVF, const double vf, const double phi, const double u, const double v, const double w, const double uStar, const double vStar, const double wStar, const double eps_s, const double phi_s, const double u_s, const double v_s, const double w_s, const double uStar_s, const double vStar_s, const double wStar_s, double &mom_u_source, double &mom_v_source, double &mom_w_source, double dmom_u_source[nSpace], double dmom_v_source[nSpace], double dmom_w_source[nSpace], double gradC_x, double gradC_y, double gradC_z)
Definition: RANS3PF2D.h:524
proteus::cppRANS3PF2D::ck
CompKernelType ck
Definition: RANS3PF2D.h:114
proteus::cppRANS3PF2D::nSpace2
const int nSpace2
Definition: RANS3PF2D.h:113
proteus::cppRANS3PF2D::calculateSubgridError_tau
void calculateSubgridError_tau(const double &hFactor, const double &elementDiameter, const double &dmt, const double &dm, const double df[nSpace], const double &a, const double &pfac, double &tau_v, double &tau_p, double &cfl)
Definition: RANS3PF2D.h:1015
proteus::cppRANS3PF2D::beta_sbm
double beta_sbm
Definition: RANS3PF2D.h:110
proteus::newRANS3PF2D
cppRANS3PF2D_base * newRANS3PF2D(int nSpaceIn, int nQuadraturePoints_elementIn, int nDOF_mesh_trial_elementIn, int nDOF_trial_elementIn, int nDOF_test_elementIn, int nQuadraturePoints_elementBoundaryIn, int CompKernelFlag, double aDarcy, double betaForch, double grain, double packFraction, double packMargin, double maxFraction, double frFraction, double sigmaC, double C3e, double C4e, double eR, double fContact, double mContact, double nContact, double angFriction, double vos_limiter, double mu_fr_limiter)
Definition: RANS3PF2D.h:7241
proteus::cppRANS3PF2D::calculateJacobian
void calculateJacobian(arguments_dict &args, bool useExact)
Definition: RANS3PF2D.h:4664
proteus::cppRANS3PF2D::calculateSubgridError_tauRes
void calculateSubgridError_tauRes(const double &tau_p, const double &tau_v, const double &pdeResidualP, const double &pdeResidualU, const double &pdeResidualV, const double &pdeResidualW, double &subgridErrorP, double &subgridErrorU, double &subgridErrorV, double &subgridErrorW)
Definition: RANS3PF2D.h:1064
L
Double L
Definition: Headers.h:72
n
Int n
Definition: Headers.h:28
proteus::cppRANS3PF2D::closure
cppHsuSedStress< 2 > closure
Definition: RANS3PF2D.h:111
proteus::cppRANS3PF2D::calculateCFL
void calculateCFL(const double &hFactor, const double &elementDiameter, const double &dm, const double df[nSpace], double &cfl)
Definition: RANS3PF2D.h:900
df
double df(double C, double b, double a, int q, int r)
Definition: analyticalSolutions.c:2209
proteus::cppRANS3PF2D
Definition: RANS3PF2D.h:106
ModelFactory.h
CompKernel.h
proteus::arguments_dict::scalar
T & scalar(const std::string &key)
proteus::arguments_dict::array
xt::pyarray< T > & array(const std::string &key)
SedClosure.h
proteus::cppRANS3PF2D::get_velocity_to_ith_ball
void get_velocity_to_ith_ball(int n_balls, double *ball_center, double *ball_radius, double *ball_velocity, double *ball_angular_velocity, int I, double x, double y, double z, double &vx, double &vy)
Definition: RANS3PF2D.h:1561
proteus::cppRANS3PF2D_base
Definition: RANS3PF2D.h:62
vel
void vel(double rS, double norm_v, double r, double theta, double *vR, double *vTHETA)
Definition: analyticalSolutions.c:2163
proteus::cppRANS3PF2D::TransportMatrix
std::valarray< double > TransportMatrix
Definition: RANS3PF2D.h:109
proteus::cppRANS3PF2D::cppRANS3PF2D
cppRANS3PF2D()
Definition: RANS3PF2D.h:117
proteus::cppRANS3PF2D::gf
GeneralizedFunctions< nSpace, 1, nQuadraturePoints_element, nQuadraturePoints_elementBoundary > gf
Definition: RANS3PF2D.h:115
proteus::cppRANS3PF2D_base::TransposeTransportMatrix
std::valarray< double > TransposeTransportMatrix
Definition: RANS3PF2D.h:64
R
Double R
Definition: Headers.h:82
proteus::cppRANS3PF2D_base::calculateJacobian
virtual void calculateJacobian(arguments_dict &args, bool useExact)=0
vx
Double vx
Definition: Headers.h:97
proteus::cppRANS3PF2D_base::calculateVelocityAverage
virtual void calculateVelocityAverage(arguments_dict &args)=0
proteus::cppRANS3PF2D_base::uStar_gamma
std::valarray< double > uStar_gamma
Definition: RANS3PF2D.h:68
DM
const double DM
Definition: RANS3PF2D.h:14
nu_0
double nu_0
Definition: ErrorResidualMethod.cpp:22
proteus::cppRANS3PF2D::exteriorNumericalAdvectiveFlux
void exteriorNumericalAdvectiveFlux(const int &isDOFBoundary_p, const int &isDOFBoundary_u, const int &isDOFBoundary_v, const int &isDOFBoundary_w, const int &isFluxBoundary_p, const int &isFluxBoundary_u, const int &isFluxBoundary_v, const int &isFluxBoundary_w, const double &oneByRho, const double &bc_oneByRho, const double n[nSpace], const double &porosity, const double &bc_p, const double &bc_u, const double &bc_v, const double &bc_w, const double bc_f_mass[nSpace], const double bc_f_umom[nSpace], const double bc_f_vmom[nSpace], const double bc_f_wmom[nSpace], const double &bc_flux_mass, const double &bc_flux_umom, const double &bc_flux_vmom, const double &bc_flux_wmom, const double &p, const double &u, const double &v, const double &w, const double f_mass[nSpace], const double f_umom[nSpace], const double f_vmom[nSpace], const double f_wmom[nSpace], const double df_mass_du[nSpace], const double df_mass_dv[nSpace], const double df_mass_dw[nSpace], const double df_umom_dp[nSpace], const double df_umom_du[nSpace], const double df_umom_dv[nSpace], const double df_umom_dw[nSpace], const double df_vmom_dp[nSpace], const double df_vmom_du[nSpace], const double df_vmom_dv[nSpace], const double df_vmom_dw[nSpace], const double df_wmom_dp[nSpace], const double df_wmom_du[nSpace], const double df_wmom_dv[nSpace], const double df_wmom_dw[nSpace], double &flux_mass, double &flux_umom, double &flux_vmom, double &flux_wmom, double *velocity_star, double *velocity)
Definition: RANS3PF2D.h:1124
proteus::cppRANS3PF2D::surrogate_boundary_particle
std::vector< int > surrogate_boundary_particle
Definition: RANS3PF2D.h:108
v
Double v
Definition: Headers.h:95
proteus::cppRANS3PF2D_base::vStar_psi
std::valarray< double > vStar_psi
Definition: RANS3PF2D.h:65
proteus::cppRANS3PF2D::calculateVelocityAverage
void calculateVelocityAverage(arguments_dict &args)
Definition: RANS3PF2D.h:6977
proteus::cppRANS3PF2D_base::uStar_psi
std::valarray< double > uStar_psi
Definition: RANS3PF2D.h:65
nu_1
double nu_1
Definition: ErrorResidualMethod.cpp:22
proteus::cppHsuSedStress::betaCoeff
double betaCoeff(double sedF, double rhoFluid, const double uFluid[nSpace], const double uSolid[nSpace], double nu)
Definition: SedClosure.h:71
proteus::cppRANS3PF2D_base::uStar_hi
std::valarray< double > uStar_hi
Definition: RANS3PF2D.h:66
proteus::cppRANS3PF2D_base::wStar_hi
std::valarray< double > wStar_hi
Definition: RANS3PF2D.h:66
proteus::cppRANS3PF2D::get_symmetric_gradient_dot_vec
void get_symmetric_gradient_dot_vec(const double *grad_u, const double *grad_v, const double *n, double res[2])
Definition: RANS3PF2D.h:1505
equivalent_polynomials.h
proteus::cppRANS3PF2D::nDOF_test_X_trial_element
const int nDOF_test_X_trial_element
Definition: RANS3PF2D.h:112
vy
Double vy
Definition: Headers.h:98
DRAG_FAC
#define DRAG_FAC
Definition: RANS3PF2D.h:17
z
Double * z
Definition: Headers.h:49
u
Double u
Definition: Headers.h:89
TURB_FORCE_FAC
#define TURB_FORCE_FAC
Definition: RANS3PF2D.h:18
proteus::phi
double phi(const double &g, const double &h, const double &hL, const double &hR, const double &uL, const double &uR)
Definition: SW2DCV.h:62
xt
Definition: AddedMass.cpp:7
rho_1
double rho_1
Definition: ErrorResidualMethod.cpp:22
proteus::cppRANS3PF2D::calculateSubgridError_tau
void calculateSubgridError_tau(const double &Ct_sge, const double &Cd_sge, const double G[nSpace *nSpace], const double &G_dd_G, const double &tr_G, const double &A0, const double Ai[nSpace], const double &Kij, const double &pfac, double &tau_v, double &tau_p, double &q_cfl)
Definition: RANS3PF2D.h:1043
proteus::cppRANS3PF2D_base::uStar_min_hiHe
std::valarray< double > uStar_min_hiHe
Definition: RANS3PF2D.h:67
proteus::cppRANS3PF2D::get_normal_to_ith_ball
void get_normal_to_ith_ball(int n_balls, double *ball_center, double *ball_radius, int I, double x, double y, double z, double &nx, double &ny)
Definition: RANS3PF2D.h:1549
cMax
#define cMax
Definition: NCLS3P.h:11
proteus::cppHsuSedStress::sigmaC_
double sigmaC_
Definition: SedClosure.h:932
proteus::cppRANS3PF2D::compute_force_around_solid
void compute_force_around_solid(bool element_owned, const double dV, const int nParticles, const int sd_offset, double *particle_signed_distances, double *particle_signed_distance_normals, double *particle_velocities, double *particle_centroids, int use_ball_as_particle, double *ball_center, double *ball_radius, double *ball_velocity, double *ball_angular_velocity, const double penalty, const double alpha, const double beta, const double eps_rho, const double eps_mu, const double rho_0, const double nu_0, const double rho_1, const double nu_1, const double useVF, const double vf, const double phi, const double x, const double y, const double z, const double p, const double u, const double v, const double w, const double uStar, const double vStar, const double wStar, const double eps_s, const double grad_u[nSpace], const double grad_v[nSpace], const double grad_w[nSpace], double *particle_netForces, double *particle_netMoments)
Definition: RANS3PF2D.h:787
proteus::cppRANS3PF2D::updateSolidParticleTerms
void updateSolidParticleTerms(bool element_owned, const double particle_nitsche, const double dV, const int nParticles, const int sd_offset, double *particle_signed_distances, double *particle_signed_distance_normals, double *particle_velocities, double *particle_centroids, int use_ball_as_particle, double *ball_center, double *ball_radius, double *ball_velocity, double *ball_angular_velocity, const double porosity, const double penalty, const double alpha, const double beta, const double eps_rho, const double eps_mu, const double rho_0, const double nu_0, const double rho_1, const double nu_1, const double useVF, const double vf, const double phi, const double x, const double y, const double z, const double p, const double u, const double v, const double w, const double uStar, const double vStar, const double wStar, const double eps_s, const double grad_u[nSpace], const double grad_v[nSpace], const double grad_w[nSpace], double &mom_u_source, double &mom_v_source, double &mom_w_source, double dmom_u_source[nSpace], double dmom_v_source[nSpace], double dmom_w_source[nSpace], double mom_u_adv[nSpace], double mom_v_adv[nSpace], double mom_w_adv[nSpace], double dmom_u_adv_u[nSpace], double dmom_v_adv_v[nSpace], double dmom_w_adv_w[nSpace], double &mom_u_ham, double dmom_u_ham_grad_u[nSpace], double &mom_v_ham, double dmom_v_ham_grad_v[nSpace], double &mom_w_ham, double dmom_w_ham_grad_w[nSpace], double *particle_netForces, double *particle_netMoments, double *particle_surfaceArea)
Definition: RANS3PF2D.h:604
proteus::cppRANS3PF2D::updateTurbulenceClosure
void updateTurbulenceClosure(const int turbulenceClosureModel, const double eps_rho, const double eps_mu, const double rho_0, const double nu_0, const double rho_1, const double nu_1, const double useVF, const double vf, const double phi, const double porosity, const double eddy_visc_coef_0, const double turb_var_0, const double turb_var_1, const double turb_grad_0[nSpace], double &eddy_viscosity, double mom_uu_diff_ten[nSpace], double mom_vv_diff_ten[nSpace], double mom_ww_diff_ten[nSpace], double mom_uv_diff_ten[1], double mom_uw_diff_ten[1], double mom_vu_diff_ten[1], double mom_vw_diff_ten[1], double mom_wu_diff_ten[1], double mom_wv_diff_ten[1], double &mom_u_source, double &mom_v_source, double &mom_w_source)
Definition: RANS3PF2D.h:919
proteus::cppRANS3PF2D::calculateResidual
void calculateResidual(arguments_dict &args, bool useExact)
Definition: RANS3PF2D.h:1571
proteus::cppRANS3PF2D::surrogate_boundary_elements
std::vector< int > surrogate_boundary_elements
Definition: RANS3PF2D.h:108
equivalent_polynomials::GeneralizedFunctions_mix
Definition: equivalent_polynomials.h:767
proteus::cppRANS3PF2D::getBoundaryDOFs
void getBoundaryDOFs(arguments_dict &args)
Definition: RANS3PF2D.h:7152
proteus::cppRANS3PF2D_base::wStar_min_hiHe
std::valarray< double > wStar_min_hiHe
Definition: RANS3PF2D.h:67
ANISOTROPIC_DIFFUSION
#define ANISOTROPIC_DIFFUSION
Definition: RANS3PF2D.h:42
proteus::cppRANS3PF2D::surrogate_boundaries
std::vector< int > surrogate_boundaries
Definition: RANS3PF2D.h:108
proteus
Definition: ADR.h:17
proteus::GeneralizedFunctions
equivalent_polynomials::GeneralizedFunctions_mix< nSpace, nP, nQ, nEBQ > GeneralizedFunctions
Definition: ADR.h:19
proteus::cppRANS3PF2D_base::vStar_gamma
std::valarray< double > vStar_gamma
Definition: RANS3PF2D.h:68
proteus::cppRANS3PF2D::gf_s
GeneralizedFunctions< nSpace, 1, nQuadraturePoints_element, nQuadraturePoints_elementBoundary > gf_s
Definition: RANS3PF2D.h:116
proteus::cppHsuSedStress< 2 >
POWER_SMOOTHNESS_INDICATOR
#define POWER_SMOOTHNESS_INDICATOR
Definition: RANS3PF2D.h:38
r
Double r
Definition: Headers.h:83
proteus::cppRANS3PF2D_base::calculateResidual
virtual void calculateResidual(arguments_dict &args, bool useExact)=0
proteus::cppRANS3PF2D::evaluateCoefficients
void evaluateCoefficients(const double eps_rho, const double eps_mu, const double eps_s, const double sigma, const double rho_0, double nu_0, const double rho_1, double nu_1, const double h_e, const double smagorinskyConstant, const int turbulenceClosureModel, const double g[nSpace], const double useVF, const double &vf, const double &phi, const double n[nSpace], const double distance_to_omega_solid, const double &kappa, const double porosity, const double &p, const double grad_p[nSpace], const double grad_u[nSpace], const double grad_v[nSpace], const double grad_w[nSpace], const double &u, const double &v, const double &w, const double &uStar, const double &vStar, const double &wStar, double &eddy_viscosity, double &mom_u_acc, double &dmom_u_acc_u, double &mom_v_acc, double &dmom_v_acc_v, double &mom_w_acc, double &dmom_w_acc_w, double mass_adv[nSpace], double dmass_adv_u[nSpace], double dmass_adv_v[nSpace], double dmass_adv_w[nSpace], double mom_u_adv[nSpace], double dmom_u_adv_u[nSpace], double dmom_u_adv_v[nSpace], double dmom_u_adv_w[nSpace], double mom_v_adv[nSpace], double dmom_v_adv_u[nSpace], double dmom_v_adv_v[nSpace], double dmom_v_adv_w[nSpace], double mom_w_adv[nSpace], double dmom_w_adv_u[nSpace], double dmom_w_adv_v[nSpace], double dmom_w_adv_w[nSpace], double mom_uu_diff_ten[nSpace], double mom_vv_diff_ten[nSpace], double mom_ww_diff_ten[nSpace], double mom_uv_diff_ten[1], double mom_uw_diff_ten[1], double mom_vu_diff_ten[1], double mom_vw_diff_ten[1], double mom_wu_diff_ten[1], double mom_wv_diff_ten[1], double &mom_u_source, double &mom_v_source, double &mom_w_source, double &mom_u_ham, double dmom_u_ham_grad_p[nSpace], double dmom_u_ham_grad_u[nSpace], double &mom_v_ham, double dmom_v_ham_grad_p[nSpace], double dmom_v_ham_grad_v[nSpace], double &mom_w_ham, double dmom_w_ham_grad_p[nSpace], double dmom_w_ham_grad_w[nSpace], double &rhoSave, double &nuSave, int KILL_PRESSURE_TERM, int MULTIPLY_EXTERNAL_FORCE_BY_DENSITY, double forcex, double forcey, double forcez, int MATERIAL_PARAMETERS_AS_FUNCTION, double density_as_function, double dynamic_viscosity_as_function, int USE_SBM, double x, double y, double z, int use_ball_as_particle, double *ball_center, double *ball_radius, double *ball_velocity, double *ball_angular_velocity, int INT_BY_PARTS_PRESSURE)
Definition: RANS3PF2D.h:208
proteus::cppRANS3PF2D::exteriorNumericalAdvectiveFluxDerivatives
void exteriorNumericalAdvectiveFluxDerivatives(const int &isDOFBoundary_p, const int &isDOFBoundary_u, const int &isDOFBoundary_v, const int &isDOFBoundary_w, const int &isFluxBoundary_p, const int &isFluxBoundary_u, const int &isFluxBoundary_v, const int &isFluxBoundary_w, const double &oneByRho, const double n[nSpace], const double &porosity, const double &bc_p, const double &bc_u, const double &bc_v, const double &bc_w, const double bc_f_mass[nSpace], const double bc_f_umom[nSpace], const double bc_f_vmom[nSpace], const double bc_f_wmom[nSpace], const double &bc_flux_mass, const double &bc_flux_umom, const double &bc_flux_vmom, const double &bc_flux_wmom, const double &p, const double &u, const double &v, const double &w, const double f_mass[nSpace], const double f_umom[nSpace], const double f_vmom[nSpace], const double f_wmom[nSpace], const double df_mass_du[nSpace], const double df_mass_dv[nSpace], const double df_mass_dw[nSpace], const double df_umom_dp[nSpace], const double df_umom_du[nSpace], const double df_umom_dv[nSpace], const double df_umom_dw[nSpace], const double df_vmom_dp[nSpace], const double df_vmom_du[nSpace], const double df_vmom_dv[nSpace], const double df_vmom_dw[nSpace], const double df_wmom_dp[nSpace], const double df_wmom_du[nSpace], const double df_wmom_dv[nSpace], const double df_wmom_dw[nSpace], double &dflux_mass_du, double &dflux_mass_dv, double &dflux_mass_dw, double &dflux_umom_dp, double &dflux_umom_du, double &dflux_umom_dv, double &dflux_umom_dw, double &dflux_vmom_dp, double &dflux_vmom_du, double &dflux_vmom_dv, double &dflux_vmom_dw, double &dflux_wmom_dp, double &dflux_wmom_du, double &dflux_wmom_dv, double &dflux_wmom_dw, double *velocity_star)
Definition: RANS3PF2D.h:1261
proteus::arguments_dict
Definition: ArgumentsDict.h:70
proteus::cppRANS3PF2D::calculateSubgridErrorDerivatives_tauRes
void calculateSubgridErrorDerivatives_tauRes(const double &tau_p, const double &tau_v, const double dpdeResidualP_du[nDOF_trial_element], const double dpdeResidualP_dv[nDOF_trial_element], const double dpdeResidualP_dw[nDOF_trial_element], const double dpdeResidualU_dp[nDOF_trial_element], const double dpdeResidualU_du[nDOF_trial_element], const double dpdeResidualV_dp[nDOF_trial_element], const double dpdeResidualV_dv[nDOF_trial_element], const double dpdeResidualW_dp[nDOF_trial_element], const double dpdeResidualW_dw[nDOF_trial_element], double dsubgridErrorP_du[nDOF_trial_element], double dsubgridErrorP_dv[nDOF_trial_element], double dsubgridErrorP_dw[nDOF_trial_element], double dsubgridErrorU_dp[nDOF_trial_element], double dsubgridErrorU_du[nDOF_trial_element], double dsubgridErrorV_dp[nDOF_trial_element], double dsubgridErrorV_dv[nDOF_trial_element], double dsubgridErrorW_dp[nDOF_trial_element], double dsubgridErrorW_dw[nDOF_trial_element])
Definition: RANS3PF2D.h:1083
proteus::cppRANS3PF2D::setSedClosure
void setSedClosure(double aDarcy, double betaForch, double grain, double packFraction, double packMargin, double maxFraction, double frFraction, double sigmaC, double C3e, double C4e, double eR, double fContact, double mContact, double nContact, double angFriction, double vos_limiter, double mu_fr_limiter)
Definition: RANS3PF2D.h:152
rho_0
double rho_0
Definition: ErrorResidualMethod.cpp:22
CUT_CELL_INTEGRATION
#define CUT_CELL_INTEGRATION
Definition: RANS3PF2D.h:19
proteus::cppRANS3PF2D_base::setSedClosure
virtual void setSedClosure(double aDarcy, double betaForch, double grain, double packFraction, double packMargin, double maxFraction, double frFraction, double sigmaC, double C3e, double C4e, double eR, double fContact, double mContact, double nContact, double angFriction, double vos_limiter, double mu_fr_limiter)
Definition: RANS3PF2D.h:70
proteus::cppRANS3PF2D_base::wStar_psi
std::valarray< double > wStar_psi
Definition: RANS3PF2D.h:65
proteus::cppRANS3PF2D::get_dot_product
double get_dot_product(const double *u, const double *v)
Definition: RANS3PF2D.h:1516
proteus::cppRANS3PF2D_base::den_hi
std::valarray< double > den_hi
Definition: RANS3PF2D.h:66
baryCoords
void baryCoords(const double r0[2], const double r1[2], const double r2[2], const double r[2], double *lambda)
Definition: RANS3PF2D.h:44
proteus::cppRANS3PF2D::get_distance_to_ball
int get_distance_to_ball(int n_balls, double *ball_center, double *ball_radius, double x, double y, double z, double &distance)
Definition: RANS3PF2D.h:1520
proteus::cppRANS3PF2D_base::~cppRANS3PF2D_base
virtual ~cppRANS3PF2D_base()
Definition: RANS3PF2D.h:69
ArgumentsDict.h
proteus::cppRANS3PF2D::TransposeTransportMatrix
std::valarray< double > TransposeTransportMatrix
Definition: RANS3PF2D.h:109
proteus::cppRANS3PF2D_base::wStar_gamma
std::valarray< double > wStar_gamma
Definition: RANS3PF2D.h:68
proteus::cppRANS3PF2D_base::TransportMatrix
std::valarray< double > TransportMatrix
Definition: RANS3PF2D.h:64
cE
#define cE
Definition: NCLS3P.h:10
proteus::cppRANS3PF2D_base::vStar_hi
std::valarray< double > vStar_hi
Definition: RANS3PF2D.h:66