proteus  1.8.1
C/C++/Fortran libraries
RANS2P.h
Go to the documentation of this file.
1 #ifndef RANS2P_H
2 #define RANS2P_H
3 #include <valarray>
4 #include <cmath>
5 #include <iostream>
6 #include <set>
7 #include <map>
8 #include "CompKernel.h"
9 #include "MixedModelFactory.h"
10 #include "PyEmbeddedFunctions.h"
11 #include "equivalent_polynomials.h"
12 #include "ArgumentsDict.h"
13 #include "xtensor/xarray.hpp"
14 #include "xtensor/xview.hpp"
15 #include "xtensor/xfixed.hpp"
16 #include "xtensor-python/pyarray.hpp"
17 #include "mpi.h"
18 #include "proteus_lapack.h"
19 
20 namespace py = pybind11;
21 
22 #define ZEROVEC {0.,0.,0.}
23 const bool UPWIND_DIRICHLET=true;
24 
25 const double DM=0.0;//1-mesh conservation and divergence, 0 - weak div(v) only
26 const double DM2=0.0;//1-point-wise mesh volume strong-residual, 0 - div(v) only
27 const double DM3=1.0;//1-point-wise divergence, 0-point-wise rate of volume change
28 const double inertial_term=1.0;
29 namespace proteus
30 {
31  inline double enorm(double* v)
32  {
33  return std::sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
34  }
35  inline double rnorm(double* r)
36  {
37  double rnorm=0.0;
38  for (int i=0;i<18;i++)
39  rnorm += r[i]*r[i];
40  return std::sqrt(rnorm);
41  }
42  inline void F6DOF(double DT, double mass, double* Iref, double* last_u, double* FT, double* last_FT, double* last_mom, double* u, //inputs
43  double* mom, double* r, double* J)//outputs
44  {
45  double *v = &u[0],
46  *last_v=&last_u[0],
47  *omega = &u[3],
48  *last_omega = &last_u[3],
49  *h = &u[6],
50  *last_h = &last_u[6],
51  *Q = &u[9],
52  *last_Q = &last_u[9];
53  register double Omega[9] = { 0.0, -omega[2], omega[1],
54  omega[2], 0.0, -omega[0],
55  -omega[1], omega[0], 0.0},
56  last_Omega[9] = { 0.0, -last_omega[2], last_omega[1],
57  last_omega[2], 0.0, -last_omega[0],
58  -last_omega[1], last_omega[0], 0.0},
59  I[9] = {0.0};
60  for (int i=0;i<18;i++)
61  {
62  r[i] = 0.0;
63  for (int j=0;j<18;j++)
64  J[i*18+j] = 0.0;
65  }
66  //I = Q*Iref*Q^t
67  for (int i=0; i < 3; i++)
68  for (int j=0; j < 3; j++)
69  for (int k=0; k < 3; k++)
70  I[i*3 + j] += Q[i*3 + k]*Iref[k*3 +j];
71  for (int i=0; i < 3; i++)
72  for (int j=0; j < 3; j++)
73  for (int k=0; k < 3; k++)
74  I[i*3 + j] += I[i*3 + k]*Q[j*3 + k];
75  double M[36] = {0.0};
76  for (int i=0; i< 3; i++)
77  {
78  M[i*6 + i] = mass;
79  mom[i] = mass*u[i];//save for next time step--linear momentum
80  mom[3+i] = 0.0;
81  for (int j=0; j<3; j++)
82  {
83  M[(3+i)*6 + (3+j)] = I[i*3 + j];
84  mom[3+i] += I[i*3 + j]*u[3+j];//save for next time step--angular momentum
85  }
86  }
87  //could do added mass modification here
88  //
89  //residual
90  //momentum conservation residual
91  for (int i=0; i < 6; i++)
92  {
93  r[i] = - last_mom[i] - DT*0.5*(FT[i] + last_FT[i]);
94  for (int j=0; j < 6; j++)
95  {
96  r[i] += M[i*6 + j]*u[j];
97  J[i*18 + j] = M[i*6 + j];//all FT terms are explicit for now
98  }
99  }
100  //displacement residual
101  for (int i=0; i < 3; i++)
102  {
103  r[6+i] = h[i] - last_h[i] - DT*0.5*(v[i] + last_v[i]);
104  J[(6+i)*18 + (6+i)] = 1.0;
105  J[(6+i)*18 + i] = -DT*0.5;
106  }
107  //rotation residual
108  for (int i=0; i < 3; i++)
109  for (int j=0; j < 3; j++)
110  {
111  r[9 + i*3 + j] = Q[i*3 + j] - last_Q[i*3 + j];
112  J[(9+i*3+j)*18 + (9+i*3+j)] = 1.0;
113  for (int k=0; k < 3; k++)
114  {
115  r[9 + i*3 + j] -= DT*0.25*(Omega[i*3 + k] + last_Omega[i*3 +k])*(Q[k*3 + j]+last_Q[k*3 + j]);
116  J[(9 + i*3 + j)*18 + 9+k*3+j] -= DT*0.25*(Omega[i*3 + k] + last_Omega[i*3 + k]);
117  }
118  }
119  }
120 
121  template<int nSpace, int nP, int nQ, int nEBQ>
123 
125  {
126  public:
127  virtual ~RANS2P_base(){}
128  virtual void calculateResidual(arguments_dict& args) = 0;
129  virtual void calculateJacobian(arguments_dict& args) = 0;
135  {
136  py::gil_scoped_release release;
137  //py::gil_scoped_acquire acquire;
138  xt::pyarray<double>& ball_FT = args.array<double>("ball_FT");
139  xt::pyarray<double>& ball_last_FT = args.array<double>("ball_last_FT");
140  xt::pyarray<double>& ball_h = args.array<double>("ball_h");
141  xt::pyarray<double>& ball_last_h = args.array<double>("ball_last_h");
142  xt::pyarray<double>& ball_center = args.array<double>("ball_center");
143  xt::pyarray<double>& ball_center_last = args.array<double>("ball_center_last");
144  //note: these are only used for the fluid
145  xt::pyarray<double>& ball_velocity = args.array<double>("ball_velocity");
146  xt::pyarray<double>& ball_angular_velocity = args.array<double>("ball_angular_velocity");
147  //
148  xt::pyarray<double>& ball_last_velocity = args.array<double>("ball_last_velocity");
149  xt::pyarray<double>& ball_last_angular_velocity = args.array<double>("ball_last_angular_velocity");
150  xt::pyarray<double>& ball_Q = args.array<double>("ball_Q");
151  xt::pyarray<double>& ball_last_Q = args.array<double>("ball_last_Q");
152  xt::pyarray<double>& ball_Omega = args.array<double>("ball_Omega");
153  xt::pyarray<double>& ball_last_Omega = args.array<double>("ball_last_Omega");
154  xt::pyarray<double>& ball_u = args.array<double>("ball_u");
155  xt::pyarray<double>& ball_last_u = args.array<double>("ball_last_u");
156  xt::pyarray<double>& ball_mom = args.array<double>("ball_mom");
157  xt::pyarray<double>& ball_last_mom = args.array<double>("ball_last_mom");
158  xt::pyarray<double>& ball_a = args.array<double>("ball_a");
159  xt::pyarray<double>& ball_I = args.array<double>("ball_I");
160  xt::pyarray<double>& ball_mass = args.array<double>("ball_mass");
161  xt::pyarray<double>& ball_radius = args.array<double>("ball_radius");
162  xt::pyarray<double>& ball_f = args.array<double>("ball_f");
163  xt::pyarray<double>& wall_f = args.array<double>("wall_f");
164  xt::pyarray<double>& particle_netForces = args.array<double>("particle_netForces");
165  xt::pyarray<double>& particle_netMoments = args.array<double>("particle_netMoments");
166  xt::pyarray<double>& last_particle_netForces = args.array<double>("last_particle_netForces");
167  xt::pyarray<double>& last_particle_netMoments = args.array<double>("last_particle_netMoments");
168  xt::pyarray<double>& g = args.array<double>("g");
169  xt::pyarray<double>& L = args.array<double>("L");
170  const double ball_force_range = args.scalar<double>("ball_force_range");
171  const double ball_stiffness = args.scalar<double>("ball_stiffness");
172  const double particle_cfl = args.scalar<double>("particle_cfl");
173  const double dt = args.scalar<double>("dt");
174  double& min_dt(*args.array<double>("min_dt").data());
175  int& nSteps(*args.array<int>("nSteps").data());
176  const int nParticles = ball_center.shape(0);
177  double DT = dt;
178  double td = 0.0;
179  //double min_dt = dt;
180  //int nSteps=0;
181  min_dt = dt;
182  nSteps=0;
183  //double max_cfl=0.0;
184  xt::xarray<double> cfl=xt::zeros<double>({nParticles});
185 #pragma omp parallel for
186  for (int ip=0; ip < nParticles; ip++)
187  for (int i=0; i < 3; i++)
188  {
189  ball_velocity(ip,i) = 0.0;
190  ball_angular_velocity(ip,i) = 0.0;
191  }
192 
193  while (td < dt)
194  {
195  nSteps +=1;
196  //particle-wall and particle-particle collision forces
197 #pragma omp parallel for
198  for (int ip=0; ip < nParticles; ip++)
199  {
200  double vnorm = enorm(&ball_last_velocity.data()[ip*3]);
201  double vp[3], vpnorm;
202  for (int i=0; i< 3; i++)
203  {
204  ball_last_FT(ip, i) = particle_netForces(ip,i) + ball_mass(ip)*g[i] + ball_f(ip,i) + wall_f(ip,i);// - 2.0*0.001*vnorm*ball_last_velocity(ip,i);
205  ball_last_FT(ip, 3+i) = particle_netMoments(ip,i);
206  vp[i] = ball_last_velocity(ip,i) + ball_a(ip,i)*DT;
207  }
208  vpnorm = enorm(vp);
209  double wall_range = 2.0*ball_radius(ip) + ball_force_range;
210  double wall_stiffness = ball_stiffness/2.0;
211  double dx0 = fmin(wall_range, ball_radius(ip) + fmax(ball_radius(ip), fabs(ball_center(ip,0))));
212  double dxL = fmin(wall_range, ball_radius(ip) + fmax(ball_radius(ip), fabs(ball_center(ip,0)-L(0))));
213  wall_f(ip,0) = (1.0/wall_stiffness)*( pow(wall_range - dx0,2) * (fmax(0.0, ball_center(ip,0)) + ball_radius(ip)) +
214  pow(wall_range - dxL,2) * (fmin(L(0), ball_center(ip,0)) - (L(0) + ball_radius(ip))));
215  double dy0 = fmin(wall_range, ball_radius(ip) + fmax(ball_radius(ip), fabs(ball_center(ip,1))));
216  double dyL = fmin(wall_range, ball_radius(ip) + fmax(ball_radius(ip), fabs(ball_center(ip,1)-L(1))));
217  wall_f(ip,1) = (1.0/wall_stiffness)*( pow(wall_range - dy0,2) * (fmax(0.0, ball_center(ip,1)) + ball_radius(ip)) +
218  pow(wall_range - dyL,2) * (fmin(L(1), ball_center(ip,1)) - (L(1) + ball_radius(ip))));
219  double dz0 = fmin(wall_range, ball_radius(ip) + fmax(ball_radius(ip), fabs(ball_center(ip,2))));
220  double dzL = fmin(wall_range, ball_radius(ip) + fmax(ball_radius(ip), fabs(ball_center(ip,2)-L(2))));
221  wall_f(ip,2) = (1.0/wall_stiffness)*( pow(wall_range - dz0,2) * (fmax(0.0, ball_center(ip,2)) + ball_radius(ip)) +
222  pow(wall_range - dzL,2) * (fmin(L(2), ball_center(ip,2)) - (L(2) + ball_radius(ip))));
223 
224  for (int i=0; i< 3;i++)
225  ball_f(ip,i) = 0.0;
226  for (int jp=0; jp < nParticles; jp++)
227  {
228  double ball_range, d;
229  double f[3], h_ipjp[3];
230  ball_range = ball_radius(ip) + ball_radius(jp) + ball_force_range;
231  for(int i=0;i<3;i++)
232  h_ipjp[i] = ball_center(ip,i) - ball_center(jp,i);
233  d = ball_range - fmin(ball_range, fmax(ball_radius(ip) + ball_radius(jp), enorm(h_ipjp)));
234  for (int i=0;i<3;i++)
235  f[i] = (1.0/ball_stiffness)*h_ipjp[i]*pow(d,2.0);
236  if (ip != jp)
237  for (int i=0;i<3;i++)
238  ball_f(ip,i) += f[i];
239  }
240  cfl(ip) = fmax(vnorm*DT/ball_force_range, vpnorm*DT/ball_force_range);
241  }
242  double max_cfl = xt::amax(cfl,{0})(0);
243  if (max_cfl > particle_cfl)
244  DT = (particle_cfl/max_cfl)*DT;
245  if (DT > dt - td - dt*1.0e-8)
246  {
247  DT = dt-td;
248  td = dt;
249  }
250  else
251  td += DT;
252  min_dt =fmin(DT, min_dt);
253  //Newton iterations
254 #pragma omp parallel for
255  for (int ip=0; ip < nParticles; ip++)
256  {
257  int pivots[18];
258  double r[18];
259  double J[18*18];
260  for (int i=0; i<3; i++)
261  {
262  ball_FT(ip, i) = particle_netForces(ip, i) + ball_mass(ip)*g[i] + ball_f(ip, i) + wall_f(ip, i);
263  ball_FT(ip, 3+i) = particle_netMoments(ip, i);
264  }
265  F6DOF(DT, ball_mass(ip), &ball_I.data()[ip*9], &ball_last_u.data()[ip*18], &ball_FT.data()[ip*6], &ball_last_FT.data()[ip*6], &ball_last_mom.data()[ip*6], &ball_u.data()[ip*18],
266  &ball_mom.data()[ip*6], r, J);
267  int its=0;
268  int maxits=100;
269  while ((its==0 || rnorm(r) > 1.0e-10) && its < maxits)
270  {
271  int info,N=18,nrhs=1;
272  char trans='T';
273  dgetrf_(&N,&N,J,&N,pivots,&info);
274  dgetrs_(&trans, &N,&nrhs,J,&N,pivots,r,&N,&info);//J = LU now
275  for (int i=0;i<18;i++)
276  ball_u(ip,i) -= r[i];//r=du now
277  F6DOF(DT, ball_mass(ip), &ball_I.data()[ip*9], &ball_last_u.data()[ip*18], &ball_FT.data()[ip*6], &ball_last_FT.data()[ip*6], &ball_last_mom.data()[ip*6], &ball_u.data()[ip*18],
278  &ball_mom.data()[ip*6], r, J);
279  its+=1;
280  }
281  for (int i=0; i< 3; i++)
282  {
283  ball_center(ip,i) += (ball_u(ip,6+i) - ball_last_u(ip,6+i));
284  ball_a(ip,i) = (ball_u(ip,i) - ball_last_velocity(ip,i))/DT;
285  ball_last_velocity(ip,i) = ball_u(ip,i);
286  ball_last_mom(ip,i) = ball_mom(ip,i);
287  ball_last_mom(ip,3+i) = ball_mom(ip,3+i);
288  //return averages over dt for the fluid velocities
289  ball_velocity(ip,i) += DT*ball_u(ip,i)/dt;
290  ball_angular_velocity(ip,i) += DT*ball_u(ip,3+i)/dt;
291  }
292  for (int i=0; i< 18; i++)
293  ball_last_u(ip,i) = ball_u(ip,i);
294  }
295  }
296  }
297  };
298 
299  template<class CompKernelType,
300  class CompKernelType_v,
301  int nSpace,
302  int nQuadraturePoints_element,
303  int nDOF_mesh_trial_element,
304  int nDOF_trial_element,
305  int nDOF_test_element,
306  int nDOF_v_trial_element,
307  int nDOF_v_test_element,
308  int nQuadraturePoints_elementBoundary>
309  class RANS2P : public RANS2P_base
310  {
311  public:
314  std::map<int, int> cutfem_local_boundaries;
315 
320  CompKernelType ck;
321  CompKernelType_v ck_v;
326  nDOF_test_X_trial_element(nDOF_test_element*nDOF_trial_element),
327  nDOF_test_X_v_trial_element(nDOF_test_element*nDOF_v_trial_element),
328  nDOF_v_test_X_trial_element(nDOF_v_test_element*nDOF_trial_element),
329  nDOF_v_test_X_v_trial_element(nDOF_v_test_element*nDOF_v_trial_element),
330  ck(),
331  ck_v()
332  {}
333 
334  inline
335  void evaluateCoefficients(const double NONCONSERVATIVE_FORM,
336  const double sigma,
337  const double rho,
338  double nu,
339  const double h_e,
340  const double smagorinskyConstant,
341  const int turbulenceClosureModel,
342  const double g[nSpace],
343  const double useVF,
344  const double& vf,
345  const double& phi,
346  const double n[nSpace],
347  const double& kappa,
348  const double porosity,//VRANS specific
349  const double phi_solid,
350  const double p_old,
351  const double u_old,
352  const double v_old,
353  const double w_old,
354  const double grad_p_old[nSpace],
355  const double grad_u_old[nSpace],
356  const double grad_v_old[nSpace],
357  const double grad_w_old[nSpace],
358  const double& p,
359  const double grad_p[nSpace],
360  const double grad_u[nSpace],
361  const double grad_v[nSpace],
362  const double grad_w[nSpace],
363  const double& u,
364  const double& v,
365  const double& w,
366  const double LAG_LES,
367  double& eddy_viscosity,
368  double& eddy_viscosity_last,
369  double& mom_u_acc,
370  double& dmom_u_acc_u,
371  double& mom_v_acc,
372  double& dmom_v_acc_v,
373  double& mom_w_acc,
374  double& dmom_w_acc_w,
375  double mass_adv[nSpace],
376  double dmass_adv_u[nSpace],
377  double dmass_adv_v[nSpace],
378  double dmass_adv_w[nSpace],
379  double mom_u_adv[nSpace],
380  double dmom_u_adv_u[nSpace],
381  double dmom_u_adv_v[nSpace],
382  double dmom_u_adv_w[nSpace],
383  double mom_v_adv[nSpace],
384  double dmom_v_adv_u[nSpace],
385  double dmom_v_adv_v[nSpace],
386  double dmom_v_adv_w[nSpace],
387  double mom_w_adv[nSpace],
388  double dmom_w_adv_u[nSpace],
389  double dmom_w_adv_v[nSpace],
390  double dmom_w_adv_w[nSpace],
391  double mom_uu_diff_ten[nSpace],
392  double mom_vv_diff_ten[nSpace],
393  double mom_ww_diff_ten[nSpace],
394  double mom_uv_diff_ten[1],
395  double mom_uw_diff_ten[1],
396  double mom_vu_diff_ten[1],
397  double mom_vw_diff_ten[1],
398  double mom_wu_diff_ten[1],
399  double mom_wv_diff_ten[1],
400  double& mom_u_source,
401  double& mom_v_source,
402  double& mom_w_source,
403  double& mom_u_ham,
404  double dmom_u_ham_grad_p[nSpace],
405  double dmom_u_ham_grad_u[nSpace],
406  double& dmom_u_ham_u,
407  double& dmom_u_ham_v,
408  double& dmom_u_ham_w,
409  double& mom_v_ham,
410  double dmom_v_ham_grad_p[nSpace],
411  double dmom_v_ham_grad_v[nSpace],
412  double& dmom_v_ham_u,
413  double& dmom_v_ham_v,
414  double& dmom_v_ham_w,
415  double& mom_w_ham,
416  double dmom_w_ham_grad_p[nSpace],
417  double dmom_w_ham_grad_w[nSpace],
418  double& dmom_w_ham_u,
419  double& dmom_w_ham_v,
420  double& dmom_w_ham_w,
421  double forcex,
422  double forcey,
423  double forcez)
424  {
425  double mu,norm_n,nu_t;
426  //calculate eddy viscosity
427  switch (turbulenceClosureModel)
428  {
429  double norm_S;
430  case 1:
431  {
432  norm_S = sqrt(2.0*(grad_u[0]*grad_u[0] + grad_v[1]*grad_v[1] + grad_w[2]*grad_w[2] +
433  0.5*(grad_u[1]+grad_v[0])*(grad_u[1]+grad_v[0]) +
434  0.5*(grad_u[2]+grad_w[0])*(grad_u[2]+grad_w[0]) +
435  0.5*(grad_v[2]+grad_w[1])*(grad_v[2]+grad_w[1])));
436  nu_t = smagorinskyConstant*smagorinskyConstant*h_e*h_e*norm_S;
437  break;
438  }
439  case 2:
440  {
441  double re,cs=0.0;
442  norm_S = sqrt(2.0*(grad_u[0]*grad_u[0] + grad_v[1]*grad_v[1] + grad_w[2]*grad_w[2] +
443  0.5*(grad_u[1]+grad_v[0])*(grad_u[1]+grad_v[0]) +
444  0.5*(grad_u[2]+grad_w[0])*(grad_u[2]+grad_w[0]) +
445  0.5*(grad_v[2]+grad_w[1])*(grad_v[2]+grad_w[1])));
446  re = h_e*h_e*norm_S/nu;
447  if (re > 1.0)
448  cs=0.027*pow(10.0,-3.23*pow(re,-0.92));
449  nu_t = cs*h_e*h_e*norm_S;
450  break;
451  }
452  default:
453  {
454  nu_t=0.0;
455  }
456  }
457  eddy_viscosity = nu_t;
458  nu += (1.0-LAG_LES)*nu_t + LAG_LES*eddy_viscosity_last;
459  mu = rho*nu;
460  if (NONCONSERVATIVE_FORM > 0.0)
461  {
462  //u momentum accumulation
463  mom_u_acc=u;//trick for non-conservative form
464  dmom_u_acc_u=rho*porosity;
465 
466  //v momentum accumulation
467  mom_v_acc=v;
468  dmom_v_acc_v=rho*porosity;
469 
470  //w momentum accumulation
471  mom_w_acc=w;
472  dmom_w_acc_w=rho*porosity;
473 
474  //mass advective flux
475  mass_adv[0]=porosity*u;
476  mass_adv[1]=porosity*v;
477  mass_adv[2]=porosity*w;
478 
479  dmass_adv_u[0]=porosity;
480  dmass_adv_u[1]=0.0;
481  dmass_adv_u[2]=0.0;
482 
483  dmass_adv_v[0]=0.0;
484  dmass_adv_v[1]=porosity;
485  dmass_adv_v[2]=0.0;
486 
487  dmass_adv_w[0]=0.0;
488  dmass_adv_w[1]=0.0;
489  dmass_adv_w[2]=porosity;
490 
491  //u momentum advective flux
492  mom_u_adv[0]=0.0;
493  mom_u_adv[1]=0.0;
494  mom_u_adv[2]=0.0;
495 
496  dmom_u_adv_u[0]=0.0;
497  dmom_u_adv_u[1]=0.0;
498  dmom_u_adv_u[2]=0.0;
499 
500  dmom_u_adv_v[0]=0.0;
501  dmom_u_adv_v[1]=0.0;
502  dmom_u_adv_v[2]=0.0;
503 
504  dmom_u_adv_w[0]=0.0;
505  dmom_u_adv_w[1]=0.0;
506  dmom_u_adv_w[2]=0.0;
507 
508  //v momentum advective_flux
509  mom_v_adv[0]=0.0;
510  mom_v_adv[1]=0.0;
511  mom_v_adv[2]=0.0;
512 
513  dmom_v_adv_u[0]=0.0;
514  dmom_v_adv_u[1]=0.0;
515  dmom_v_adv_u[2]=0.0;
516 
517  dmom_v_adv_w[0]=0.0;
518  dmom_v_adv_w[1]=0.0;
519  dmom_v_adv_w[2]=0.0;
520 
521  dmom_v_adv_v[0]=0.0;
522  dmom_v_adv_v[1]=0.0;
523  dmom_v_adv_v[2]=0.0;
524 
525  //w momentum advective_flux
526  mom_w_adv[0]=0.0;
527  mom_w_adv[1]=0.0;
528  mom_w_adv[2]=0.0;
529 
530  dmom_w_adv_u[0]=0.0;
531  dmom_w_adv_u[1]=0.0;
532  dmom_w_adv_u[2]=0.0;
533 
534  dmom_w_adv_v[0]=0.0;
535  dmom_w_adv_v[1]=0.0;
536  dmom_w_adv_v[2]=0.0;
537 
538  dmom_w_adv_w[0]=0.0;
539  dmom_w_adv_w[1]=0.0;
540  dmom_w_adv_w[2]=0.0;
541 
542  //u momentum diffusion tensor
543  mom_uu_diff_ten[0] = 2.0*porosity*mu;
544  mom_uu_diff_ten[1] = porosity*mu;
545  mom_uu_diff_ten[2] = porosity*mu;
546 
547  mom_uv_diff_ten[0]=porosity*mu;
548 
549  mom_uw_diff_ten[0]=porosity*mu;
550 
551  //v momentum diffusion tensor
552  mom_vv_diff_ten[0] = porosity*mu;
553  mom_vv_diff_ten[1] = 2.0*porosity*mu;
554  mom_vv_diff_ten[2] = porosity*mu;
555 
556  mom_vu_diff_ten[0]=porosity*mu;
557 
558  mom_vw_diff_ten[0]=porosity*mu;
559 
560  //w momentum diffusion tensor
561  mom_ww_diff_ten[0] = porosity*mu;
562  mom_ww_diff_ten[1] = porosity*mu;
563  mom_ww_diff_ten[2] = 2.0*porosity*mu;
564 
565  mom_wu_diff_ten[0]=porosity*mu;
566 
567  mom_wv_diff_ten[0]=porosity*mu;
568 
569  //momentum sources
570  norm_n = sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);
571  mom_u_source = -porosity*rho*g[0];// - porosity*d_mu*sigma*kappa*n[0];
572  mom_v_source = -porosity*rho*g[1];// - porosity*d_mu*sigma*kappa*n[1];
573  mom_w_source = -porosity*rho*g[2];// - porosity*d_mu*sigma*kappa*n[2];
574 
575  //u momentum Hamiltonian (pressure)
576  mom_u_ham = porosity*grad_p[0];
577  dmom_u_ham_grad_p[0]=porosity;
578  dmom_u_ham_grad_p[1]=0.0;
579  dmom_u_ham_grad_p[2]=0.0;
580 
581  //v momentum Hamiltonian (pressure)
582  mom_v_ham = porosity*grad_p[1];
583  dmom_v_ham_grad_p[0]=0.0;
584  dmom_v_ham_grad_p[1]=porosity;
585  dmom_v_ham_grad_p[2]=0.0;
586 
587  //w momentum Hamiltonian (pressure)
588  mom_w_ham = porosity*grad_p[2];
589  dmom_w_ham_grad_p[0]=0.0;
590  dmom_w_ham_grad_p[1]=0.0;
591  dmom_w_ham_grad_p[2]=porosity;
592 
593  //u momentum Hamiltonian (advection)
594  mom_u_ham += inertial_term*rho*porosity*(u*grad_u[0]+v*grad_u[1]+w*grad_u[2]);
595  dmom_u_ham_grad_u[0]=inertial_term*rho*porosity*u;
596  dmom_u_ham_grad_u[1]=inertial_term*rho*porosity*v;
597  dmom_u_ham_grad_u[2]=inertial_term*rho*porosity*w;
598  dmom_u_ham_u =inertial_term*rho*porosity*grad_u[0];
599  dmom_u_ham_v =inertial_term*rho*porosity*grad_u[1];
600  dmom_u_ham_w =inertial_term*rho*porosity*grad_u[2];
601 
602  //v momentum Hamiltonian (advection)
603  mom_v_ham += inertial_term*rho*porosity*(u*grad_v[0]+v*grad_v[1]+w*grad_v[2]);
604  dmom_v_ham_grad_v[0]=inertial_term*rho*porosity*u;
605  dmom_v_ham_grad_v[1]=inertial_term*rho*porosity*v;
606  dmom_v_ham_grad_v[2]=inertial_term*rho*porosity*w;
607  dmom_v_ham_u =inertial_term*rho*porosity*grad_v[0];
608  dmom_v_ham_v =inertial_term*rho*porosity*grad_v[1];
609  dmom_v_ham_w =inertial_term*rho*porosity*grad_v[2];
610 
611  /* //w momentum Hamiltonian (advection) */
612  mom_w_ham += inertial_term*rho*porosity*(u*grad_w[0]+v*grad_w[1]+w*grad_w[2]);
613  dmom_w_ham_grad_w[0]=inertial_term*rho*porosity*u;
614  dmom_w_ham_grad_w[1]=inertial_term*rho*porosity*v;
615  dmom_w_ham_grad_w[2]=inertial_term*rho*porosity*w;
616  dmom_w_ham_u =inertial_term*rho*porosity*grad_w[0];
617  dmom_w_ham_v =inertial_term*rho*porosity*grad_w[1];
618  dmom_w_ham_w =inertial_term*rho*porosity*grad_w[2];
619 
620  }
621  else
622  {
623  //u momentum accumulation
624  mom_u_acc=porosity*u;
625  dmom_u_acc_u=porosity;
626 
627  //v momentum accumulation
628  mom_v_acc=porosity*v;
629  dmom_v_acc_v=porosity;
630 
631  //w momentum accumulation
632  mom_w_acc=porosity*w;
633  dmom_w_acc_w=porosity;
634 
635  //mass advective flux
636  mass_adv[0]=porosity*u;
637  mass_adv[1]=porosity*v;
638  mass_adv[2]=porosity*w;
639 
640  dmass_adv_u[0]=porosity;
641  dmass_adv_u[1]=0.0;
642  dmass_adv_u[2]=0.0;
643 
644  dmass_adv_v[0]=0.0;
645  dmass_adv_v[1]=porosity;
646  dmass_adv_v[2]=0.0;
647 
648  dmass_adv_w[0]=0.0;
649  dmass_adv_w[1]=0.0;
650  dmass_adv_w[2]=porosity;
651 
652  //u momentum advective flux
653  mom_u_adv[0]=inertial_term*porosity*u*u;
654  mom_u_adv[1]=inertial_term*porosity*u*v;
655  mom_u_adv[2]=inertial_term*porosity*u*w;
656 
657  dmom_u_adv_u[0]=inertial_term*2.0*porosity*u;
658  dmom_u_adv_u[1]=inertial_term*porosity*v;
659  dmom_u_adv_u[2]=inertial_term*porosity*w;
660 
661  dmom_u_adv_v[0]=0.0;
662  dmom_u_adv_v[1]=inertial_term*porosity*u;
663  dmom_u_adv_v[2]=0.0;
664 
665  dmom_u_adv_w[0]=0.0;
666  dmom_u_adv_w[1]=0.0;
667  dmom_u_adv_w[2]=inertial_term*porosity*u;
668 
669  //v momentum advective_flux
670  mom_v_adv[0]=inertial_term*porosity*v*u;
671  mom_v_adv[1]=inertial_term*porosity*v*v;
672  mom_v_adv[2]=inertial_term*porosity*v*w;
673 
674  dmom_v_adv_u[0]=inertial_term*porosity*v;
675  dmom_v_adv_u[1]=0.0;
676  dmom_v_adv_u[2]=0.0;
677 
678  dmom_v_adv_w[0]=0.0;
679  dmom_v_adv_w[1]=0.0;
680  dmom_v_adv_w[2]=inertial_term*porosity*v;
681 
682  dmom_v_adv_v[0]=inertial_term*porosity*u;
683  dmom_v_adv_v[1]=inertial_term*2.0*porosity*v;
684  dmom_v_adv_v[2]=inertial_term*porosity*w;
685 
686  //w momentum advective_flux
687  mom_w_adv[0]=inertial_term*porosity*w*u;
688  mom_w_adv[1]=inertial_term*porosity*w*v;
689  mom_w_adv[2]=inertial_term*porosity*w*w;
690 
691  dmom_w_adv_u[0]=inertial_term*porosity*w;
692  dmom_w_adv_u[1]=0.0;
693  dmom_w_adv_u[2]=0.0;
694 
695  dmom_w_adv_v[0]=0.0;
696  dmom_w_adv_v[1]=inertial_term*porosity*w;
697  dmom_w_adv_v[2]=0.0;
698 
699  dmom_w_adv_w[0]=inertial_term*porosity*u;
700  dmom_w_adv_w[1]=inertial_term*porosity*v;
701  dmom_w_adv_w[2]=inertial_term*2.0*porosity*w;
702 
703  //u momentum diffusion tensor
704  mom_uu_diff_ten[0] = 2.0*porosity*nu;
705  mom_uu_diff_ten[1] = porosity*nu;
706  mom_uu_diff_ten[2] = porosity*nu;
707 
708  mom_uv_diff_ten[0]=porosity*nu;
709 
710  mom_uw_diff_ten[0]=porosity*nu;
711 
712  //v momentum diffusion tensor
713  mom_vv_diff_ten[0] = porosity*nu;
714  mom_vv_diff_ten[1] = 2.0*porosity*nu;
715  mom_vv_diff_ten[2] = porosity*nu;
716 
717  mom_vu_diff_ten[0]=porosity*nu;
718 
719  mom_vw_diff_ten[0]=porosity*nu;
720 
721  //w momentum diffusion tensor
722  mom_ww_diff_ten[0] = porosity*nu;
723  mom_ww_diff_ten[1] = porosity*nu;
724  mom_ww_diff_ten[2] = 2.0*porosity*nu;
725 
726  mom_wu_diff_ten[0]=porosity*nu;
727 
728  mom_wv_diff_ten[0]=porosity*nu;
729 
730  //momentum sources
731  norm_n = sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);
732  mom_u_source = -porosity*g[0];// - porosity*d_mu*sigma*kappa*n[0]/(rho*(norm_n+1.0e-8));
733  mom_v_source = -porosity*g[1];// - porosity*d_mu*sigma*kappa*n[1]/(rho*(norm_n+1.0e-8));
734  mom_w_source = -porosity*g[2];// - porosity*d_mu*sigma*kappa*n[2]/(rho*(norm_n+1.0e-8));
735 
736  //u momentum Hamiltonian (pressure)
737  mom_u_ham = porosity*grad_p[0]/rho;
738  dmom_u_ham_grad_p[0]=porosity/rho;
739  dmom_u_ham_grad_p[1]=0.0;
740  dmom_u_ham_grad_p[2]=0.0;
741 
742  //v momentum Hamiltonian (pressure)
743  mom_v_ham = porosity*grad_p[1]/rho;
744  dmom_v_ham_grad_p[0]=0.0;
745  dmom_v_ham_grad_p[1]=porosity/rho;
746  dmom_v_ham_grad_p[2]=0.0;
747 
748  //w momentum Hamiltonian (pressure)
749  mom_w_ham = porosity*grad_p[2]/rho;
750  dmom_w_ham_grad_p[0]=0.0;
751  dmom_w_ham_grad_p[1]=0.0;
752  dmom_w_ham_grad_p[2]=porosity/rho;
753 
754  //u momentum Hamiltonian (advection)
755  dmom_u_ham_grad_u[0]=0.0;
756  dmom_u_ham_grad_u[1]=0.0;
757  dmom_u_ham_grad_u[2]=0.0;
758  dmom_u_ham_u =0.0;
759  dmom_u_ham_v =0.0;
760  dmom_u_ham_w =0.0;
761 
762  //v momentum Hamiltonian (advection)
763  dmom_v_ham_grad_v[0]=0.0;
764  dmom_v_ham_grad_v[1]=0.0;
765  dmom_v_ham_grad_v[2]=0.0;
766  dmom_v_ham_u =0.0;
767  dmom_v_ham_v =0.0;
768  dmom_v_ham_w =0.0;
769 
770  //w momentum Hamiltonian (advection)
771  dmom_w_ham_grad_w[0]=0.0;
772  dmom_w_ham_grad_w[1]=0.0;
773  dmom_w_ham_grad_w[2]=0.0;
774  dmom_w_ham_u =0.0;
775  dmom_w_ham_v =0.0;
776  dmom_w_ham_w =0.0;
777  }
778  mom_u_source -= forcex;
779  mom_v_source -= forcey;
780  mom_w_source -= forcez;
781  }
782 
783  int get_distance_to_ball(int n_balls,const double* ball_center, const double* ball_radius, const double x, const double y, const double z, double& distance)
784  {
785  distance = 1e10;
786  int index = -1;
787  double d_ball_i;
788  for (int i=0; i<n_balls; ++i)
789  {
790  d_ball_i = std::sqrt((ball_center[i*3+0]-x)*(ball_center[i*3+0]-x)
791  +(ball_center[i*3+1]-y)*(ball_center[i*3+1]-y)
792  +(ball_center[i*3+2]-z)*(ball_center[i*3+2]-z)
793  ) - ball_radius[i];
794  if(d_ball_i<distance)
795  {
796  distance = d_ball_i;
797  index = i;
798  }
799  }
800  return index;
801  }
802 
803  void get_distance_to_ith_ball(int n_balls,const double* ball_center, const double* ball_radius,
804  int I,
805  const double x, const double y, const double z,
806  double& distance)
807  {
808  distance = std::sqrt((ball_center[I*3+0]-x)*(ball_center[I*3+0]-x)
809  + (ball_center[I*3+1]-y)*(ball_center[I*3+1]-y)
810  + (ball_center[I*3+2]-z)*(ball_center[I*3+2]-z)
811  ) - ball_radius[I];
812  }
813  void get_normal_to_ith_ball(int n_balls,const double* ball_center, const double* ball_radius,
814  int I,
815  const double x, const double y, const double z,
816  double& nx, double& ny, double& nz)
817  {
818  double distance = std::sqrt((ball_center[I*3+0]-x)*(ball_center[I*3+0]-x)
819  + (ball_center[I*3+1]-y)*(ball_center[I*3+1]-y)
820  + (ball_center[I*3+2]-z)*(ball_center[I*3+2]-z)
821  );
822  if (distance > 1.0e-8)
823  {
824  nx = (x - ball_center[I*3+0])/distance;
825  ny = (y - ball_center[I*3+1])/distance;
826  nz = (z - ball_center[I*3+2])/distance;
827  assert(std::fabs(std::sqrt(nx*nx + ny*ny + nz*nz) - 1.0) < 1.0e-10);
828  }
829  else
830  {
831  nx = 1.0;
832  ny = 0.0;
833  nz = 0.0;
834  }
835  }
836  void get_cross_product(const double *u, const double *v,double res[3])
837  {
838  res[0] = u[1]*v[2]-u[2]*v[1];
839  res[1] = u[2]*v[0]-u[0]*v[2];
840  res[2] = u[0]*v[1]-u[1]*v[0];
841  }
842  void get_velocity_to_ith_ball(int n_balls,const double* ball_center, const double* ball_radius,
843  const double* ball_velocity, const double* ball_angular_velocity,
844  int I,
845  const double x, const double y, const double z,
846  double& vx, double& vy, double& vz)
847  {
848  double position[3]={x-ball_center[3*I + 0],y-ball_center[3*I + 1],z-ball_center[3*I + 2]};
849  double angular_cross_position[3];
850  get_cross_product(&ball_angular_velocity[3*I + 0],position,angular_cross_position);
851  vx = ball_velocity[3*I + 0] + angular_cross_position[0];
852  vy = ball_velocity[3*I + 1] + angular_cross_position[1];
853  vz = ball_velocity[3*I + 2] + angular_cross_position[2];
854 
855  }
856  inline void updateSolidParticleTerms(int particle_index,
857  const double NONCONSERVATIVE_FORM,
858  bool element_owned,
859  const double particle_nitsche,
860  const double dV,
861  const int nParticles,
862  const int sd_offset,
863  double* particle_signed_distances,
864  double* particle_signed_distance_normals,
865  double* particle_velocities,
866  double* particle_centroids,
867  const int use_ball_as_particle,
868  const double* ball_center,
869  const double* ball_radius,
870  const double* ball_velocity,
871  const double* ball_angular_velocity,
872  const double* ball_density,
873  const double porosity, //VRANS specific
874  const double penalty,
875  const double alpha,
876  const double beta,
877  const double eps_rho,
878  const double eps_mu,
879  const double rho_0,
880  const double nu_0,
881  const double rho_1,
882  const double nu_1,
883  const double useVF,
884  const double vf,
885  const double phi,
886  const double x,
887  const double y,
888  const double z,
889  const double p,
890  const double u,
891  const double v,
892  const double w,
893  const double uStar,
894  const double vStar,
895  const double wStar,
896  const double eps_s,
897  const double grad_u[nSpace],
898  const double grad_v[nSpace],
899  const double grad_w[nSpace],
900  double &mass_source,
901  double &mom_u_source,
902  double &mom_v_source,
903  double &mom_w_source,
904  double dmom_u_source[nSpace],
905  double dmom_v_source[nSpace],
906  double dmom_w_source[nSpace],
907  double mom_u_adv[nSpace],
908  double mom_v_adv[nSpace],
909  double mom_w_adv[nSpace],
910  double dmom_u_adv_u[nSpace],
911  double dmom_v_adv_v[nSpace],
912  double dmom_w_adv_w[nSpace],
913  double &mom_u_ham,
914  double dmom_u_ham_grad_u[nSpace],
915  double dmom_u_ham_grad_v[nSpace],
916  double dmom_u_ham_grad_w[nSpace],
917  double &dmom_u_ham_u,
918  double &dmom_u_ham_v,
919  double &dmom_u_ham_w,
920  double &mom_v_ham,
921  double dmom_v_ham_grad_u[nSpace],
922  double dmom_v_ham_grad_v[nSpace],
923  double dmom_v_ham_grad_w[nSpace],
924  double &dmom_v_ham_u,
925  double &dmom_v_ham_v,
926  double &dmom_v_ham_w,
927  double &mom_w_ham,
928  double dmom_w_ham_grad_u[nSpace],
929  double dmom_w_ham_grad_v[nSpace],
930  double dmom_w_ham_grad_w[nSpace],
931  double &dmom_w_ham_u,
932  double &dmom_w_ham_v,
933  double &dmom_w_ham_w,
934  double &mass_ham,
935  double &dmass_ham_u,
936  double &dmass_ham_v,
937  double &dmass_ham_w,
938  double *particle_netForces,
939  double *particle_netMoments,
940  double *particle_surfaceArea)
941  {
942  double C, rho, mu, nu, H_mu, ImH_mu, uc, duc_du, duc_dv, duc_dw, H_s, ImH_s, D_s, phi_s, u_s, v_s, w_s;
943  double force_x, force_y, force_z, r_x, r_y, r_z, force_p_x, force_p_y, force_p_z, force_stress_x, force_stress_y, force_stress_z;
944  double phi_s_normal[nSpace]=ZEROVEC;
945  double fluid_outward_normal[nSpace]=ZEROVEC;
946  double vel[nSpace]=ZEROVEC;
947  double center[nSpace]=ZEROVEC;
948  H_mu = (1.0 - useVF) * gf.H(eps_mu, phi) + useVF * fmin(1.0, fmax(0.0, vf));
949  ImH_mu = (1.0 - useVF) * gf.ImH(eps_mu, phi) + useVF * (1.0-fmin(1.0, fmax(0.0, vf)));
950  nu = nu_0 * ImH_mu + nu_1 * H_mu;
951  rho = rho_0 * ImH_mu + rho_1 * H_mu;
952  mu = rho_0 * nu_0 * ImH_mu + rho_1 * nu_1 * H_mu;
953  C = 0.0;
954  for (int i = particle_index; i < particle_index+1; i++)//cek hack to leave loop for the moment
955  {
956  if(use_ball_as_particle==1)
957  {
958  get_distance_to_ith_ball(nParticles,ball_center,ball_radius,i,x,y,z,phi_s);
959  get_velocity_to_ith_ball(nParticles,ball_center,ball_radius,
960  ball_velocity,ball_angular_velocity,
961  i,x,y,z,
962  vel[0],vel[1],vel[2]);
963  center[0] = ball_center[3*i+0];
964  center[1] = ball_center[3*i+1];
965  center[2] = ball_center[3*i+2];
966  particle_velocities[0] = vel[0];
967  particle_velocities[1] = vel[1];
968  particle_velocities[2] = vel[2];
969  }
970  else
971  {
972  phi_s = particle_signed_distances[i * sd_offset];
973  vel[0] = particle_velocities[i * sd_offset * 3 + 0];
974  vel[1] = particle_velocities[i * sd_offset * 3 + 1];
975  vel[2] = particle_velocities[i * sd_offset * 3 + 2];
976  center[0] = particle_centroids[3*i+0];
977  center[1] = particle_centroids[3*i+1];
978  center[2] = particle_centroids[3*i+2];
979  }
980  for (int I=0;I<nSpace;I++)
981  phi_s_normal[I] = particle_signed_distance_normals[I];
982  assert(std::fabs(1.0-std::sqrt(phi_s_normal[0]*phi_s_normal[0] + phi_s_normal[1]*phi_s_normal[1] + phi_s_normal[2]*phi_s_normal[2])) < 1.0e-8);
983  /* if (fabs(vel[0] - particle_velocities[i * sd_offset * 3 + 0])> 1.0e-12) */
984  /* std::cout<<"vel[0] "<<vel[0]<<'\t'<<particle_velocities[3*i+0]<<std::endl; */
985  /* if(fabs(vel[1] - particle_velocities[i * sd_offset * 3 + 1])> 1.0e-12) */
986  /* std::cout<<"vel[1] "<<vel[1]<<'\t'<<particle_velocities[3*i+1]<<std::endl; */
987  /* if(fabs(center[0] - particle_centroids[3*i+0])> 1.0e-12) */
988  /* std::cout<<"center[0] "<<center[0]<<'\t'<<particle_centroids[3*i+0]<<std::endl; */
989  /* if(fabs(center[1] - particle_centroids[3*i+1])> 1.0e-12) */
990  /* std::cout<<"center[1] "<<center[1]<<'\t'<<particle_centroids[3*i+1]<<std::endl; */
991  /* if(fabs(phi_s - particle_signed_distances[i * sd_offset]) > 1.0e-12) */
992  /* std::cout<<"phi_s "<<phi_s<<'\t'<<particle_signed_distances[i * sd_offset]<<std::endl; */
993  /* if(fabs(phi_s_normal[0] - particle_signed_distance_normals[i * sd_offset * 3 + 0]) > 1.0e-12) */
994  /* std::cout<<"phi_s_normal[0] "<<phi_s_normal[0]<<'\t'<<particle_signed_distance_normals[i * sd_offset*3 + 0]<<std::endl; */
995  /* if(fabs(phi_s_normal[1] - particle_signed_distance_normals[i * sd_offset * 3 + 1]) > 1.0e-12) */
996  /* std::cout<<"phi_s_normal[1] "<<phi_s_normal[1]<<'\t'<<particle_signed_distance_normals[i * sd_offset*3 + 1]<<std::endl; */
997 
998  fluid_outward_normal[0] = -phi_s_normal[0];
999  fluid_outward_normal[1] = -phi_s_normal[1];
1000  fluid_outward_normal[2] = -phi_s_normal[2];
1001  assert(std::fabs(1.0-std::sqrt(fluid_outward_normal[0]*fluid_outward_normal[0] + fluid_outward_normal[1]*fluid_outward_normal[1] + fluid_outward_normal[2]*fluid_outward_normal[2])) < 1.0e-8);
1002  u_s = vel[0];
1003  v_s = vel[1];
1004  w_s = vel[2];
1005  D_s = gf_s.D(eps_s, phi_s);
1006 
1007  double rel_vel_norm = sqrt((uStar - u_s) * (uStar - u_s) +
1008  (vStar - v_s) * (vStar - v_s) +
1009  (wStar - w_s) * (wStar - w_s));
1010  force_p_x = porosity * dV * D_s * p * fluid_outward_normal[0];
1011  force_p_y = porosity * dV * D_s * p * fluid_outward_normal[1];
1012  force_p_z = porosity * dV * D_s * p * fluid_outward_normal[2];
1013  force_stress_x = porosity * dV * D_s * (-mu*(fluid_outward_normal[0]*2*grad_u[0] + fluid_outward_normal[1]*(grad_u[1]+grad_v[0]) + fluid_outward_normal[2]*(grad_u[2]+grad_w[0]))
1014  +mu*penalty*(u-u_s));
1015  force_stress_y = porosity * dV * D_s * (-mu*(fluid_outward_normal[0]*(grad_v[0]+grad_u[1]) + fluid_outward_normal[1]*2*grad_v[1] + fluid_outward_normal[2]*(grad_v[2]+grad_w[1]))
1016  +mu*penalty*(v-v_s));
1017  force_stress_z = porosity * dV * D_s * (-mu*(fluid_outward_normal[0]*(grad_w[0]+grad_u[2]) + fluid_outward_normal[1]*(grad_w[1]+grad_v[2]) + fluid_outward_normal[2]*2*grad_w[2])
1018  +mu*penalty*(w-w_s));
1019  force_x = force_p_x + force_stress_x;
1020  force_y = force_p_y + force_stress_y;
1021  force_z = force_p_z + force_stress_z;
1022  //always 3D for particle centroids
1023  r_x = x - center[0];
1024  r_y = y - center[1];
1025  r_z = z - center[2];
1026 
1027  if (element_owned)
1028  {
1029  particle_surfaceArea[i] += dV * D_s;
1030  particle_netForces[i * 3 + 0] += force_x;
1031  particle_netForces[i * 3 + 1] += force_y;
1032  particle_netForces[i * 3 + 2] += force_z;
1033  particle_netForces[(i+ nParticles)*3+0]+= force_stress_x;
1034  particle_netForces[(i+2*nParticles)*3+0]+= force_p_x;
1035  particle_netForces[(i+ nParticles)*3+1]+= force_stress_y;
1036  particle_netForces[(i+2*nParticles)*3+1]+= force_p_y;
1037  particle_netForces[(i+ nParticles)*3+2]+= force_stress_z;
1038  particle_netForces[(i+2*nParticles)*3+2]+= force_p_z;
1039  particle_netMoments[i*3+0] += (r_y*force_z - r_z*force_y);
1040  particle_netMoments[i*3+1] += (r_z*force_x - r_x*force_z);
1041  particle_netMoments[i*3+2] += (r_x*force_y - r_y*force_x);
1042  }
1043 
1044 
1045  mass_source += D_s*(fluid_outward_normal[0]*u_s + fluid_outward_normal[1]*v_s + fluid_outward_normal[2]*w_s);
1046 
1047  if (NONCONSERVATIVE_FORM > 0.0)
1048  {
1049  //upwinded advective flux
1050  if (!UPWIND_DIRICHLET || (fluid_outward_normal[0]*u_s + fluid_outward_normal[1]*v_s + fluid_outward_normal[2]*w_s) < 0.0)
1051  {
1052  mom_u_source += rho*D_s*(u_s - u)*(fluid_outward_normal[0]*u_s + fluid_outward_normal[1]*v_s + fluid_outward_normal[2]*w_s);
1053  mom_v_source += rho*D_s*(v_s - v)*(fluid_outward_normal[0]*u_s + fluid_outward_normal[1]*v_s + fluid_outward_normal[2]*w_s);
1054  mom_w_source += rho*D_s*(w_s - w)*(fluid_outward_normal[0]*u_s + fluid_outward_normal[1]*v_s + fluid_outward_normal[2]*w_s);
1055  dmom_u_source[0] -= rho*D_s*(fluid_outward_normal[0]*u_s + fluid_outward_normal[1]*v_s + fluid_outward_normal[2]*w_s);
1056  dmom_v_source[1] -= rho*D_s*(fluid_outward_normal[0]*u_s + fluid_outward_normal[1]*v_s + fluid_outward_normal[2]*w_s);
1057  dmom_w_source[2] -= rho*D_s*(fluid_outward_normal[0]*u_s + fluid_outward_normal[1]*v_s + fluid_outward_normal[2]*w_s);
1058  }
1059 
1060  //viscous flux
1061  mom_u_ham -= D_s * porosity * mu * (fluid_outward_normal[0] * 2* grad_u[0] + fluid_outward_normal[1] * (grad_u[1]+grad_v[0]) + fluid_outward_normal[2] * (grad_u[2]+grad_w[0]));
1062  dmom_u_ham_grad_u[0] -= D_s * porosity * mu * 2 * fluid_outward_normal[0];
1063  dmom_u_ham_grad_u[1] -= D_s * porosity * mu * fluid_outward_normal[1];
1064  dmom_u_ham_grad_u[2] -= D_s * porosity * mu * fluid_outward_normal[2];
1065  dmom_u_ham_grad_v[0] -= D_s * porosity * mu * fluid_outward_normal[1];
1066  dmom_u_ham_grad_w[0] -= D_s * porosity * mu * fluid_outward_normal[2];
1067 
1068  mom_v_ham -= D_s * porosity * mu * (fluid_outward_normal[0] * (grad_u[1]+grad_v[0]) + fluid_outward_normal[1] * 2* grad_v[1] + fluid_outward_normal[2] * (grad_w[1]+grad_v[2]));
1069  dmom_v_ham_grad_u[1] -= D_s * porosity * mu * fluid_outward_normal[0];
1070  dmom_v_ham_grad_v[0] -= D_s * porosity * mu * fluid_outward_normal[0];
1071  dmom_v_ham_grad_v[1] -= D_s * porosity * mu * 2 * fluid_outward_normal[1];
1072  dmom_v_ham_grad_v[2] -= D_s * porosity * mu * fluid_outward_normal[2];
1073  dmom_v_ham_grad_w[1] -= D_s * porosity * mu * fluid_outward_normal[2];
1074 
1075  mom_w_ham -= D_s * porosity * mu * (fluid_outward_normal[0] * (grad_u[2]+grad_w[0]) + fluid_outward_normal[1] * (grad_v[2]+grad_w[1]) + fluid_outward_normal[2]*2*grad_w[2]);
1076  dmom_w_ham_grad_u[2] -= D_s * porosity * mu * fluid_outward_normal[0];
1077  dmom_w_ham_grad_v[2] -= D_s * porosity * mu * fluid_outward_normal[1];
1078  dmom_w_ham_grad_w[0] -= D_s * porosity * mu * fluid_outward_normal[0];
1079  dmom_w_ham_grad_w[1] -= D_s * porosity * mu * fluid_outward_normal[1];
1080  dmom_w_ham_grad_w[2] -= D_s * porosity * mu * 2 * fluid_outward_normal[2];
1081 
1082  //Nitsche Dirichlet penalty
1083  mom_u_source += D_s*mu*penalty * (u - u_s);
1084  dmom_u_source[0] += D_s*mu*penalty;
1085 
1086  mom_v_source += D_s*mu*penalty * (v - v_s);
1087  dmom_v_source[1] += D_s*mu*penalty;
1088 
1089  mom_w_source += D_s*mu*penalty * (w - w_s);
1090  dmom_w_source[2] += D_s*mu*penalty;
1091 
1092  //Nitsche adjoint consistency
1093  mom_u_adv[0] += D_s * porosity * mu * fluid_outward_normal[0] * (u - u_s);
1094  mom_u_adv[1] += D_s * porosity * mu * fluid_outward_normal[1] * (u - u_s);
1095  mom_u_adv[2] += D_s * porosity * mu * fluid_outward_normal[2] * (u - u_s);
1096  dmom_u_adv_u[0] += D_s * porosity * mu * fluid_outward_normal[0];
1097  dmom_u_adv_u[1] += D_s * porosity * mu * fluid_outward_normal[1];
1098  dmom_u_adv_u[2] += D_s * porosity * mu * fluid_outward_normal[2];
1099 
1100  mom_v_adv[0] += D_s * porosity * mu * fluid_outward_normal[0] * (v - v_s);
1101  mom_v_adv[1] += D_s * porosity * mu * fluid_outward_normal[1] * (v - v_s);
1102  mom_v_adv[2] += D_s * porosity * mu * fluid_outward_normal[2] * (v - v_s);
1103  dmom_v_adv_v[0] += D_s * porosity * mu * fluid_outward_normal[0];
1104  dmom_v_adv_v[1] += D_s * porosity * mu * fluid_outward_normal[1];
1105  dmom_v_adv_v[2] += D_s * porosity * mu * fluid_outward_normal[2];
1106 
1107  mom_w_adv[0] += D_s * porosity * mu * fluid_outward_normal[0] * (w - w_s);
1108  mom_w_adv[1] += D_s * porosity * mu * fluid_outward_normal[1] * (w - w_s);
1109  mom_w_adv[2] += D_s * porosity * mu * fluid_outward_normal[2] * (w - w_s);
1110  dmom_w_adv_w[0] += D_s * porosity * mu * fluid_outward_normal[0];
1111  dmom_w_adv_w[1] += D_s * porosity * mu * fluid_outward_normal[1];
1112  dmom_w_adv_w[2] += D_s * porosity * mu * fluid_outward_normal[2];
1113  }
1114  else
1115  {
1116  //divided through by rho...
1117  //upwinded advective flux
1118  if (!UPWIND_DIRICHLET || (fluid_outward_normal[0]*u_s + fluid_outward_normal[1]*v_s + fluid_outward_normal[2]*w_s) < 0.0)
1119  {
1120  mom_u_source += D_s*u_s*(fluid_outward_normal[0]*u_s + fluid_outward_normal[1]*v_s + fluid_outward_normal[2]*w_s);
1121  mom_v_source += D_s*v_s*(fluid_outward_normal[0]*u_s + fluid_outward_normal[1]*v_s + fluid_outward_normal[2]*w_s);
1122  mom_w_source += D_s*w_s*(fluid_outward_normal[0]*u_s + fluid_outward_normal[1]*v_s + fluid_outward_normal[2]*w_s);
1123  }
1124  else
1125  {
1126  mom_u_source += D_s*u*(fluid_outward_normal[0]*u_s + fluid_outward_normal[1]*v_s + fluid_outward_normal[2]*w_s);
1127  dmom_u_source[0] += D_s*(fluid_outward_normal[0]*u_s + fluid_outward_normal[1]*v_s + fluid_outward_normal[2]*w_s);
1128  mom_v_source += D_s*v*(fluid_outward_normal[0]*u_s + fluid_outward_normal[1]*v_s + fluid_outward_normal[2]*w_s);
1129  dmom_v_source[1] += D_s*(fluid_outward_normal[0]*u_s + fluid_outward_normal[1]*v_s + fluid_outward_normal[2]*w_s);
1130  mom_w_source += D_s*w*(fluid_outward_normal[0]*u_s + fluid_outward_normal[1]*v_s + fluid_outward_normal[2]*w_s);
1131  dmom_w_source[2] += D_s*(fluid_outward_normal[0]*u_s + fluid_outward_normal[1]*v_s + fluid_outward_normal[2]*w_s);
1132  }
1133 
1134  //viscous flux
1135  mom_u_ham -= D_s * porosity * nu * (fluid_outward_normal[0] * 2* grad_u[0] + fluid_outward_normal[1] * (grad_u[1]+grad_v[0]) + fluid_outward_normal[2] * (grad_u[2]+grad_w[0]));
1136  dmom_u_ham_grad_u[0] -= D_s * porosity * nu * 2 * fluid_outward_normal[0];
1137  dmom_u_ham_grad_u[1] -= D_s * porosity * nu * fluid_outward_normal[1];
1138  dmom_u_ham_grad_u[2] -= D_s * porosity * nu * fluid_outward_normal[2];
1139  dmom_u_ham_grad_v[0] -= D_s * porosity * nu * fluid_outward_normal[1];
1140  dmom_u_ham_grad_w[0] -= D_s * porosity * nu * fluid_outward_normal[2];
1141 
1142  mom_v_ham -= D_s * porosity * nu * (fluid_outward_normal[0] * (grad_u[1]+grad_v[0]) + fluid_outward_normal[1] * 2* grad_v[1] + fluid_outward_normal[2] * (grad_v[2]+grad_w[1]));
1143  dmom_v_ham_grad_u[1] -= D_s * porosity * nu * fluid_outward_normal[0];
1144  dmom_v_ham_grad_v[0] -= D_s * porosity * nu * fluid_outward_normal[0];
1145  dmom_v_ham_grad_v[1] -= D_s * porosity * nu * 2 * fluid_outward_normal[1];
1146  dmom_v_ham_grad_v[2] -= D_s * porosity * nu * fluid_outward_normal[2];
1147  dmom_v_ham_grad_w[1] -= D_s * porosity * nu * fluid_outward_normal[2];
1148 
1149  mom_w_ham -= D_s * porosity * nu * (fluid_outward_normal[0] * (grad_u[2]+grad_w[0]) + fluid_outward_normal[1] * (grad_v[2]+grad_w[1]) + fluid_outward_normal[2] * 2* grad_w[2] );
1150  dmom_w_ham_grad_u[2] -= D_s * porosity * nu * fluid_outward_normal[0];
1151  dmom_w_ham_grad_v[2] -= D_s * porosity * nu * fluid_outward_normal[1];
1152  dmom_w_ham_grad_w[0] -= D_s * porosity * nu * fluid_outward_normal[0];
1153  dmom_w_ham_grad_w[1] -= D_s * porosity * nu * fluid_outward_normal[1];
1154  dmom_w_ham_grad_w[2] -= D_s * porosity * nu * 2 * fluid_outward_normal[2];
1155 
1156  //Nitsche Dirichlet penalty
1157  mom_u_source += D_s*nu*penalty * (u - u_s);
1158  dmom_u_source[0] += D_s*nu*penalty;
1159 
1160  mom_v_source += D_s*nu*penalty * (v - v_s);
1161  dmom_v_source[1] += D_s*nu*penalty;
1162 
1163  mom_w_source += D_s*nu*penalty * (w - w_s);
1164  dmom_w_source[2] += D_s*nu*penalty;
1165 
1166  //Nitsche adjoint consistency
1167  mom_u_adv[0] += D_s * porosity * nu * fluid_outward_normal[0] * (u - u_s);
1168  mom_u_adv[1] += D_s * porosity * nu * fluid_outward_normal[1] * (u - u_s);
1169  mom_u_adv[2] += D_s * porosity * nu * fluid_outward_normal[2] * (u - u_s);
1170  dmom_u_adv_u[0] += D_s * porosity * nu * fluid_outward_normal[0];
1171  dmom_u_adv_u[1] += D_s * porosity * nu * fluid_outward_normal[1];
1172  dmom_u_adv_u[2] += D_s * porosity * nu * fluid_outward_normal[2];
1173 
1174  mom_v_adv[0] += D_s * porosity * nu * fluid_outward_normal[0] * (v - v_s);
1175  mom_v_adv[1] += D_s * porosity * nu * fluid_outward_normal[1] * (v - v_s);
1176  mom_v_adv[2] += D_s * porosity * nu * fluid_outward_normal[2] * (v - v_s);
1177  dmom_v_adv_v[0] += D_s * porosity * nu * fluid_outward_normal[0];
1178  dmom_v_adv_v[1] += D_s * porosity * nu * fluid_outward_normal[1];
1179  dmom_v_adv_v[2] += D_s * porosity * nu * fluid_outward_normal[2];
1180 
1181  mom_w_adv[0] += D_s * porosity * nu * fluid_outward_normal[0] * (w - w_s);
1182  mom_w_adv[1] += D_s * porosity * nu * fluid_outward_normal[1] * (w - w_s);
1183  mom_w_adv[2] += D_s * porosity * nu * fluid_outward_normal[2] * (w - w_s);
1184  dmom_w_adv_w[0] += D_s * porosity * nu * fluid_outward_normal[0];
1185  dmom_w_adv_w[1] += D_s * porosity * nu * fluid_outward_normal[1];
1186  dmom_w_adv_w[2] += D_s * porosity * nu * fluid_outward_normal[2];
1187  }
1188  }
1189  }
1190  //VRANS specific
1191  inline
1192  void updateDarcyForchheimerTerms_Ergun(const double NONCONSERVATIVE_FORM,
1193  /* const double linearDragFactor, */
1194  /* const double nonlinearDragFactor, */
1195  /* const double porosity, */
1196  /* const double meanGrainSize, */
1197  const double alpha,
1198  const double beta,
1199  const double eps_rho,
1200  const double eps_mu,
1201  const double rho_0,
1202  const double nu_0,
1203  const double rho_1,
1204  const double nu_1,
1205  const double useVF,
1206  const double vf,
1207  const double phi,
1208  const double u,
1209  const double v,
1210  const double w,
1211  const double uStar,
1212  const double vStar,
1213  const double wStar,
1214  const double eps_porous,
1215  const double phi_porous,
1216  const double u_porous,
1217  const double v_porous,
1218  const double w_porous,
1219  double& mom_u_source,
1220  double& mom_v_source,
1221  double& mom_w_source,
1222  double dmom_u_source[nSpace],
1223  double dmom_v_source[nSpace],
1224  double dmom_w_source[nSpace])
1225  {
1226  double rho,mu,nu,H_mu,ImH_mu, uc,duc_du,duc_dv,duc_dw,viscosity,H_porous;
1227  H_mu = (1.0-useVF)*gf.H(eps_mu,phi)+useVF*fmin(1.0,fmax(0.0,vf));
1228  ImH_mu = (1.0-useVF)*gf.ImH(eps_mu,phi)+useVF*(1.0-fmin(1.0,fmax(0.0,vf)));
1229  nu = nu_0*ImH_mu+nu_1*H_mu;
1230  rho = rho_0*ImH_mu+rho_1*H_mu;
1231  mu = rho_0*nu_0*ImH_mu+rho_1*nu_1*H_mu;
1232  if (NONCONSERVATIVE_FORM > 0.0)
1233  {
1234  viscosity = mu;
1235  }
1236  else
1237  {
1238  viscosity = nu;
1239  }
1240  double x = fmax(0.0, fmin( 1.0, 0.5+phi_porous/(2.0*eps_porous)));//0 at phi_porous = -eps, 1 at phi_porous=eps
1241 
1242  // Relaxation function, Jacobsen et al. 2011, Mayer et al 1998
1243  H_porous = (exp(pow(x,3.5)) - 1.)/ (exp(1.) - 1.);
1244 
1245  //implicit
1246  /* uc = sqrt(u*u+v*v*+w*w); */
1247  /* duc_du = u/(uc+1.0e-12); */
1248  /* duc_dv = v/(uc+1.0e-12); */
1249  /* duc_dw = w/(uc+1.0e-12); */
1250  //semi-implicit quadratic term
1251  uc = sqrt(uStar*uStar+vStar*vStar+wStar*wStar);
1252  duc_du = 0.0;
1253  duc_dv = 0.0;
1254  duc_dw = 0.0;
1255 
1256  mom_u_source += H_porous*viscosity*(alpha + beta*uc)*(u-u_porous);
1257  mom_v_source += H_porous*viscosity*(alpha + beta*uc)*(v-v_porous);
1258  mom_w_source += H_porous*viscosity*(alpha + beta*uc)*(w-w_porous);
1259 
1260  dmom_u_source[0] = H_porous*viscosity*(alpha + beta*uc + beta*duc_du*(u-u_porous));
1261  dmom_u_source[1] = H_porous*viscosity*beta*duc_dv*(u-u_porous);
1262  dmom_u_source[2] = H_porous*viscosity*beta*duc_dw*(u-u_porous);
1263 
1264  dmom_v_source[0] = H_porous*viscosity*beta*duc_du*(v-v_porous);
1265  dmom_v_source[1] = H_porous*viscosity*(alpha + beta*uc + beta*duc_dv*(v-v_porous));
1266  dmom_v_source[2] = H_porous*viscosity*beta*duc_dw*(v-v_porous);
1267 
1268  dmom_w_source[0] = H_porous*viscosity*beta*duc_du*(w-w_porous);
1269  dmom_w_source[1] = H_porous*viscosity*beta*duc_dv*(w-w_porous);
1270  dmom_w_source[2] = H_porous*viscosity*(alpha + beta*uc + beta*duc_dw*(w-w_porous));
1271  }
1272 
1273  inline
1274  void updateTurbulenceClosure(const double NONCONSERVATIVE_FORM,
1275  const int turbulenceClosureModel,
1276  const double eps_rho,
1277  const double eps_mu,
1278  const double rho_0,
1279  const double nu_0,
1280  const double rho_1,
1281  const double nu_1,
1282  const double useVF,
1283  const double vf,
1284  const double phi,
1285  const double porosity,
1286  const double eddy_visc_coef_0,
1287  const double turb_var_0, //k for k-eps or k-omega
1288  const double turb_var_1, //epsilon for k-epsilon, omega for k-omega
1289  const double turb_grad_0[nSpace],//grad k for k-eps,k-omega
1290  double& eddy_viscosity,
1291  double mom_uu_diff_ten[nSpace],
1292  double mom_vv_diff_ten[nSpace],
1293  double mom_ww_diff_ten[nSpace],
1294  double mom_uv_diff_ten[1],
1295  double mom_uw_diff_ten[1],
1296  double mom_vu_diff_ten[1],
1297  double mom_vw_diff_ten[1],
1298  double mom_wu_diff_ten[1],
1299  double mom_wv_diff_ten[1],
1300  double& mom_u_source,
1301  double& mom_v_source,
1302  double& mom_w_source)
1303  {
1304  /****
1305  eddy_visc_coef
1306  <= 2 LES (do nothing)
1307  == 3 k-epsilon
1308 
1309  */
1310  assert (turbulenceClosureModel >=3);
1311  double rho,nu,H_mu,ImH_mu, nu_t=0.0,nu_t_keps =0.0, nu_t_komega=0.0;
1312  double isKEpsilon = 1.0, dynamic_eddy_viscosity = 0.0;
1313 
1314  if (turbulenceClosureModel == 4)
1315  isKEpsilon = 0.0;
1316  H_mu = (1.0-useVF)*gf.H(eps_mu,phi)+useVF*fmin(1.0,fmax(0.0,vf));
1317  ImH_mu = (1.0-useVF)*gf.ImH(eps_mu,phi)+useVF*(1.0-fmin(1.0,fmax(0.0,vf)));
1318  nu = nu_0*ImH_mu+nu_1*H_mu;
1319  rho = rho_0*ImH_mu+rho_1*H_mu;
1320 
1321  const double twoThirds = 2.0/3.0; const double div_zero = 1.0e-2*fmin(nu_0,nu_1);
1322  mom_u_source += twoThirds*turb_grad_0[0];
1323  mom_v_source += twoThirds*turb_grad_0[1];
1324  mom_w_source += twoThirds*turb_grad_0[2];
1325 
1326  //--- closure model specific ---
1327  //k-epsilon
1328  nu_t_keps = eddy_visc_coef_0*turb_var_0*turb_var_0/(fabs(turb_var_1) + div_zero);
1329  //k-omega
1330  nu_t_komega = turb_var_0/(fabs(turb_var_1) + div_zero);
1331  //
1332  nu_t = isKEpsilon*nu_t_keps + (1.0-isKEpsilon)*nu_t_komega;
1333 
1334  nu_t = fmax(nu_t,1.0e-4*nu); //limit according to Lew, Buscaglia etal 01
1335  //mwf hack
1336  nu_t = fmin(nu_t,1.0e6*nu);
1337  eddy_viscosity = nu_t;
1338  if (NONCONSERVATIVE_FORM > 0.0)
1339  {
1340  dynamic_eddy_viscosity = nu_t*rho;
1341  //u momentum diffusion tensor
1342  mom_uu_diff_ten[0] += 2.0*porosity*dynamic_eddy_viscosity;
1343  mom_uu_diff_ten[1] += porosity*dynamic_eddy_viscosity;
1344  mom_uu_diff_ten[2] += porosity*dynamic_eddy_viscosity;
1345 
1346  mom_uv_diff_ten[0] +=porosity*dynamic_eddy_viscosity;
1347 
1348  mom_uw_diff_ten[0] +=porosity*dynamic_eddy_viscosity;
1349 
1350  //v momentum diffusion tensor
1351  mom_vv_diff_ten[0] += porosity*dynamic_eddy_viscosity;
1352  mom_vv_diff_ten[1] += 2.0*porosity*dynamic_eddy_viscosity;
1353  mom_vv_diff_ten[2] += porosity*dynamic_eddy_viscosity;
1354 
1355  mom_vu_diff_ten[0] += porosity*dynamic_eddy_viscosity;
1356 
1357  mom_vw_diff_ten[0] += porosity*dynamic_eddy_viscosity;
1358 
1359  //w momentum diffusion tensor
1360  mom_ww_diff_ten[0] += porosity*dynamic_eddy_viscosity;
1361  mom_ww_diff_ten[1] += porosity*dynamic_eddy_viscosity;
1362  mom_ww_diff_ten[2] += 2.0*porosity*dynamic_eddy_viscosity;
1363 
1364  mom_wu_diff_ten[0] += porosity*dynamic_eddy_viscosity;
1365 
1366  mom_wv_diff_ten[0] += porosity*dynamic_eddy_viscosity;
1367  }
1368  else
1369  {
1370  //u momentum diffusion tensor
1371  mom_uu_diff_ten[0] += 2.0*porosity*eddy_viscosity;
1372  mom_uu_diff_ten[1] += porosity*eddy_viscosity;
1373  mom_uu_diff_ten[2] += porosity*eddy_viscosity;
1374 
1375  mom_uv_diff_ten[0]+=porosity*eddy_viscosity;
1376 
1377  mom_uw_diff_ten[0]+=porosity*eddy_viscosity;
1378 
1379  //v momentum diffusion tensor
1380  mom_vv_diff_ten[0] += porosity*eddy_viscosity;
1381  mom_vv_diff_ten[1] += 2.0*porosity*eddy_viscosity;
1382  mom_vv_diff_ten[2] += porosity*eddy_viscosity;
1383 
1384  mom_vu_diff_ten[0]+=porosity*eddy_viscosity;
1385 
1386  mom_vw_diff_ten[0]+=porosity*eddy_viscosity;
1387 
1388  //w momentum diffusion tensor
1389  mom_ww_diff_ten[0] += porosity*eddy_viscosity;
1390  mom_ww_diff_ten[1] += porosity*eddy_viscosity;
1391  mom_ww_diff_ten[2] += 2.0*porosity*eddy_viscosity;
1392 
1393  mom_wu_diff_ten[0]+=porosity*eddy_viscosity;
1394 
1395  mom_wv_diff_ten[0]+=porosity*eddy_viscosity;
1396  }
1397  }
1398 
1399  inline
1400  void calculateSubgridError_tau(const double& hFactor,
1401  const double& elementDiameter,
1402  const double& dmt,
1403  const double& dm,
1404  const double df[nSpace],
1405  const double& a,
1406  const double& pfac,
1407  double& tau_v,
1408  double& tau_p,
1409  double& cfl)
1410  {
1411  double h,oneByAbsdt,density,viscosity,nrm_df;
1412  h = hFactor*elementDiameter;
1413  density = dm;
1414  viscosity = a;
1415  nrm_df=0.0;
1416  for(int I=0;I<nSpace;I++)
1417  nrm_df+=df[I]*df[I];
1418  nrm_df = sqrt(nrm_df);
1419  cfl = nrm_df/(h*density);//this is really cfl/dt, but that's what we want to know, the step controller expect this
1420  oneByAbsdt = fabs(dmt);
1421  tau_v = 1.0/(4.0*viscosity/(h*h) + inertial_term*(2.0*nrm_df/h + oneByAbsdt));
1422  tau_p = (4.0*viscosity + inertial_term*(2.0*nrm_df*h + oneByAbsdt*h*h))/pfac;
1423  }
1424 
1425  inline
1426  void calculateSubgridError_tau( const double& Ct_sge,
1427  const double& Cd_sge,
1428  const double G[nSpace*nSpace],
1429  const double& G_dd_G,
1430  const double& tr_G,
1431  const double& A0,
1432  const double Ai[nSpace],
1433  const double& Kij,
1434  const double& pfac,
1435  double& tau_v,
1436  double& tau_p,
1437  double& q_cfl)
1438  {
1439  double v_d_Gv=0.0;
1440  for(int I=0;I<nSpace;I++)
1441  for (int J=0;J<nSpace;J++)
1442  v_d_Gv += Ai[I]*G[I*nSpace+J]*Ai[J];
1443  tau_v = 1.0/sqrt(inertial_term*(Ct_sge*A0*A0 + v_d_Gv + 1.0e-12) + Cd_sge*Kij*Kij*G_dd_G);
1444  tau_p = 1.0/(pfac*tr_G*tau_v);
1445  }
1446 
1447  inline
1448  void calculateSubgridError_tauRes(const double& tau_p,
1449  const double& tau_v,
1450  const double& pdeResidualP,
1451  const double& pdeResidualU,
1452  const double& pdeResidualV,
1453  const double& pdeResidualW,
1454  double& subgridErrorP,
1455  double& subgridErrorU,
1456  double& subgridErrorV,
1457  double& subgridErrorW)
1458  {
1459  /* GLS pressure */
1460  subgridErrorP = -tau_p*pdeResidualP;
1461  /* GLS momentum */
1462  subgridErrorU = -tau_v*pdeResidualU;
1463  subgridErrorV = -tau_v*pdeResidualV;
1464  subgridErrorW = -tau_v*pdeResidualW;
1465  }
1466 
1467  inline
1469  const double& tau_v,
1470  const double dpdeResidualP_du[nDOF_v_trial_element],
1471  const double dpdeResidualP_dv[nDOF_v_trial_element],
1472  const double dpdeResidualP_dw[nDOF_v_trial_element],
1473  const double dpdeResidualU_dp[nDOF_trial_element],
1474  const double dpdeResidualU_du[nDOF_v_trial_element],
1475  const double dpdeResidualV_dp[nDOF_trial_element],
1476  const double dpdeResidualV_dv[nDOF_v_trial_element],
1477  const double dpdeResidualW_dp[nDOF_trial_element],
1478  const double dpdeResidualW_dw[nDOF_v_trial_element],
1479  double dsubgridErrorP_du[nDOF_v_trial_element],
1480  double dsubgridErrorP_dv[nDOF_v_trial_element],
1481  double dsubgridErrorP_dw[nDOF_v_trial_element],
1482  double dsubgridErrorU_dp[nDOF_trial_element],
1483  double dsubgridErrorU_du[nDOF_v_trial_element],
1484  double dsubgridErrorV_dp[nDOF_trial_element],
1485  double dsubgridErrorV_dv[nDOF_v_trial_element],
1486  double dsubgridErrorW_dp[nDOF_trial_element],
1487  double dsubgridErrorW_dw[nDOF_v_trial_element])
1488  {
1489  for (int j=0;j<nDOF_v_trial_element;j++)
1490  {
1491  /* GLS pressure */
1492  dsubgridErrorP_du[j] = -tau_p*dpdeResidualP_du[j];
1493  dsubgridErrorP_dv[j] = -tau_p*dpdeResidualP_dv[j];
1494  dsubgridErrorP_dw[j] = -tau_p*dpdeResidualP_dw[j];
1495  /* GLS momentum*/
1496  /* u */
1497  dsubgridErrorU_du[j] = -tau_v*dpdeResidualU_du[j];
1498  /* v */
1499  dsubgridErrorV_dv[j] = -tau_v*dpdeResidualV_dv[j];
1500  /* w */
1501  dsubgridErrorW_dw[j] = -tau_v*dpdeResidualW_dw[j];
1502  }
1503  for (int j=0;j<nDOF_trial_element;j++)
1504  {
1505  /* GLS momentum*/
1506  /* u */
1507  dsubgridErrorU_dp[j] = -tau_v*dpdeResidualU_dp[j];
1508  /* v */
1509  dsubgridErrorV_dp[j] = -tau_v*dpdeResidualV_dp[j];
1510  /* w */
1511  dsubgridErrorW_dp[j] = -tau_v*dpdeResidualW_dp[j];
1512  }
1513  }
1514 
1515  inline
1516  void exteriorNumericalAdvectiveFlux(const double NONCONSERVATIVE_FORM,
1517  const int& isDOFBoundary_p,
1518  const int& isDOFBoundary_u,
1519  const int& isDOFBoundary_v,
1520  const int& isDOFBoundary_w,
1521  const int& isFluxBoundary_p,
1522  const int& isFluxBoundary_u,
1523  const int& isFluxBoundary_v,
1524  const int& isFluxBoundary_w,
1525  const double& oneByRho,
1526  const double& bc_oneByRho,
1527  const double n[nSpace],
1528  const double& bc_p,
1529  const double& bc_u,
1530  const double& bc_v,
1531  const double& bc_w,
1532  const double bc_f_mass[nSpace],
1533  const double bc_f_umom[nSpace],
1534  const double bc_f_vmom[nSpace],
1535  const double bc_f_wmom[nSpace],
1536  const double& bc_flux_mass,
1537  const double& bc_flux_umom,
1538  const double& bc_flux_vmom,
1539  const double& bc_flux_wmom,
1540  const double& p,
1541  const double& u,
1542  const double& v,
1543  const double& w,
1544  const double f_mass[nSpace],
1545  const double f_umom[nSpace],
1546  const double f_vmom[nSpace],
1547  const double f_wmom[nSpace],
1548  const double df_mass_du[nSpace],
1549  const double df_mass_dv[nSpace],
1550  const double df_mass_dw[nSpace],
1551  const double df_umom_dp[nSpace],
1552  const double dham_grad[nSpace],
1553  const double df_umom_du[nSpace],
1554  const double df_umom_dv[nSpace],
1555  const double df_umom_dw[nSpace],
1556  const double df_vmom_dp[nSpace],
1557  const double df_vmom_du[nSpace],
1558  const double df_vmom_dv[nSpace],
1559  const double df_vmom_dw[nSpace],
1560  const double df_wmom_dp[nSpace],
1561  const double df_wmom_du[nSpace],
1562  const double df_wmom_dv[nSpace],
1563  const double df_wmom_dw[nSpace],
1564  double& flux_mass,
1565  double& flux_umom,
1566  double& flux_vmom,
1567  double& flux_wmom,
1568  double* velocity)
1569  {
1570  double flowSpeedNormal;
1571  flux_mass = 0.0;
1572  flux_umom = 0.0;
1573  flux_vmom = 0.0;
1574  flux_wmom = 0.0;
1575  if (NONCONSERVATIVE_FORM > 0.0)
1576  {
1577  flowSpeedNormal=n[0]*df_vmom_dv[0]+n[1]*df_umom_du[1]+n[2]*df_umom_du[2];//tricky, works for moving and fixed domains
1578  flowSpeedNormal+=n[0]*dham_grad[0]+n[1]*dham_grad[1]+n[2]*dham_grad[2];
1579  }
1580  else
1581  flowSpeedNormal=n[0]*df_vmom_dv[0]+n[1]*df_umom_du[1]+n[2]*df_umom_du[2];//tricky, works for moving and fixed domains
1582  if (isDOFBoundary_u != 1)
1583  {
1584  flux_mass += n[0] * f_mass[0];
1585  velocity[0] = f_mass[0];
1586  if (flowSpeedNormal >= 0.0)
1587  {
1588  flux_umom += n[0] * f_umom[0];
1589  flux_vmom += n[0] * f_vmom[0];
1590  flux_wmom += n[0] * f_wmom[0];
1591  }
1592  else
1593  {
1594  if (NONCONSERVATIVE_FORM > 0.0)
1595  {
1596  flux_umom += (0.0 - u) * flowSpeedNormal;
1597  }
1598  }
1599  }
1600  else
1601  {
1602  flux_mass += n[0] * f_mass[0];
1603  velocity[0] = f_mass[0];
1604  if (UPWIND_DIRICHLET && flowSpeedNormal >= 0.0)
1605  {
1606  flux_umom += n[0] * f_umom[0];
1607  flux_vmom += n[0] * f_vmom[0];
1608  flux_wmom += n[0] * f_wmom[0];
1609  }
1610  else
1611  {
1612  if (NONCONSERVATIVE_FORM > 0.0)
1613  {
1614  flux_umom += (bc_u - u) * flowSpeedNormal;
1615  }
1616  else
1617  {
1618  flux_umom += n[0] * bc_f_umom[0];
1619  flux_vmom += n[0] * bc_f_vmom[0];
1620  flux_wmom += n[0] * bc_f_wmom[0];
1621  }
1622  }
1623  }
1624  if (isDOFBoundary_v != 1)
1625  {
1626  flux_mass += n[1] * f_mass[1];
1627  velocity[1] = f_mass[1];
1628  if (flowSpeedNormal >= 0.0)
1629  {
1630  flux_umom += n[1] * f_umom[1];
1631  flux_vmom += n[1] * f_vmom[1];
1632  flux_wmom += n[1] * f_wmom[1];
1633  }
1634  else
1635  {
1636  if (NONCONSERVATIVE_FORM > 0.0)
1637  {
1638  flux_vmom += (0.0 - v) * flowSpeedNormal;
1639  }
1640  }
1641  }
1642  else
1643  {
1644  flux_mass += n[1] * f_mass[1];
1645  velocity[1] = f_mass[1];
1646  if (UPWIND_DIRICHLET && flowSpeedNormal >= 0.0)
1647  {
1648  flux_umom += n[1] * f_umom[1];
1649  flux_vmom += n[1] * f_vmom[1];
1650  flux_wmom += n[1] * f_wmom[1];
1651  }
1652  else
1653  {
1654  if (NONCONSERVATIVE_FORM > 0.0)
1655  {
1656  flux_vmom += (bc_v - v) * flowSpeedNormal;
1657  }
1658  else
1659  {
1660  flux_umom += n[1] * bc_f_umom[1];
1661  flux_vmom += n[1] * bc_f_vmom[1];
1662  flux_wmom += n[1] * bc_f_wmom[1];
1663  }
1664  }
1665  }
1666  if (isDOFBoundary_w != 1)
1667  {
1668  flux_mass+=n[2]*f_mass[2];
1669  velocity[2] = f_mass[2];
1670  if (flowSpeedNormal >= 0.0)
1671  {
1672  flux_umom += n[2] * f_umom[2];
1673  flux_vmom += n[2] * f_vmom[2];
1674  flux_wmom += n[2] * f_wmom[2];
1675  }
1676  else
1677  {
1678  if (NONCONSERVATIVE_FORM > 0.0)
1679  {
1680  flux_wmom += (0.0 - w) * flowSpeedNormal;
1681  }
1682  }
1683  }
1684  else
1685  {
1686  flux_mass +=n[2]*f_mass[2];
1687  velocity[2] = f_mass[2];
1688  if (UPWIND_DIRICHLET && flowSpeedNormal >= 0.0)
1689  {
1690  flux_umom += n[2] * f_umom[2];
1691  flux_vmom += n[2] * f_vmom[2];
1692  flux_wmom += n[2] * f_wmom[2];
1693  }
1694  else
1695  {
1696  if (NONCONSERVATIVE_FORM > 0.0)
1697  {
1698  flux_wmom += (bc_w - w) * flowSpeedNormal;
1699  }
1700  else
1701  {
1702  flux_umom += n[2] * bc_f_umom[2];
1703  flux_vmom += n[2] * bc_f_vmom[2];
1704  flux_wmom += n[2] * bc_f_wmom[2];
1705  }
1706  }
1707  }
1708  if (isDOFBoundary_p == 1)
1709  {
1710  if (NONCONSERVATIVE_FORM > 0.0)
1711  {
1712  flux_umom += n[0] * (bc_p - p);
1713  flux_vmom += n[1] * (bc_p - p);
1714  flux_wmom += n[2] * (bc_p - p);
1715  }
1716  else
1717  {
1718  flux_umom += n[0] * (bc_p * bc_oneByRho - p * oneByRho);
1719  flux_vmom += n[1] * (bc_p * bc_oneByRho - p * oneByRho);
1720  flux_wmom += n[2] * (bc_p * bc_oneByRho - p * oneByRho);
1721  }
1722  }
1723  if (isFluxBoundary_p == 1)
1724  {
1725  velocity[0] += (bc_flux_mass - flux_mass) * n[0];
1726  velocity[1] += (bc_flux_mass - flux_mass) * n[1];
1727  velocity[2] += (bc_flux_mass - flux_mass) * n[2];
1728  flux_mass = bc_flux_mass;
1729  }
1730  if (isFluxBoundary_u == 1)
1731  {
1732  flux_umom = bc_flux_umom;
1733  }
1734  if (isFluxBoundary_v == 1)
1735  {
1736  flux_vmom = bc_flux_vmom;
1737  }
1738  if (isFluxBoundary_w == 1)
1739  {
1740  flux_wmom = bc_flux_wmom;
1741  }
1742  }
1743 
1744  inline
1745  void exteriorNumericalAdvectiveFluxDerivatives(const double NONCONSERVATIVE_FORM,
1746  const int& isDOFBoundary_p,
1747  const int& isDOFBoundary_u,
1748  const int& isDOFBoundary_v,
1749  const int& isDOFBoundary_w,
1750  const int& isFluxBoundary_p,
1751  const int& isFluxBoundary_u,
1752  const int& isFluxBoundary_v,
1753  const int& isFluxBoundary_w,
1754  const double& oneByRho,
1755  const double n[nSpace],
1756  const double& bc_p,
1757  const double& bc_u,
1758  const double& bc_v,
1759  const double& bc_w,
1760  const double bc_f_mass[nSpace],
1761  const double bc_f_umom[nSpace],
1762  const double bc_f_vmom[nSpace],
1763  const double bc_f_wmom[nSpace],
1764  const double& bc_flux_mass,
1765  const double& bc_flux_umom,
1766  const double& bc_flux_vmom,
1767  const double& bc_flux_wmom,
1768  const double& p,
1769  const double& u,
1770  const double& v,
1771  const double& w,
1772  const double& dmom_u_acc_u,
1773  const double f_mass[nSpace],
1774  const double f_umom[nSpace],
1775  const double f_vmom[nSpace],
1776  const double f_wmom[nSpace],
1777  const double df_mass_du[nSpace],
1778  const double df_mass_dv[nSpace],
1779  const double df_mass_dw[nSpace],
1780  const double df_umom_dp[nSpace],
1781  const double dham_grad[nSpace],
1782  const double df_umom_du[nSpace],
1783  const double df_umom_dv[nSpace],
1784  const double df_umom_dw[nSpace],
1785  const double df_vmom_dp[nSpace],
1786  const double df_vmom_du[nSpace],
1787  const double df_vmom_dv[nSpace],
1788  const double df_vmom_dw[nSpace],
1789  const double df_wmom_dp[nSpace],
1790  const double df_wmom_du[nSpace],
1791  const double df_wmom_dv[nSpace],
1792  const double df_wmom_dw[nSpace],
1793  double& dflux_mass_du,
1794  double& dflux_mass_dv,
1795  double& dflux_mass_dw,
1796  double& dflux_umom_dp,
1797  double& dflux_umom_du,
1798  double& dflux_umom_dv,
1799  double& dflux_umom_dw,
1800  double& dflux_vmom_dp,
1801  double& dflux_vmom_du,
1802  double& dflux_vmom_dv,
1803  double& dflux_vmom_dw,
1804  double& dflux_wmom_dp,
1805  double& dflux_wmom_du,
1806  double& dflux_wmom_dv,
1807  double& dflux_wmom_dw)
1808  {
1809  double flowSpeedNormal;
1810  dflux_mass_du = 0.0;
1811  dflux_mass_dv = 0.0;
1812  dflux_mass_dw = 0.0;
1813 
1814  dflux_umom_dp = 0.0;
1815  dflux_umom_du = 0.0;
1816  dflux_umom_dv = 0.0;
1817  dflux_umom_dw = 0.0;
1818 
1819  dflux_vmom_dp = 0.0;
1820  dflux_vmom_du = 0.0;
1821  dflux_vmom_dv = 0.0;
1822  dflux_vmom_dw = 0.0;
1823 
1824  dflux_wmom_dp = 0.0;
1825  dflux_wmom_du = 0.0;
1826  dflux_wmom_dv = 0.0;
1827  dflux_wmom_dw = 0.0;
1828 
1829  flowSpeedNormal=n[0]*df_vmom_dv[0]+n[1]*df_umom_du[1]+n[2]*df_umom_du[2];//tricky, works for moving and fixed domains
1830  flowSpeedNormal+=NONCONSERVATIVE_FORM*(n[0]*dham_grad[0]+n[1]*dham_grad[1]+n[2]*dham_grad[2]);
1831  if (isDOFBoundary_u != 1)
1832  {
1833  dflux_mass_du += n[0] * df_mass_du[0];
1834  if (flowSpeedNormal >= 0.0)
1835  {
1836  dflux_umom_du += n[0] * df_umom_du[0];
1837  dflux_umom_dv += n[0] * df_umom_dv[0];
1838  dflux_umom_dw += n[0] * df_umom_dw[0];
1839 
1840  dflux_vmom_du += n[0] * df_vmom_du[0];
1841  dflux_vmom_dv += n[0] * df_vmom_dv[0];
1842  dflux_vmom_dw += n[0] * df_vmom_dw[0];
1843 
1844  dflux_wmom_du += n[0] * df_wmom_du[0];
1845  dflux_wmom_dv += n[0] * df_wmom_dv[0];
1846  dflux_wmom_dw += n[0] * df_wmom_dw[0];
1847  }
1848  else
1849  {
1850  if (NONCONSERVATIVE_FORM > 0.0)
1851  {
1852  dflux_umom_du += dmom_u_acc_u * n[0] * (0.0 - u) - flowSpeedNormal;
1853  dflux_umom_dv += dmom_u_acc_u * n[1] * (0.0 - u) ;
1854  dflux_umom_dw += dmom_u_acc_u * n[2] * (0.0 - u) ;
1855  }
1856  }
1857  }
1858  else
1859  {
1860  //cek still upwind the advection for Dirichlet?
1861  dflux_mass_du += n[0] * df_mass_du[0];
1862  if (UPWIND_DIRICHLET && flowSpeedNormal >= 0.0)
1863  {
1864  dflux_umom_du += n[0] * df_umom_du[0];
1865  dflux_umom_dv += n[0] * df_umom_dv[0];
1866  dflux_umom_dw += n[0] * df_umom_dw[0];
1867 
1868  dflux_vmom_du += n[0] * df_vmom_du[0];
1869  dflux_vmom_dv += n[0] * df_vmom_dv[0];
1870  dflux_vmom_dw += n[0] * df_vmom_dw[0];
1871 
1872  dflux_wmom_du += n[0] * df_wmom_du[0];
1873  dflux_wmom_dv += n[0] * df_wmom_dv[0];
1874  dflux_wmom_dw += n[0] * df_wmom_dw[0];
1875  }
1876  else
1877  {
1878  if (NONCONSERVATIVE_FORM > 0.0)
1879  {
1880  dflux_umom_du += dmom_u_acc_u * n[0] * (bc_u - u) - flowSpeedNormal;
1881  dflux_umom_dv += dmom_u_acc_u * n[1] * (bc_u - u) ;
1882  dflux_umom_dw += dmom_u_acc_u * n[2] * (bc_u - u) ;
1883  }
1884  else
1885  {
1886  if (isDOFBoundary_v != 1)
1887  dflux_vmom_dv += n[0] * df_vmom_dv[0];
1888  if (isDOFBoundary_w != 1)
1889  dflux_wmom_dw += n[0] * df_wmom_dw[0];
1890  }
1891  }
1892  }
1893  if (isDOFBoundary_v != 1)
1894  {
1895  dflux_mass_dv += n[1] * df_mass_dv[1];
1896  if (flowSpeedNormal >= 0.0)
1897  {
1898  dflux_umom_du += n[1] * df_umom_du[1];
1899  dflux_umom_dv += n[1] * df_umom_dv[1];
1900  dflux_umom_dw += n[1] * df_umom_dw[1];
1901 
1902  dflux_vmom_du += n[1] * df_vmom_du[1];
1903  dflux_vmom_dv += n[1] * df_vmom_dv[1];
1904  dflux_vmom_dw += n[1] * df_vmom_dw[1];
1905 
1906  dflux_wmom_du += n[1] * df_wmom_du[1];
1907  dflux_wmom_dv += n[1] * df_wmom_dv[1];
1908  dflux_wmom_dw += n[1] * df_wmom_dw[1];
1909  }
1910  else
1911  {
1912  if (NONCONSERVATIVE_FORM > 0.0)
1913  {
1914  dflux_vmom_du += dmom_u_acc_u * n[0] * (0.0 - v);
1915  dflux_vmom_dv += dmom_u_acc_u * n[1] * (0.0 - v) - flowSpeedNormal;
1916  dflux_vmom_dw += dmom_u_acc_u * n[2] * (0.0 - v);
1917  }
1918  }
1919  }
1920  else
1921  {
1922  //cek still upwind the advection for Dirichlet?
1923  dflux_mass_dv += n[1] * df_mass_dv[1];
1924  if (UPWIND_DIRICHLET && flowSpeedNormal >= 0.0)
1925  {
1926  dflux_umom_du += n[1] * df_umom_du[1];
1927  dflux_umom_dv += n[1] * df_umom_dv[1];
1928  dflux_umom_dw += n[1] * df_umom_dw[1];
1929 
1930  dflux_vmom_du += n[1] * df_vmom_du[1];
1931  dflux_vmom_dv += n[1] * df_vmom_dv[1];
1932  dflux_vmom_dw += n[1] * df_vmom_dw[1];
1933 
1934  dflux_wmom_du += n[1] * df_wmom_du[1];
1935  dflux_wmom_dv += n[1] * df_wmom_dv[1];
1936  dflux_wmom_dw += n[1] * df_wmom_dw[1];
1937  }
1938  else
1939  {
1940  if (NONCONSERVATIVE_FORM > 0.0)
1941  {
1942  dflux_vmom_du += dmom_u_acc_u * n[0] * (bc_v - v);
1943  dflux_vmom_dv += dmom_u_acc_u * n[1] * (bc_v - v) - flowSpeedNormal;
1944  dflux_vmom_dw += dmom_u_acc_u * n[2] * (bc_v - v);
1945  }
1946  else
1947  {
1948  if (isDOFBoundary_u != 1)
1949  dflux_umom_du += n[1] * df_umom_du[1];
1950  if (isDOFBoundary_w != 1)
1951  dflux_wmom_dw += n[1] * df_wmom_dw[1];
1952  }
1953  }
1954  }
1955  if (isDOFBoundary_w != 1)
1956  {
1957  dflux_mass_dw+=n[2]*df_mass_dw[2];
1958  if (flowSpeedNormal >= 0.0)
1959  {
1960  dflux_umom_du += n[2] * df_umom_du[2];
1961  dflux_umom_dv += n[2] * df_umom_dv[2];
1962  dflux_umom_dw += n[2] * df_umom_dw[2];
1963 
1964  dflux_vmom_du += n[2] * df_vmom_du[2];
1965  dflux_vmom_dv += n[2] * df_vmom_dv[2];
1966  dflux_vmom_dw += n[2] * df_vmom_dw[2];
1967 
1968  dflux_wmom_du += n[2] * df_wmom_du[2];
1969  dflux_wmom_dv += n[2] * df_wmom_dv[2];
1970  dflux_wmom_dw += n[2] * df_wmom_dw[2];
1971  }
1972  else
1973  {
1974  if (NONCONSERVATIVE_FORM > 0.0)
1975  {
1976  dflux_wmom_du += dmom_u_acc_u * n[0] * (0.0 - w);
1977  dflux_wmom_dv += dmom_u_acc_u * n[1] * (0.0 - w);
1978  dflux_wmom_dw += dmom_u_acc_u * n[2] * (0.0 - w) - flowSpeedNormal;
1979  }
1980  }
1981  }
1982  else
1983  {
1984  //cek still upwind the advection for Dirichlet?
1985  dflux_mass_dw += n[2]*df_mass_dw[2];
1986  if (UPWIND_DIRICHLET && flowSpeedNormal >= 0.0)
1987  {
1988  dflux_umom_du += n[2] * df_umom_du[2];
1989  dflux_umom_dv += n[2] * df_umom_dv[2];
1990  dflux_umom_dw += n[2] * df_umom_dw[2];
1991 
1992  dflux_vmom_du += n[2] * df_vmom_du[2];
1993  dflux_vmom_dv += n[2] * df_vmom_dv[2];
1994  dflux_vmom_dw += n[2] * df_vmom_dw[2];
1995 
1996  dflux_wmom_du += n[2] * df_wmom_du[2];
1997  dflux_wmom_dv += n[2] * df_wmom_dv[2];
1998  dflux_wmom_dw += n[2] * df_wmom_dw[2];
1999  }
2000  else
2001  {
2002  if (NONCONSERVATIVE_FORM > 0.0)
2003  {
2004  dflux_wmom_du += dmom_u_acc_u * n[0] * (0.0 - w);
2005  dflux_wmom_dv += dmom_u_acc_u * n[1] * (0.0 - w);
2006  dflux_wmom_dw += dmom_u_acc_u * n[2] * (0.0 - w) - flowSpeedNormal;
2007  }
2008  else
2009  {
2010  if (isDOFBoundary_u != 1)
2011  dflux_umom_du += n[2] * df_umom_du[2];
2012  if (isDOFBoundary_v != 1)
2013  dflux_vmom_dv += n[2] * df_vmom_dv[2];
2014  }
2015  }
2016  }
2017  if (isDOFBoundary_p == 1)
2018  {
2019  if (NONCONSERVATIVE_FORM > 0.0)
2020  {
2021  dflux_umom_dp = -n[0];
2022  dflux_vmom_dp = -n[1];
2023  dflux_wmom_dp = -n[2];
2024  }
2025  else
2026  {
2027  dflux_umom_dp = -n[0] * oneByRho;
2028  dflux_vmom_dp = -n[1] * oneByRho;
2029  dflux_wmom_dp = -n[2] * oneByRho;
2030  }
2031  }
2032  if (isFluxBoundary_p == 1)
2033  {
2034  dflux_mass_du = 0.0;
2035  dflux_mass_dv = 0.0;
2036  dflux_mass_dw = 0.0;
2037  }
2038  if (isFluxBoundary_u == 1)
2039  {
2040  dflux_umom_dp = 0.0;
2041  dflux_umom_du = 0.0;
2042  dflux_umom_dv = 0.0;
2043  dflux_umom_dw = 0.0;
2044  }
2045  if (isFluxBoundary_v == 1)
2046  {
2047  dflux_vmom_dp = 0.0;
2048  dflux_vmom_du = 0.0;
2049  dflux_vmom_dv = 0.0;
2050  dflux_vmom_dw = 0.0;
2051  }
2052  if (isFluxBoundary_w == 1)
2053  {
2054  dflux_wmom_dp = 0.0;
2055  dflux_wmom_du = 0.0;
2056  dflux_wmom_dv = 0.0;
2057  dflux_wmom_dw = 0.0;
2058  }
2059  }
2060 
2061  inline
2062  void exteriorNumericalDiffusiveFlux(const double& eps,
2063  const double& phi,
2064  int* rowptr,
2065  int* colind,
2066  const int& isDOFBoundary,
2067  const int& isFluxBoundary,
2068  const double n[nSpace],
2069  double* bc_a,
2070  const double& bc_u,
2071  const double& bc_flux,
2072  double* a,
2073  const double grad_potential[nSpace],
2074  const double& u,
2075  const double& penalty,
2076  double& flux)
2077  {
2078  double diffusiveVelocityComponent_I,penaltyFlux,max_a;
2079  if(isFluxBoundary == 1)
2080  {
2081  flux = bc_flux;
2082  }
2083  else if(isDOFBoundary == 1)
2084  {
2085  flux = 0.0;
2086  max_a=0.0;
2087  for(int I=0;I<nSpace;I++)
2088  {
2089  diffusiveVelocityComponent_I=0.0;
2090  for(int m=rowptr[I];m<rowptr[I+1];m++)
2091  {
2092  diffusiveVelocityComponent_I -= a[m]*grad_potential[colind[m]];
2093  max_a = fmax(max_a,a[m]);
2094  }
2095  flux+= diffusiveVelocityComponent_I*n[I];
2096  }
2097  penaltyFlux = max_a*penalty*(u-bc_u);
2098  flux += penaltyFlux;
2099  //cek: need to investigate this issue more
2100  //contact line slip
2101  //flux*=(gf.D(eps,0) - gf.D(eps,phi))/gf.D(eps,0);
2102  }
2103  else
2104  {
2105  std::cerr<<"RANS2P: warning, diffusion term with no boundary condition set, setting diffusive flux to 0.0"<<std::endl;
2106  flux = 0.0;
2107  }
2108  }
2109 
2110 
2111  inline
2112  double ExteriorNumericalDiffusiveFluxJacobian(const double& eps,
2113  const double& phi,
2114  int* rowptr,
2115  int* colind,
2116  const int& isDOFBoundary,
2117  const int& isFluxBoundary,
2118  const double n[nSpace],
2119  double* a,
2120  const double& v,
2121  const double grad_v[nSpace],
2122  const double& penalty)
2123  {
2124  double dvel_I,tmp=0.0,max_a=0.0;
2125  if(isFluxBoundary==0 && isDOFBoundary==1)
2126  {
2127  for(int I=0;I<nSpace;I++)
2128  {
2129  dvel_I=0.0;
2130  for(int m=rowptr[I];m<rowptr[I+1];m++)
2131  {
2132  dvel_I -= a[m]*grad_v[colind[m]];
2133  max_a = fmax(max_a,a[m]);
2134  }
2135  tmp += dvel_I*n[I];
2136  }
2137  tmp +=max_a*penalty*v;
2138  //cek: need to investigate this issue more
2139  //contact line slip
2140  //tmp*=(gf.D(eps,0) - gf.D(eps,phi))/gf.D(eps,0);
2141  }
2142  return tmp;
2143  }
2144 
2146  {
2147  double NONCONSERVATIVE_FORM = args.scalar<double>("NONCONSERVATIVE_FORM");
2148  double MOMENTUM_SGE = args.scalar<double>("MOMENTUM_SGE");
2149  double PRESSURE_SGE = args.scalar<double>("PRESSURE_SGE");
2150  double VELOCITY_SGE = args.scalar<double>("VELOCITY_SGE");
2151  double PRESSURE_PROJECTION_STABILIZATION = args.scalar<double>("PRESSURE_PROJECTION_STABILIZATION");
2152  xt::pyarray<double>& numerical_viscosity = args.array<double>("numerical_viscosity");
2153  xt::pyarray<double>& mesh_trial_ref = args.array<double>("mesh_trial_ref");
2154  xt::pyarray<double>& mesh_grad_trial_ref = args.array<double>("mesh_grad_trial_ref");
2155  xt::pyarray<double>& mesh_dof = args.array<double>("mesh_dof");
2156  xt::pyarray<double>& mesh_velocity_dof = args.array<double>("mesh_velocity_dof");
2157  double MOVING_DOMAIN = args.scalar<double>("MOVING_DOMAIN");
2158  xt::pyarray<int>& mesh_l2g = args.array<int>("mesh_l2g");
2159  xt::pyarray<double>& x_ref = args.array<double>("x_ref");
2160  xt::pyarray<double>& dV_ref = args.array<double>("dV_ref");
2161  xt::pyarray<double>& p_trial_ref = args.array<double>("p_trial_ref");
2162  xt::pyarray<double>& p_grad_trial_ref = args.array<double>("p_grad_trial_ref");
2163  xt::pyarray<double>& p_test_ref = args.array<double>("p_test_ref");
2164  xt::pyarray<double>& p_grad_test_ref = args.array<double>("p_grad_test_ref");
2165  xt::pyarray<double>& vel_trial_ref = args.array<double>("vel_trial_ref");
2166  xt::pyarray<double>& vel_grad_trial_ref = args.array<double>("vel_grad_trial_ref");
2167  xt::pyarray<double>& vel_test_ref = args.array<double>("vel_test_ref");
2168  xt::pyarray<double>& vel_grad_test_ref = args.array<double>("vel_grad_test_ref");
2169  xt::pyarray<double>& mesh_trial_trace_ref = args.array<double>("mesh_trial_trace_ref");
2170  xt::pyarray<double>& mesh_grad_trial_trace_ref = args.array<double>("mesh_grad_trial_trace_ref");
2171  xt::pyarray<double>& xb_ref = args.array<double>("xb_ref");
2172  xt::pyarray<double>& dS_ref = args.array<double>("dS_ref");
2173  xt::pyarray<double>& p_trial_trace_ref = args.array<double>("p_trial_trace_ref");
2174  xt::pyarray<double>& p_grad_trial_trace_ref = args.array<double>("p_grad_trial_trace_ref");
2175  xt::pyarray<double>& p_test_trace_ref = args.array<double>("p_test_trace_ref");
2176  xt::pyarray<double>& p_grad_test_trace_ref = args.array<double>("p_grad_test_trace_ref");
2177  xt::pyarray<double>& vel_trial_trace_ref = args.array<double>("vel_trial_trace_ref");
2178  xt::pyarray<double>& vel_grad_trial_trace_ref = args.array<double>("vel_grad_trial_trace_ref");
2179  xt::pyarray<double>& vel_test_trace_ref = args.array<double>("vel_test_trace_ref");
2180  xt::pyarray<double>& vel_grad_test_trace_ref = args.array<double>("vel_grad_test_trace_ref");
2181  xt::pyarray<double>& normal_ref = args.array<double>("normal_ref");
2182  xt::pyarray<double>& boundaryJac_ref = args.array<double>("boundaryJac_ref");
2183  double eb_adjoint_sigma = args.scalar<double>("eb_adjoint_sigma");
2184  xt::pyarray<double>& elementDiameter = args.array<double>("elementDiameter");
2185  xt::pyarray<double>& elementBoundaryDiameter = args.array<double>("elementBoundaryDiameter");
2186  xt::pyarray<double>& nodeDiametersArray = args.array<double>("nodeDiametersArray");
2187  double hFactor = args.scalar<double>("hFactor");
2188  int nElements_global = args.scalar<int>("nElements_global");
2189  int nElementBoundaries_owned = args.scalar<int>("nElementBoundaries_owned");
2190  double useRBLES = args.scalar<double>("useRBLES");
2191  double useMetrics = args.scalar<double>("useMetrics");
2192  double alphaBDF = args.scalar<double>("alphaBDF");
2193  double epsFact_rho = args.scalar<double>("epsFact_rho");
2194  double epsFact_mu = args.scalar<double>("epsFact_mu");
2195  double sigma = args.scalar<double>("sigma");
2196  double rho_0 = args.scalar<double>("rho_0");
2197  double nu_0 = args.scalar<double>("nu_0");
2198  double rho_1 = args.scalar<double>("rho_1");
2199  double nu_1 = args.scalar<double>("nu_1");
2200  double smagorinskyConstant = args.scalar<double>("smagorinskyConstant");
2201  int turbulenceClosureModel = args.scalar<int>("turbulenceClosureModel");
2202  double Ct_sge = args.scalar<double>("Ct_sge");
2203  double Cd_sge = args.scalar<double>("Cd_sge");
2204  double C_dc = args.scalar<double>("C_dc");
2205  double C_b = args.scalar<double>("C_b");
2206  const xt::pyarray<double>& eps_solid = args.array<double>("eps_solid");
2207  xt::pyarray<double>& phi_solid = args.array<double>("phi_solid");
2208  const xt::pyarray<double>& eps_porous = args.array<double>("eps_porous");
2209  xt::pyarray<double>& phi_porous = args.array<double>("phi_porous");
2210  const xt::pyarray<double>& q_velocity_porous = args.array<double>("q_velocity_porous");
2211  const xt::pyarray<double>& q_porosity = args.array<double>("q_porosity");
2212  const xt::pyarray<double>& q_dragAlpha = args.array<double>("q_dragAlpha");
2213  const xt::pyarray<double>& q_dragBeta = args.array<double>("q_dragBeta");
2214  const xt::pyarray<double>& q_mass_source = args.array<double>("q_mass_source");
2215  const xt::pyarray<double>& q_turb_var_0 = args.array<double>("q_turb_var_0");
2216  const xt::pyarray<double>& q_turb_var_1 = args.array<double>("q_turb_var_1");
2217  const xt::pyarray<double>& q_turb_var_grad_0 = args.array<double>("q_turb_var_grad_0");
2218  const double LAG_LES = args.scalar<double>("LAG_LES");
2219  xt::pyarray<double> & q_eddy_viscosity = args.array<double>("q_eddy_viscosity");
2220  xt::pyarray<double> & q_eddy_viscosity_last = args.array<double>("q_eddy_viscosity_last");
2221  xt::pyarray<double> & ebqe_eddy_viscosity = args.array<double>("ebqe_eddy_viscosity");
2222  xt::pyarray<double> & ebqe_eddy_viscosity_last = args.array<double>("ebqe_eddy_viscosity_last");
2223  xt::pyarray<int>& p_l2g = args.array<int>("p_l2g");
2224  xt::pyarray<int>& vel_l2g = args.array<int>("vel_l2g");
2225  xt::pyarray<int>& rp_l2g = args.array<int>("rp_l2g");
2226  xt::pyarray<int>& rvel_l2g = args.array<int>("rvel_l2g");
2227  xt::pyarray<double>& p_dof = args.array<double>("p_dof");
2228  xt::pyarray<double>& u_dof = args.array<double>("u_dof");
2229  xt::pyarray<double>& v_dof = args.array<double>("v_dof");
2230  xt::pyarray<double>& w_dof = args.array<double>("w_dof");
2231  xt::pyarray<double>& p_old_dof = args.array<double>("p_old_dof");
2232  xt::pyarray<double>& u_old_dof = args.array<double>("u_old_dof");
2233  xt::pyarray<double>& v_old_dof = args.array<double>("v_old_dof");
2234  xt::pyarray<double>& w_old_dof = args.array<double>("w_old_dof");
2235  xt::pyarray<double>& g = args.array<double>("g");
2236  const double useVF = args.scalar<double>("useVF");
2237  xt::pyarray<double>& q_rho = args.array<double>("q_rho");
2238  xt::pyarray<double>& vf = args.array<double>("vf");
2239  xt::pyarray<double>& phi = args.array<double>("phi");
2240  xt::pyarray<double>& phi_nodes = args.array<double>("phi_nodes");
2241  xt::pyarray<double>& normal_phi = args.array<double>("normal_phi");
2242  xt::pyarray<double>& kappa_phi = args.array<double>("kappa_phi");
2243  xt::pyarray<double>& q_mom_u_acc = args.array<double>("q_mom_u_acc");
2244  xt::pyarray<double>& q_mom_v_acc = args.array<double>("q_mom_v_acc");
2245  xt::pyarray<double>& q_mom_w_acc = args.array<double>("q_mom_w_acc");
2246  xt::pyarray<double>& q_mass_adv = args.array<double>("q_mass_adv");
2247  xt::pyarray<double>& q_mom_u_acc_beta_bdf = args.array<double>("q_mom_u_acc_beta_bdf");
2248  xt::pyarray<double>& q_mom_v_acc_beta_bdf = args.array<double>("q_mom_v_acc_beta_bdf");
2249  xt::pyarray<double>& q_mom_w_acc_beta_bdf = args.array<double>("q_mom_w_acc_beta_bdf");
2250  xt::pyarray<double>& q_dV = args.array<double>("q_dV");
2251  xt::pyarray<double>& q_dV_last = args.array<double>("q_dV_last");
2252  xt::pyarray<double>& q_velocity_sge = args.array<double>("q_velocity_sge");
2253  xt::pyarray<double>& q_cfl = args.array<double>("q_cfl");
2254  xt::pyarray<double>& q_numDiff_u = args.array<double>("q_numDiff_u");
2255  xt::pyarray<double>& q_numDiff_v = args.array<double>("q_numDiff_v");
2256  xt::pyarray<double>& q_numDiff_w = args.array<double>("q_numDiff_w");
2257  xt::pyarray<double>& q_numDiff_u_last = args.array<double>("q_numDiff_u_last");
2258  xt::pyarray<double>& q_numDiff_v_last = args.array<double>("q_numDiff_v_last");
2259  xt::pyarray<double>& q_numDiff_w_last = args.array<double>("q_numDiff_w_last");
2260  xt::pyarray<int>& sdInfo_u_u_rowptr = args.array<int>("sdInfo_u_u_rowptr");
2261  xt::pyarray<int>& sdInfo_u_u_colind = args.array<int>("sdInfo_u_u_colind");
2262  xt::pyarray<int>& sdInfo_u_v_rowptr = args.array<int>("sdInfo_u_v_rowptr");
2263  xt::pyarray<int>& sdInfo_u_v_colind = args.array<int>("sdInfo_u_v_colind");
2264  xt::pyarray<int>& sdInfo_u_w_rowptr = args.array<int>("sdInfo_u_w_rowptr");
2265  xt::pyarray<int>& sdInfo_u_w_colind = args.array<int>("sdInfo_u_w_colind");
2266  xt::pyarray<int>& sdInfo_v_v_rowptr = args.array<int>("sdInfo_v_v_rowptr");
2267  xt::pyarray<int>& sdInfo_v_v_colind = args.array<int>("sdInfo_v_v_colind");
2268  xt::pyarray<int>& sdInfo_v_u_rowptr = args.array<int>("sdInfo_v_u_rowptr");
2269  xt::pyarray<int>& sdInfo_v_u_colind = args.array<int>("sdInfo_v_u_colind");
2270  xt::pyarray<int>& sdInfo_v_w_rowptr = args.array<int>("sdInfo_v_w_rowptr");
2271  xt::pyarray<int>& sdInfo_v_w_colind = args.array<int>("sdInfo_v_w_colind");
2272  xt::pyarray<int>& sdInfo_w_w_rowptr = args.array<int>("sdInfo_w_w_rowptr");
2273  xt::pyarray<int>& sdInfo_w_w_colind = args.array<int>("sdInfo_w_w_colind");
2274  xt::pyarray<int>& sdInfo_w_u_rowptr = args.array<int>("sdInfo_w_u_rowptr");
2275  xt::pyarray<int>& sdInfo_w_u_colind = args.array<int>("sdInfo_w_u_colind");
2276  xt::pyarray<int>& sdInfo_w_v_rowptr = args.array<int>("sdInfo_w_v_rowptr");
2277  xt::pyarray<int>& sdInfo_w_v_colind = args.array<int>("sdInfo_w_v_colind");
2278  int offset_p = args.scalar<int>("offset_p");
2279  int offset_u = args.scalar<int>("offset_u");
2280  int offset_v = args.scalar<int>("offset_v");
2281  int offset_w = args.scalar<int>("offset_w");
2282  int stride_p = args.scalar<int>("stride_p");
2283  int stride_u = args.scalar<int>("stride_u");
2284  int stride_v = args.scalar<int>("stride_v");
2285  int stride_w = args.scalar<int>("stride_w");
2286  xt::pyarray<double>& globalResidual = args.array<double>("globalResidual");
2287  int nExteriorElementBoundaries_global = args.scalar<int>("nExteriorElementBoundaries_global");
2288  xt::pyarray<int>& exteriorElementBoundariesArray = args.array<int>("exteriorElementBoundariesArray");
2289  xt::pyarray<int>& elementBoundariesArray = args.array<int>("elementBoundariesArray");
2290  xt::pyarray<int>& elementBoundaryElementsArray = args.array<int>("elementBoundaryElementsArray");
2291  xt::pyarray<int>& elementBoundaryLocalElementBoundariesArray = args.array<int>("elementBoundaryLocalElementBoundariesArray");
2292  xt::pyarray<double>& ebqe_vf_ext = args.array<double>("ebqe_vf_ext");
2293  xt::pyarray<double>& bc_ebqe_vf_ext = args.array<double>("bc_ebqe_vf_ext");
2294  xt::pyarray<double>& ebqe_phi_ext = args.array<double>("ebqe_phi_ext");
2295  xt::pyarray<double>& bc_ebqe_phi_ext = args.array<double>("bc_ebqe_phi_ext");
2296  xt::pyarray<double>& ebqe_normal_phi_ext = args.array<double>("ebqe_normal_phi_ext");
2297  xt::pyarray<double>& ebqe_kappa_phi_ext = args.array<double>("ebqe_kappa_phi_ext");
2298  const xt::pyarray<double>& ebqe_porosity_ext = args.array<double>("ebqe_porosity_ext");
2299  const xt::pyarray<double>& ebqe_turb_var_0 = args.array<double>("ebqe_turb_var_0");
2300  const xt::pyarray<double>& ebqe_turb_var_1 = args.array<double>("ebqe_turb_var_1");
2301  xt::pyarray<int>& isDOFBoundary_p = args.array<int>("isDOFBoundary_p");
2302  xt::pyarray<int>& isDOFBoundary_u = args.array<int>("isDOFBoundary_u");
2303  xt::pyarray<int>& isDOFBoundary_v = args.array<int>("isDOFBoundary_v");
2304  xt::pyarray<int>& isDOFBoundary_w = args.array<int>("isDOFBoundary_w");
2305  xt::pyarray<int>& isAdvectiveFluxBoundary_p = args.array<int>("isAdvectiveFluxBoundary_p");
2306  xt::pyarray<int>& isAdvectiveFluxBoundary_u = args.array<int>("isAdvectiveFluxBoundary_u");
2307  xt::pyarray<int>& isAdvectiveFluxBoundary_v = args.array<int>("isAdvectiveFluxBoundary_v");
2308  xt::pyarray<int>& isAdvectiveFluxBoundary_w = args.array<int>("isAdvectiveFluxBoundary_w");
2309  xt::pyarray<int>& isDiffusiveFluxBoundary_u = args.array<int>("isDiffusiveFluxBoundary_u");
2310  xt::pyarray<int>& isDiffusiveFluxBoundary_v = args.array<int>("isDiffusiveFluxBoundary_v");
2311  xt::pyarray<int>& isDiffusiveFluxBoundary_w = args.array<int>("isDiffusiveFluxBoundary_w");
2312  xt::pyarray<double>& ebqe_bc_p_ext = args.array<double>("ebqe_bc_p_ext");
2313  xt::pyarray<double>& ebqe_bc_flux_mass_ext = args.array<double>("ebqe_bc_flux_mass_ext");
2314  xt::pyarray<double>& ebqe_bc_flux_mom_u_adv_ext = args.array<double>("ebqe_bc_flux_mom_u_adv_ext");
2315  xt::pyarray<double>& ebqe_bc_flux_mom_v_adv_ext = args.array<double>("ebqe_bc_flux_mom_v_adv_ext");
2316  xt::pyarray<double>& ebqe_bc_flux_mom_w_adv_ext = args.array<double>("ebqe_bc_flux_mom_w_adv_ext");
2317  xt::pyarray<double>& ebqe_bc_u_ext = args.array<double>("ebqe_bc_u_ext");
2318  xt::pyarray<double>& ebqe_bc_flux_u_diff_ext = args.array<double>("ebqe_bc_flux_u_diff_ext");
2319  xt::pyarray<double>& ebqe_penalty_ext = args.array<double>("ebqe_penalty_ext");
2320  xt::pyarray<double>& ebqe_bc_v_ext = args.array<double>("ebqe_bc_v_ext");
2321  xt::pyarray<double>& ebqe_bc_flux_v_diff_ext = args.array<double>("ebqe_bc_flux_v_diff_ext");
2322  xt::pyarray<double>& ebqe_bc_w_ext = args.array<double>("ebqe_bc_w_ext");
2323  xt::pyarray<double>& ebqe_bc_flux_w_diff_ext = args.array<double>("ebqe_bc_flux_w_diff_ext");
2324  xt::pyarray<double>& q_x = args.array<double>("q_x");
2325  xt::pyarray<double>& q_u_0 = args.array<double>("q_u_0");
2326  xt::pyarray<double>& q_u_1 = args.array<double>("q_u_1");
2327  xt::pyarray<double>& q_u_2 = args.array<double>("q_u_2");
2328  xt::pyarray<double>& q_u_3 = args.array<double>("q_u_3");
2329  xt::pyarray<double>& q_velocity = args.array<double>("q_velocity");
2330  xt::pyarray<double>& ebqe_velocity = args.array<double>("ebqe_velocity");
2331  xt::pyarray<double>& flux = args.array<double>("flux");
2332  xt::pyarray<double>& elementResidual_p_save = args.array<double>("elementResidual_p_save");
2333  xt::pyarray<int>& elementFlags = args.array<int>("elementFlags");
2334  xt::pyarray<int>& boundaryFlags = args.array<int>("boundaryFlags");
2335  xt::pyarray<double>& barycenters = args.array<double>("barycenters");
2336  xt::pyarray<double>& wettedAreas = args.array<double>("wettedAreas");
2337  xt::pyarray<double>& netForces_p = args.array<double>("netForces_p");
2338  xt::pyarray<double>& netForces_v = args.array<double>("netForces_v");
2339  xt::pyarray<double>& netMoments = args.array<double>("netMoments");
2340  xt::pyarray<double>& velocityError = args.array<double>("velocityError");
2341  xt::pyarray<double>& velocityErrorNodal = args.array<double>("velocityErrorNodal");
2342  xt::pyarray<double>& forcex = args.array<double>("forcex");
2343  xt::pyarray<double>& forcey = args.array<double>("forcey");
2344  xt::pyarray<double>& forcez = args.array<double>("forcez");
2345  int use_ball_as_particle = args.scalar<int>("use_ball_as_particle");
2346  xt::pyarray<double>& ball_center = args.array<double>("ball_center");
2347  xt::pyarray<double>& ball_radius = args.array<double>("ball_radius");
2348  xt::pyarray<double>& ball_velocity = args.array<double>("ball_velocity");
2349  xt::pyarray<double>& ball_angular_velocity = args.array<double>("ball_angular_velocity");
2350  xt::pyarray<double>& ball_density = args.array<double>("ball_density");
2351  xt::pyarray<double>& particle_signed_distances = args.array<double>("particle_signed_distances");
2352  xt::pyarray<double>& particle_signed_distance_normals = args.array<double>("particle_signed_distance_normals");
2353  xt::pyarray<double>& particle_velocities = args.array<double>("particle_velocities");
2354  xt::pyarray<double>& particle_centroids = args.array<double>("particle_centroids");
2355  xt::pyarray<double>& ebqe_phi_s = args.array<double>("ebqe_phi_s");
2356  xt::pyarray<double>& ebq_global_grad_phi_s = args.array<double>("ebq_global_grad_phi_s");
2357  xt::pyarray<double>& ebq_particle_velocity_s = args.array<double>("ebq_particle_velocity_s");
2358  int nParticles = args.scalar<int>("nParticles");
2359  xt::pyarray<double>& particle_netForces = args.array<double>("particle_netForces");
2360  xt::pyarray<double>& particle_netMoments = args.array<double>("particle_netMoments");
2361  xt::pyarray<double>& particle_surfaceArea = args.array<double>("particle_surfaceArea");
2362  int nElements_owned = args.scalar<int>("nElements_owned");
2363  double particle_nitsche = args.scalar<double>("particle_nitsche");
2364  double particle_epsFact = args.scalar<double>("particle_epsFact");
2365  double particle_alpha = args.scalar<double>("particle_alpha");
2366  double particle_beta = args.scalar<double>("particle_beta");
2367  double particle_penalty_constant = args.scalar<double>("particle_penalty_constant");
2368  double ghost_penalty_constant = args.scalar<double>("ghost_penalty_constant");
2369  xt::pyarray<double>& phi_solid_nodes = args.array<double>("phi_solid_nodes");
2370  xt::pyarray<double>& distance_to_solids = args.array<double>("distance_to_solids");
2371  bool useExact = args.scalar<int>("useExact");
2372  xt::pyarray<double>& isActiveR = args.array<double>("isActiveR");
2373  xt::pyarray<double>& isActiveDOF_p = args.array<double>("isActiveDOF_p");
2374  xt::pyarray<double>& isActiveDOF_vel = args.array<double>("isActiveDOF_vel");
2375  const bool normalize_pressure = args.scalar<int>("normalize_pressure");
2376  xt::pyarray<double>& errors = args.array<double>("errors");
2377  xt::pyarray<double>& ball_u = args.array<double>("ball_u");
2378  xt::pyarray<double>& ball_v = args.array<double>("ball_v");
2379  xt::pyarray<double>& ball_w = args.array<double>("ball_w");
2380  xt::pyarray<int>& isActiveElement = args.array<int>("isActiveElement");
2381  xt::pyarray<int>& isActiveElement_last = args.array<int>("isActiveElement_last");
2382  logEvent("Entered mprans calculateResidual",6);
2383  gf.useExact = false;//useExact;
2384  gf_p.useExact = false;//useExact;
2385  gf_s.useExact = useExact;
2386  ifem_boundaries.clear();
2387  ifem_boundary_elements.clear();
2388  cutfem_boundaries.clear();
2389  cutfem_local_boundaries.clear();
2390  const int nQuadraturePoints_global(nElements_global*nQuadraturePoints_element);
2391  //
2392  //loop over elements to compute volume integrals and load them into element and global residual
2393  //
2394  double p_dv=0.0,pa_dv=0.0,total_volume=0.0,total_surface_area=0.0,total_flux=0.0;
2395  double mesh_volume_conservation=0.0,
2396  mesh_volume_conservation_weak=0.0,
2397  mesh_volume_conservation_err_max=0.0,
2398  mesh_volume_conservation_err_max_weak=0.0,
2399  domain_volume=0.0,
2400  &p_L1=errors(0,0),&u_L1=errors(0,1),&v_L1=errors(0,2),&w_L1=errors(0,3),&velocity_L1=errors(0,4),
2401  &p_L2=errors(1,0),&u_L2=errors(1,1),&v_L2=errors(1,2),&w_L2=errors(1,3),&velocity_L2=errors(1,4),
2402  &p_LI=errors(2,0),&u_LI=errors(2,1),&v_LI=errors(2,2),&w_LI=errors(2,3),&velocity_LI=errors(2,4);
2403  p_L1=0.0; u_L1=0.0; v_L1=0.0; w_L1=0.0; velocity_L1=0.0;
2404  p_L2=0.0; u_L2=0.0; v_L2=0.0; w_L2=0.0; velocity_L2=0.0;
2405  p_LI=0.0; u_LI=0.0; v_LI=0.0; w_LI=0.0; velocity_LI=0.0;
2406  double globalConservationError=0.0;
2407  /* std::cout<<"Ball Info: center "<<ball_center[0]<<'\t'<<ball_center[1]<<std::endl */
2408  /* <<"Ball Info: radius "<<ball_radius[0]<<std::endl */
2409  /* <<"Ball Info: velocity "<<ball_velocity[0]<<'\t'<<ball_velocity[1]<<'\t'<<ball_velocity[2]<<std::endl */
2410  /* <<"Ball Info: angular "<<ball_angular_velocity[0]<<ball_angular_velocity[1]<<ball_angular_velocity[2]<<std::endl; */
2411  for(int eN=0;eN<nElements_global;eN++)
2412  {
2413  //declare local storage for element residual and initialize
2414  register double elementResidual_p[nDOF_test_element],elementResidual_p_check[nDOF_test_element],elementResidual_mesh[nDOF_test_element],
2415  elementResidual_u[nDOF_v_test_element],
2416  elementResidual_v[nDOF_v_test_element],
2417  elementResidual_w[nDOF_v_test_element],
2418  pelementResidual_u[nDOF_v_test_element],
2419  pelementResidual_v[nDOF_v_test_element],
2420  pelementResidual_w[nDOF_v_test_element],
2421  velocityErrorElement[nDOF_v_test_element],
2422  eps_rho,eps_mu;
2423  bool element_active=false;
2424  isActiveElement[eN]=0;
2425  double mesh_volume_conservation_element=0.0,
2426  mesh_volume_conservation_element_weak=0.0;
2427  int particle_index=0;
2428  for (int i=0;i<nDOF_test_element;i++)
2429  {
2430  int eN_i = eN*nDOF_test_element+i;
2431  elementResidual_p_save.data()[eN_i]=0.0;
2432  elementResidual_mesh[i]=0.0;
2433  elementResidual_p[i]=0.0;
2434  elementResidual_p_check[i]=0.0;
2435  }
2436  for (int i=0;i<nDOF_v_test_element;i++)
2437  {
2438  elementResidual_u[i]=0.0;
2439  elementResidual_v[i]=0.0;
2440  elementResidual_w[i]=0.0;
2441  pelementResidual_u[i]=0.0;
2442  pelementResidual_v[i]=0.0;
2443  pelementResidual_w[i]=0.0;
2444  velocityErrorElement[i]=0.0;
2445  }//i
2446  //Use for plotting result
2447  if(use_ball_as_particle==1 && nParticles > 0)
2448  {
2449  double min_d = 1e10;
2450  for (int I=0;I<nDOF_mesh_trial_element;I++)
2451  {
2452  int index = get_distance_to_ball(nParticles, ball_center.data(), ball_radius.data(),
2453  mesh_dof.data()[3*mesh_l2g.data()[eN*nDOF_mesh_trial_element+I]+0],
2454  mesh_dof.data()[3*mesh_l2g.data()[eN*nDOF_mesh_trial_element+I]+1],
2455  mesh_dof.data()[3*mesh_l2g.data()[eN*nDOF_mesh_trial_element+I]+2],
2456  phi_solid_nodes.data()[mesh_l2g.data()[eN*nDOF_mesh_trial_element+I]]);
2457  if (phi_solid_nodes.data()[mesh_l2g.data()[eN*nDOF_mesh_trial_element+I]] < min_d)
2458  {
2459  min_d = phi_solid_nodes.data()[mesh_l2g.data()[eN*nDOF_mesh_trial_element+I]];
2460  particle_index = index;
2461  }
2462  }
2463  }
2464  else
2465  {
2466  //phi_solid_nodes is updated in PreStep
2467  }
2468  double element_phi[nDOF_mesh_trial_element], element_phi_s[nDOF_mesh_trial_element];
2469  for (int j=0;j<nDOF_mesh_trial_element;j++)
2470  {
2471  register int eN_j = eN*nDOF_mesh_trial_element+j;
2472  element_phi[j] = phi_nodes.data()[p_l2g.data()[eN_j]];
2473  element_phi_s[j] = phi_solid_nodes.data()[p_l2g.data()[eN_j]];
2474  }
2475  double element_nodes[nDOF_mesh_trial_element*3];
2476  for (int i=0;i<nDOF_mesh_trial_element;i++)
2477  {
2478  register int eN_i=eN*nDOF_mesh_trial_element+i;
2479  for(int I=0;I<3;I++)
2480  element_nodes[i*3 + I] = mesh_dof.data()[mesh_l2g.data()[eN_i]*3 + I];
2481  }//i
2482  int icase_s = gf_s.calculate(element_phi_s, element_nodes, x_ref.data(),false);
2483  if (icase_s == 0)
2484  {
2485  element_active=true;
2486  isActiveElement[eN]=1;
2487  //only works for simplices
2488  for (int ebN_element=0;ebN_element < nDOF_mesh_trial_element; ebN_element++)
2489  {
2490  const int ebN = elementBoundariesArray.data()[eN*nDOF_mesh_trial_element+ebN_element];
2491  //internal and actually a cut edge
2492  //if (elementBoundaryElementsArray.data()[ebN*2+1] != -1 && (ebN < nElementBoundaries_owned) && element_phi_s[(ebN_element+1)%nDOF_mesh_trial_element]*element_phi_s[(ebN_element+2)%nDOF_mesh_trial_element] < 0.0)
2493  if (elementBoundaryElementsArray[ebN*2+1] != -1 && element_phi_s[(ebN_element+1)%nDOF_mesh_trial_element]*element_phi_s[(ebN_element+2)%nDOF_mesh_trial_element] <= 0.0)
2494  {
2495  cutfem_boundaries.insert(ebN);
2496  if (elementBoundaryElementsArray[ebN*2 + 0] == eN)
2497  cutfem_local_boundaries[ebN] = ebN_element;
2498  }
2499  }
2500  }
2501  else if (icase_s == 1)
2502  {
2503  element_active=true;
2504  isActiveElement[eN]=1;
2505  }
2506 #ifdef IFEM
2507  int icase_p = gf_p.calculate(element_phi, element_nodes, x_ref.data(), -rho_1*g.data()[1], -rho_0*g.data()[1],false,true);
2508  int icase = gf.calculate(element_phi, element_nodes, x_ref.data(), rho_1*nu_1, rho_0*nu_0,false,false);
2509 #else
2510  int icase_p = gf_p.calculate(element_phi, element_nodes, x_ref.data(), 1.,1.,false,false);
2511  int icase = gf.calculate(element_phi, element_nodes, x_ref.data(), 1.,1.,false,false);
2512 #endif
2513  if (icase == 0)
2514  {
2515  //only works for simplices
2516  for (int ebN_element=0;ebN_element < nDOF_mesh_trial_element; ebN_element++)
2517  {
2518  const int ebN = elementBoundariesArray.data()[eN*nDOF_mesh_trial_element+ebN_element];
2519  //if (elementBoundaryElementsArray.data()[ebN*2+1] != -1 && (ebN < nElementBoundaries_owned))
2520  // ifem_boundaries.insert(ebN);
2521  ifem_boundaries.insert(ebN);
2522  }
2523  }
2524  //
2525  //loop over quadrature points and compute integrands
2526  //
2527  double numDiffMax=0.0;
2528  for(int fluid_phase=0;fluid_phase < 2 - abs(icase);fluid_phase++)
2529  {
2530  for(int k=0;k<nQuadraturePoints_element;k++)
2531  {
2532  //compute indices and declare local storage
2533  register int eN_k = eN*nQuadraturePoints_element+k,
2534  eN_k_nSpace = eN_k*nSpace,
2535  eN_k_3d = eN_k*3,
2536  eN_nDOF_trial_element = eN*nDOF_trial_element,
2537  eN_nDOF_v_trial_element = eN*nDOF_v_trial_element;
2538  register double p=0.0,u=0.0,v=0.0,w=0.0,
2539  grad_p[nSpace]=ZEROVEC,grad_u[nSpace]=ZEROVEC,grad_v[nSpace]=ZEROVEC,grad_w[nSpace]=ZEROVEC,
2540  p_old=0.0,u_old=0.0,v_old=0.0,w_old=0.0,
2541  grad_p_old[nSpace]=ZEROVEC,grad_u_old[nSpace]=ZEROVEC,grad_v_old[nSpace]=ZEROVEC,grad_w_old[nSpace]=ZEROVEC,
2542  mom_u_acc=0.0,
2543  dmom_u_acc_u=0.0,
2544  mom_v_acc=0.0,
2545  dmom_v_acc_v=0.0,
2546  mom_w_acc=0.0,
2547  dmom_w_acc_w=0.0,
2548  mass_adv[nSpace]=ZEROVEC,
2549  dmass_adv_u[nSpace]=ZEROVEC,
2550  dmass_adv_v[nSpace]=ZEROVEC,
2551  dmass_adv_w[nSpace]=ZEROVEC,
2552  mass_ham=0.0,
2553  dmass_ham_u=0.0,
2554  dmass_ham_v=0.0,
2555  dmass_ham_w=0.0,
2556  mom_u_adv[nSpace]=ZEROVEC,
2557  dmom_u_adv_u[nSpace]=ZEROVEC,
2558  dmom_u_adv_v[nSpace]=ZEROVEC,
2559  dmom_u_adv_w[nSpace]=ZEROVEC,
2560  mom_v_adv[nSpace]=ZEROVEC,
2561  dmom_v_adv_u[nSpace]=ZEROVEC,
2562  dmom_v_adv_v[nSpace]=ZEROVEC,
2563  dmom_v_adv_w[nSpace]=ZEROVEC,
2564  mom_w_adv[nSpace]=ZEROVEC,
2565  dmom_w_adv_u[nSpace]=ZEROVEC,
2566  dmom_w_adv_v[nSpace]=ZEROVEC,
2567  dmom_w_adv_w[nSpace]=ZEROVEC,
2568  mom_uu_diff_ten[nSpace]=ZEROVEC,
2569  mom_vv_diff_ten[nSpace]=ZEROVEC,
2570  mom_ww_diff_ten[nSpace]=ZEROVEC,
2571  mom_uv_diff_ten[1],
2572  mom_uw_diff_ten[1],
2573  mom_vu_diff_ten[1],
2574  mom_vw_diff_ten[1],
2575  mom_wu_diff_ten[1],
2576  mom_wv_diff_ten[1],
2577  mom_u_source=0.0,
2578  mom_v_source=0.0,
2579  mom_w_source=0.0,
2580  mom_u_ham=0.0,
2581  dmom_u_ham_grad_p[nSpace]=ZEROVEC,
2582  dmom_u_ham_grad_u[nSpace]=ZEROVEC,
2583  dmom_u_ham_grad_v[nSpace]=ZEROVEC,
2584  dmom_u_ham_grad_w[nSpace]=ZEROVEC,
2585  dmom_u_ham_u=0.0,
2586  dmom_u_ham_v=0.0,
2587  dmom_u_ham_w=0.0,
2588  mom_v_ham=0.0,
2589  dmom_v_ham_grad_p[nSpace]=ZEROVEC,
2590  dmom_v_ham_grad_u[nSpace]=ZEROVEC,
2591  dmom_v_ham_grad_v[nSpace]=ZEROVEC,
2592  dmom_v_ham_grad_w[nSpace]=ZEROVEC,
2593  dmom_v_ham_u=0.0,
2594  dmom_v_ham_v=0.0,
2595  dmom_v_ham_w=0.0,
2596  mom_w_ham=0.0,
2597  dmom_w_ham_grad_p[nSpace]=ZEROVEC,
2598  dmom_w_ham_grad_u[nSpace]=ZEROVEC,
2599  dmom_w_ham_grad_v[nSpace]=ZEROVEC,
2600  dmom_w_ham_grad_w[nSpace]=ZEROVEC,
2601  dmom_w_ham_u=0.0,
2602  dmom_w_ham_v=0.0,
2603  dmom_w_ham_w=0.0,
2604  mom_u_acc_t=0.0,
2605  dmom_u_acc_u_t=0.0,
2606  mom_v_acc_t=0.0,
2607  dmom_v_acc_v_t=0.0,
2608  mom_w_acc_t=0.0,
2609  dmom_w_acc_w_t=0.0,
2610  pdeResidual_p=0.0,
2611  pdeResidual_u=0.0,
2612  pdeResidual_v=0.0,
2613  pdeResidual_w=0.0,
2614  Lstar_u_p[nDOF_test_element],
2615  Lstar_v_p[nDOF_test_element],
2616  Lstar_w_p[nDOF_test_element],
2617  Lstar_u_u[nDOF_v_test_element],
2618  Lstar_v_v[nDOF_v_test_element],
2619  Lstar_w_w[nDOF_v_test_element],
2620  Lstar_p_u[nDOF_v_test_element],
2621  Lstar_p_v[nDOF_v_test_element],
2622  Lstar_p_w[nDOF_v_test_element],
2623  subgridError_p=0.0,
2624  subgridError_u=0.0,
2625  subgridError_v=0.0,
2626  subgridError_w=0.0,
2627  tau_p=0.0,tau_p0=0.0,tau_p1=0.0,
2628  tau_v=0.0,tau_v0=0.0,tau_v1=0.0,
2629  jac[nSpace*nSpace],
2630  jacDet,
2631  jacInv[nSpace*nSpace],
2632  p_trial[nDOF_trial_element], vel_trial[nDOF_v_trial_element],
2633  p_grad_trial_ib[nDOF_trial_element*nSpace], vel_grad_trial_ib[nDOF_v_trial_element*nSpace],
2634  p_grad_trial[nDOF_trial_element*nSpace],vel_grad_trial[nDOF_v_trial_element*nSpace],
2635  p_test_dV[nDOF_trial_element],vel_test_dV[nDOF_v_test_element],
2636  p_grad_test_dV[nDOF_test_element*nSpace],vel_grad_test_dV[nDOF_v_test_element*nSpace],
2637  dV,x,y,z,xt,yt,zt,
2638  p_element_avg=0.0,
2639  //
2640  porosity,
2641  //meanGrainSize,
2642  mass_source,
2643  dmom_u_source[nSpace]=ZEROVEC,
2644  dmom_v_source[nSpace]=ZEROVEC,
2645  dmom_w_source[nSpace]=ZEROVEC,
2646  //
2647  G[nSpace*nSpace],G_dd_G,tr_G,norm_Rv,h_phi, dmom_adv_star[nSpace]=ZEROVEC,dmom_adv_sge[nSpace]=ZEROVEC,dmom_ham_grad_sge[nSpace]=ZEROVEC,
2648  //embedded solid terms
2649  mass_source_s=0.0,
2650  mom_u_source_s=0.0,
2651  mom_v_source_s=0.0,
2652  mom_w_source_s=0.0,
2653  dmom_u_source_s[nSpace]=ZEROVEC,
2654  dmom_v_source_s[nSpace]=ZEROVEC,
2655  dmom_w_source_s[nSpace]=ZEROVEC,
2656  mom_u_adv_s[nSpace]=ZEROVEC,
2657  mom_v_adv_s[nSpace]=ZEROVEC,
2658  mom_w_adv_s[nSpace]=ZEROVEC,
2659  dmom_u_adv_u_s[nSpace]=ZEROVEC,
2660  dmom_v_adv_v_s[nSpace]=ZEROVEC,
2661  dmom_w_adv_w_s[nSpace]=ZEROVEC,
2662  mom_u_ham_s=0.0,
2663  dmom_u_ham_grad_u_s[nSpace]=ZEROVEC,
2664  dmom_u_ham_grad_v_s[nSpace]=ZEROVEC,
2665  dmom_u_ham_grad_w_s[nSpace]=ZEROVEC,
2666  dmom_u_ham_u_s=0.0,
2667  dmom_u_ham_v_s=0.0,
2668  dmom_u_ham_w_s=0.0,
2669  mom_v_ham_s=0.0,
2670  dmom_v_ham_grad_u_s[nSpace]=ZEROVEC,
2671  dmom_v_ham_grad_v_s[nSpace]=ZEROVEC,
2672  dmom_v_ham_grad_w_s[nSpace]=ZEROVEC,
2673  dmom_v_ham_u_s=0.0,
2674  dmom_v_ham_v_s=0.0,
2675  dmom_v_ham_w_s=0.0,
2676  mom_w_ham_s=0.0,
2677  dmom_w_ham_grad_u_s[nSpace]=ZEROVEC,
2678  dmom_w_ham_grad_v_s[nSpace]=ZEROVEC,
2679  dmom_w_ham_grad_w_s[nSpace]=ZEROVEC,
2680  dmom_w_ham_u_s=0.0,
2681  dmom_w_ham_v_s=0.0,
2682  dmom_w_ham_w_s=0.0,
2683  mass_ham_s=0.0,
2684  dmass_ham_u_s=0.0,
2685  dmass_ham_v_s=0.0,
2686  dmass_ham_w_s=0.0;
2687  //get jacobian, etc for mapping reference element
2688  gf_s.set_quad(k);
2689  gf.set_quad(k);
2690  gf_p.set_quad(k);
2691  ck.calculateMapping_element(eN,
2692  k,
2693  mesh_dof.data(),
2694  mesh_l2g.data(),
2695  mesh_trial_ref.data(),
2696  mesh_grad_trial_ref.data(),
2697  jac,
2698  jacDet,
2699  jacInv,
2700  x,y,z);
2701  ck.calculateH_element(eN,
2702  k,
2703  nodeDiametersArray.data(),
2704  mesh_l2g.data(),
2705  mesh_trial_ref.data(),
2706  h_phi);
2707 
2708  ck.calculateMappingVelocity_element(eN,
2709  k,
2710  mesh_velocity_dof.data(),
2711  mesh_l2g.data(),
2712  mesh_trial_ref.data(),
2713  xt,yt,zt);
2714  //xt=0.0;yt=0.0;zt=0.0;
2715  //std::cout<<"xt "<<xt<<'\t'<<yt<<'\t'<<zt<<std::endl;
2716  //get the physical integration weight
2717  dV = fabs(jacDet)*dV_ref.data()[k];
2718  ck.calculateG(jacInv,G,G_dd_G,tr_G);
2719  //ck.calculateGScale(G,&normal_phi.data()[eN_k_nSpace],h_phi);
2720 
2721  eps_rho = epsFact_rho*(useMetrics*h_phi+(1.0-useMetrics)*elementDiameter.data()[eN]);
2722  eps_mu = epsFact_mu *(useMetrics*h_phi+(1.0-useMetrics)*elementDiameter.data()[eN]);
2723 
2724  //get the trial function gradients
2725  ck.gradTrialFromRef(&p_grad_trial_ref.data()[k*nDOF_trial_element*nSpace],jacInv,p_grad_trial);
2726  ck_v.gradTrialFromRef(&vel_grad_trial_ref.data()[k*nDOF_v_trial_element*nSpace],jacInv,vel_grad_trial);
2727  for (int i=0; i < nDOF_trial_element; i++)
2728  {
2729  p_trial[i] = p_trial_ref.data()[k*nDOF_trial_element + i];
2730  p_grad_trial_ib[i*nSpace + 0] = p_grad_trial[i*nSpace+0];
2731  p_grad_trial_ib[i*nSpace + 1] = p_grad_trial[i*nSpace+1];
2732  p_grad_trial_ib[i*nSpace + 2] = p_grad_trial[i*nSpace+2];
2733  }
2734  for (int i=0; i < nDOF_v_trial_element; i++)
2735  {
2736  vel_trial[i] = vel_trial_ref.data()[k*nDOF_v_trial_element + i];
2737  vel_grad_trial_ib[i*nSpace + 0] = vel_grad_trial[i*nSpace+0];
2738  vel_grad_trial_ib[i*nSpace + 1] = vel_grad_trial[i*nSpace+1];
2739  vel_grad_trial_ib[i*nSpace + 2] = vel_grad_trial[i*nSpace+2];
2740  }
2741  if (icase == 0)
2742  {
2743 #ifdef IFEMBASIS
2744  for (int i=0; i < nDOF_trial_element; i++)
2745  {
2746  if (fluid_phase == 0)
2747  {
2748  if (not std::isnan(gf_p.VA(i)))
2749  {
2750  p_trial[i] = gf_p.VA(i);
2751  p_grad_trial_ib[i*nSpace + 0] = gf_p.VA_x(i);
2752  p_grad_trial_ib[i*nSpace + 1] = gf_p.VA_y(i);
2753  p_grad_trial_ib[i*nSpace + 2] = gf_p.VA_z(i);
2754  }
2755  }
2756  else
2757  {
2758  if (not std::isnan(gf_p.VB(i)))
2759  {
2760  p_trial[i] = gf_p.VB(i);
2761  p_grad_trial_ib[i*nSpace + 0] = gf_p.VB_x(i);
2762  p_grad_trial_ib[i*nSpace + 1] = gf_p.VB_y(i);
2763  p_grad_trial_ib[i*nSpace + 2] = gf_p.VB_z(i);
2764  }
2765  }
2766  }
2767  if(nDOF_v_trial_element == nDOF_trial_element)
2768  {
2769  for (int vi=0; vi < nDOF_v_trial_element; vi++)
2770  {
2771  if (fluid_phase == 0)
2772  {
2773  if (not std::isnan(gf.VA(vi)))
2774  {
2775  vel_trial[vi] = gf.VA(vi);
2776  vel_grad_trial_ib[vi*nSpace + 0] = gf.VA_x(vi);
2777  vel_grad_trial_ib[vi*nSpace + 1] = gf.VA_y(vi);
2778  vel_grad_trial_ib[vi*nSpace + 2] = gf.VA_z(vi);
2779  }
2780  }
2781  else
2782  {
2783  if (not std::isnan(gf.VB(vi)))
2784  {
2785  vel_trial[vi] = gf.VB(vi);
2786  vel_grad_trial_ib[vi*nSpace + 0] = gf.VB_x(vi);
2787  vel_grad_trial_ib[vi*nSpace + 1] = gf.VB_y(vi);
2788  vel_grad_trial_ib[vi*nSpace + 2] = gf.VB_z(vi);
2789  }
2790  }
2791  }
2792  }
2793 #endif
2794 #ifndef IFEM
2795  bool prob=false;
2796  for (int vi=0; vi < nDOF_v_trial_element; vi++)
2797  {
2798  //pressure
2799  if (fabs(p_trial_ref.data()[k*nDOF_trial_element + vi] - p_trial[vi]) > 1.0e-8)
2800  {
2801  for (int vj=0; vj < nDOF_trial_element; vj++)
2802  std::cout<<"Trial "<<p_trial_ref.data()[k*nDOF_trial_element + vj]<<'\t'<<gf_p.VA(vj)<<'\t'<<gf_p.VB(vj)<<std::endl;
2803  prob=true;
2804  }
2805  if (fabs(p_grad_trial[vi*nSpace + 0] - p_grad_trial_ib[vi*nSpace+0]) > 1.0e-8)
2806  {
2807  for (int vj=0; vj < nDOF_trial_element; vj++)
2808  std::cout<<"Grad Trial x"<<p_grad_trial[vj*nSpace + 0]<<'\t'<<gf_p.VA_x(vj)<<'\t'<<gf_p.VB_x(vj)<<std::endl;
2809  prob=true;
2810  }
2811  if (fabs(p_grad_trial[vi*nSpace + 1] - p_grad_trial_ib[vi*nSpace+1]) > 1.0e-8)
2812  {
2813  for (int vj=0; vj < nDOF_trial_element; vj++)
2814  std::cout<<"Grad Trial y "<<p_grad_trial[vj*nSpace + 1]<<'\t'<<gf_p.VA_y(vj)<<'\t'<<gf_p.VB_y(vj)<<std::endl;
2815  prob=true;
2816  }
2817  if (fabs(p_grad_trial[vi*nSpace + 2] - p_grad_trial_ib[vi*nSpace+2]) > 1.0e-8)
2818  {
2819  for (int vj=0; vj < nDOF_trial_element; vj++)
2820  std::cout<<"Grad Trial z "<<p_grad_trial[vj*nSpace + 2]<<'\t'<<gf_p.VA_z(vj)<<'\t'<<gf_p.VB_z(vj)<<std::endl;
2821  prob=true;
2822  }
2823  //velocity
2824  if (fabs(vel_trial_ref.data()[k*nDOF_v_trial_element + vi] - vel_trial[vi]) > 1.0e-8)
2825  {
2826  for (int vj=0; vj < nDOF_v_trial_element; vj++)
2827  std::cout<<"Trial "<<vel_trial_ref.data()[k*nDOF_v_trial_element + vj]<<'\t'<<gf.VA(vj)<<'\t'<<gf.VB(vj)<<std::endl;
2828  prob=true;
2829  }
2830  if (fabs(vel_grad_trial[vi*nSpace + 0] - vel_grad_trial_ib[vi*nSpace+0]) > 1.0e-8)
2831  {
2832  for (int vj=0; vj < nDOF_v_trial_element; vj++)
2833  std::cout<<"Grad Trial x"<<vel_grad_trial[vj*nSpace + 0]<<'\t'<<gf.VA_x(vj)<<'\t'<<gf.VB_x(vj)<<std::endl;
2834  prob=true;
2835  }
2836  if (fabs(vel_grad_trial[vi*nSpace + 1] - vel_grad_trial_ib[vi*nSpace+1]) > 1.0e-8)
2837  {
2838  for (int vj=0; vj < nDOF_v_trial_element; vj++)
2839  std::cout<<"Grad Trial y "<<vel_grad_trial[vj*nSpace + 1]<<'\t'<<gf.VA_y(vj)<<'\t'<<gf.VB_y(vj)<<std::endl;
2840  prob=true;
2841  }
2842  if (fabs(vel_grad_trial[vi*nSpace + 2] - vel_grad_trial_ib[vi*nSpace+2]) > 1.0e-8)
2843  {
2844  for (int vj=0; vj < nDOF_v_trial_element; vj++)
2845  std::cout<<"Grad Trial z "<<vel_grad_trial[vj*nSpace + 2]<<'\t'<<gf.VA_z(vj)<<'\t'<<gf.VB_z(vj)<<std::endl;
2846  prob=true;
2847  }
2848  if (prob)
2849  break;
2850  }
2851  assert(!prob);
2852 #endif
2853  }
2854  //get the solution
2855  ck.valFromDOF(p_dof.data(),&p_l2g.data()[eN_nDOF_trial_element],p_trial,p);
2856  ck_v.valFromDOF(u_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],vel_trial,u);
2857  ck_v.valFromDOF(v_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],vel_trial,v);
2858  ck_v.valFromDOF(w_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],vel_trial,w);
2859  ck.valFromDOF(p_old_dof.data(),&p_l2g.data()[eN_nDOF_trial_element],p_trial,p_old);
2860  ck_v.valFromDOF(u_old_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],vel_trial,u_old);
2861  ck_v.valFromDOF(v_old_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],vel_trial,v_old);
2862  ck_v.valFromDOF(w_old_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],vel_trial,w_old);
2863  //get the solution gradients
2864  ck.gradFromDOF(p_dof.data(),&p_l2g.data()[eN_nDOF_trial_element],p_grad_trial_ib,grad_p);
2865  ck_v.gradFromDOF(u_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],vel_grad_trial_ib,grad_u);
2866  ck_v.gradFromDOF(v_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],vel_grad_trial_ib,grad_v);
2867  ck_v.gradFromDOF(w_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],vel_grad_trial_ib,grad_w);
2868  ck.gradFromDOF(p_old_dof.data(),&p_l2g.data()[eN_nDOF_trial_element],p_grad_trial_ib,grad_p_old);
2869  ck_v.gradFromDOF(u_old_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],vel_grad_trial_ib,grad_u_old);
2870  ck_v.gradFromDOF(v_old_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],vel_grad_trial_ib,grad_v_old);
2871  ck_v.gradFromDOF(w_old_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],vel_grad_trial_ib,grad_w_old);
2872  // calculate the average pressure value
2873  if (PRESSURE_PROJECTION_STABILIZATION)
2874  ck.DOFaverage(p_dof.data(), &p_l2g.data()[eN_nDOF_trial_element],p_element_avg);
2875  //precalculate test function products with integration weights
2876 #ifdef IFEMGALERKIN
2877  for (int j=0;j<nDOF_test_element;j++)
2878  {
2879  p_test_dV[j] = p_trial[j]*dV;
2880  for (int I=0;I<nSpace;I++)
2881  {
2882  p_grad_test_dV[j*nSpace+I] = p_grad_trial_ib[j*nSpace+I]*dV;
2883  }
2884  }
2885  //precalculate test function products with integration weights
2886  for (int j=0;j<nDOF_v_test_element;j++)
2887  {
2888  vel_test_dV[j] = vel_trial[j]*dV;
2889  for (int I=0;I<nSpace;I++)
2890  {
2891  vel_grad_test_dV[j*nSpace+I] = vel_grad_trial_ib[j*nSpace+I]*dV;
2892  }
2893  }
2894 #else
2895  for (int j=0;j<nDOF_test_element;j++)
2896  {
2897  p_test_dV[j] = p_test_ref.data()[k*nDOF_trial_element+j]*dV;
2898  for (int I=0;I<nSpace;I++)
2899  {
2900  p_grad_test_dV[j*nSpace+I] = p_grad_trial[j*nSpace+I]*dV;//assume test_i = trial_i, not using ib basis here
2901  }
2902  }
2903  //precalculate test function products with integration weights
2904  for (int j=0;j<nDOF_v_test_element;j++)
2905  {
2906  vel_test_dV[j] = vel_test_ref.data()[k*nDOF_v_trial_element+j]*dV;
2907  for (int I=0;I<nSpace;I++)
2908  {
2909  vel_grad_test_dV[j*nSpace+I] = vel_grad_trial[j*nSpace+I]*dV;//assume test_i = trial_i
2910  }
2911  }
2912 #endif
2913  //todo: extend this to higher-order meshes, for now assume mesh trial and p trial are same
2914  double div_mesh_velocity=0.0;
2915  for (int j=0;j<nDOF_trial_element;j++)
2916  {
2917  int eN_j=eN*nDOF_trial_element+j;
2918  div_mesh_velocity +=
2919  mesh_velocity_dof.data()[mesh_l2g.data()[eN_j]*3+0]*p_grad_trial[j*nSpace+0] +
2920  mesh_velocity_dof.data()[mesh_l2g.data()[eN_j]*3+1]*p_grad_trial[j*nSpace+1] +
2921  mesh_velocity_dof.data()[mesh_l2g.data()[eN_j]*3+2]*p_grad_trial[j*nSpace+2];
2922  }
2923  mesh_volume_conservation_element += (alphaBDF*(dV-q_dV_last.data()[eN_k])/dV - div_mesh_velocity)*dV;
2924  div_mesh_velocity = DM3*div_mesh_velocity + (1.0-DM3)*alphaBDF*(dV-q_dV_last.data()[eN_k])/dV;
2925  //VRANS
2926  porosity = q_porosity.data()[eN_k];
2927  //
2928  q_velocity.data()[eN_k_nSpace+0]=u;
2929  q_velocity.data()[eN_k_nSpace+1]=v;
2930  q_velocity.data()[eN_k_nSpace+2]=w;
2931  q_x.data()[eN_k_3d + 0] = x;
2932  q_x.data()[eN_k_3d + 1] = y;
2933  q_x.data()[eN_k_3d + 2] = z;
2934  double ball_n[nSpace];
2935  if (use_ball_as_particle == 1 && nParticles > 0)
2936  {
2937  int ball_index=get_distance_to_ball(nParticles, ball_center.data(), ball_radius.data(),x,y,z,distance_to_solids.data()[eN_k]);
2938  get_normal_to_ith_ball(nParticles, ball_center.data(), ball_radius.data(),ball_index,x,y,z,ball_n[0],ball_n[1],ball_n[2]);
2939  }
2940  else
2941  {
2942  //distance_to_solids is given in Prestep
2943  }
2944  if (nParticles > 0)
2945  phi_solid.data()[eN_k] = distance_to_solids.data()[eN_k];
2946  const double particle_eps = particle_epsFact*(useMetrics*h_phi+(1.0-useMetrics)*elementDiameter.data()[eN]);
2947  //
2948  //calculate pde coefficients at quadrature points
2949  //
2950  const double H_s = gf_s.H(particle_eps,phi_solid.data()[eN_k]);
2951  const double D_s = gf_s.D(particle_eps,phi_solid.data()[eN_k]);
2952  //save velocity at quadrature points for other models to use
2953  double p_e = q_u_0.data()[eN_k] - p,
2954  u_e = q_u_1.data()[eN_k] - u,
2955  v_e = q_u_2.data()[eN_k] - v,
2956  w_e = q_u_3.data()[eN_k] - w,
2957  velocity_e = sqrt(u_e*u_e + v_e*v_e + w_e*w_e);
2958 
2959 
2960  /* q_u_0.data()[eN_k] = p; */
2961  /* q_u_1.data()[eN_k] = u; */
2962  /* q_u_2.data()[eN_k] = v; */
2963  /* q_u_3.data()[eN_k] = w; */
2964 
2965  double rho,nu;
2966  if (gf.useExact)
2967  {
2968  if (icase == 0)
2969  {
2970  if (fluid_phase == 0)
2971  {
2972  rho=rho_0;
2973  nu=nu_0;
2974  }
2975  else
2976  {
2977  rho=rho_1;
2978  nu=nu_1;
2979  }
2980  }
2981  else if (icase == -1)
2982  {
2983  rho=rho_0;
2984  nu=nu_0;
2985  }
2986  else if (icase == 1)
2987  {
2988  rho=rho_1;
2989  nu=nu_1;
2990  }
2991  else
2992  assert(false);
2993  }
2994  else
2995  {
2996  double H = (1.0-useVF)*gf.H(eps_rho,phi[eN_k]) + useVF*fmin(1.0,fmax(0.0,vf[eN_k]));
2997  double ImH = (1.0-useVF)*gf.ImH(eps_rho,phi[eN_k]) + useVF*(1.0-fmin(1.0,fmax(0.0,vf[eN_k])));
2998 
2999  rho = rho_0*ImH + rho_1*H;
3000  nu = nu_0*ImH + nu_1*H;
3001  }
3002  evaluateCoefficients(NONCONSERVATIVE_FORM,
3003  sigma,
3004  rho,
3005  nu,
3006  elementDiameter.data()[eN],
3007  smagorinskyConstant,
3008  turbulenceClosureModel,
3009  g.data(),
3010  useVF,
3011  vf.data()[eN_k],
3012  phi.data()[eN_k],
3013  &normal_phi.data()[eN_k_nSpace],
3014  kappa_phi.data()[eN_k],
3015  //VRANS
3016  porosity,
3017  phi_solid.data()[eN_k],//distance to solid
3018  p_old,
3019  u_old,
3020  v_old,
3021  w_old,
3022  grad_p_old,
3023  grad_u_old,
3024  grad_v_old,
3025  grad_w_old,
3026  //
3027  p,
3028  grad_p,
3029  grad_u,
3030  grad_v,
3031  grad_w,
3032  u,
3033  v,
3034  w,
3035  LAG_LES,
3036  q_eddy_viscosity.data()[eN_k],
3037  q_eddy_viscosity_last.data()[eN_k],
3038  mom_u_acc,
3039  dmom_u_acc_u,
3040  mom_v_acc,
3041  dmom_v_acc_v,
3042  mom_w_acc,
3043  dmom_w_acc_w,
3044  mass_adv,
3045  dmass_adv_u,
3046  dmass_adv_v,
3047  dmass_adv_w,
3048  mom_u_adv,
3049  dmom_u_adv_u,
3050  dmom_u_adv_v,
3051  dmom_u_adv_w,
3052  mom_v_adv,
3053  dmom_v_adv_u,
3054  dmom_v_adv_v,
3055  dmom_v_adv_w,
3056  mom_w_adv,
3057  dmom_w_adv_u,
3058  dmom_w_adv_v,
3059  dmom_w_adv_w,
3060  mom_uu_diff_ten,
3061  mom_vv_diff_ten,
3062  mom_ww_diff_ten,
3063  mom_uv_diff_ten,
3064  mom_uw_diff_ten,
3065  mom_vu_diff_ten,
3066  mom_vw_diff_ten,
3067  mom_wu_diff_ten,
3068  mom_wv_diff_ten,
3069  mom_u_source,
3070  mom_v_source,
3071  mom_w_source,
3072  mom_u_ham,
3073  dmom_u_ham_grad_p,
3074  dmom_u_ham_grad_u,
3075  dmom_u_ham_u,
3076  dmom_u_ham_v,
3077  dmom_u_ham_w,
3078  mom_v_ham,
3079  dmom_v_ham_grad_p,
3080  dmom_v_ham_grad_v,
3081  dmom_v_ham_u,
3082  dmom_v_ham_v,
3083  dmom_v_ham_w,
3084  mom_w_ham,
3085  dmom_w_ham_grad_p,
3086  dmom_w_ham_grad_w,
3087  dmom_w_ham_u,
3088  dmom_w_ham_v,
3089  dmom_w_ham_w,
3090  forcex.data()[eN_k],
3091  forcey.data()[eN_k],
3092  forcez.data()[eN_k]);
3093  q_rho.data()[eN_k] = rho;
3094  //VRANS
3095  mass_source = q_mass_source.data()[eN_k];
3096  //todo: decide if these should be lagged or not?
3097  updateDarcyForchheimerTerms_Ergun(NONCONSERVATIVE_FORM,
3098  /* linearDragFactor, */
3099  /* nonlinearDragFactor, */
3100  /* porosity, */
3101  /* meanGrainSize, */
3102  q_dragAlpha.data()[eN_k],
3103  q_dragBeta.data()[eN_k],
3104  eps_rho,
3105  eps_mu,
3106  rho_0,
3107  nu_0,
3108  rho_1,
3109  nu_1,
3110  useVF,
3111  vf.data()[eN_k],
3112  phi.data()[eN_k],
3113  u,
3114  v,
3115  w,
3116  q_velocity_sge.data()[eN_k_nSpace+0],
3117  q_velocity_sge.data()[eN_k_nSpace+1],
3118  q_velocity_sge.data()[eN_k_nSpace+2],
3119  eps_porous.data()[elementFlags.data()[eN]],
3120  phi_porous.data()[eN_k],
3121  q_velocity_porous.data()[eN_k_nSpace+0],
3122  q_velocity_porous.data()[eN_k_nSpace+1],
3123  q_velocity_porous.data()[eN_k_nSpace+2],
3124  mom_u_source,
3125  mom_v_source,
3126  mom_w_source,
3127  dmom_u_source,
3128  dmom_v_source,
3129  dmom_w_source);
3130  //Turbulence closure model
3131  if (turbulenceClosureModel >= 3)
3132  {
3133  const double c_mu = 0.09;//mwf hack
3134  updateTurbulenceClosure(NONCONSERVATIVE_FORM,
3135  turbulenceClosureModel,
3136  eps_rho,
3137  eps_mu,
3138  rho_0,
3139  nu_0,
3140  rho_1,
3141  nu_1,
3142  useVF,
3143  vf.data()[eN_k],
3144  phi.data()[eN_k],
3145  porosity,
3146  c_mu, //mwf hack
3147  q_turb_var_0.data()[eN_k],
3148  q_turb_var_1.data()[eN_k],
3149  &q_turb_var_grad_0.data()[eN_k_nSpace],
3150  q_eddy_viscosity.data()[eN_k],
3151  mom_uu_diff_ten,
3152  mom_vv_diff_ten,
3153  mom_ww_diff_ten,
3154  mom_uv_diff_ten,
3155  mom_uw_diff_ten,
3156  mom_vu_diff_ten,
3157  mom_vw_diff_ten,
3158  mom_wu_diff_ten,
3159  mom_wv_diff_ten,
3160  mom_u_source,
3161  mom_v_source,
3162  mom_w_source);
3163  }
3164  //
3165  //moving mesh
3166  //
3167  if (NONCONSERVATIVE_FORM > 0.0)
3168  {
3169  mom_u_ham -= MOVING_DOMAIN*dmom_u_acc_u*(grad_u[0]*xt + grad_u[1]*yt + grad_u[2]*zt);
3170  dmom_u_ham_grad_u[0] -= MOVING_DOMAIN*dmom_u_acc_u*xt;
3171  dmom_u_ham_grad_u[1] -= MOVING_DOMAIN*dmom_u_acc_u*yt;
3172  dmom_u_ham_grad_u[2] -= MOVING_DOMAIN*dmom_u_acc_u*zt;
3173  }
3174  else
3175  {
3176  mom_u_adv[0] -= MOVING_DOMAIN*mom_u_acc*xt;
3177  mom_u_adv[1] -= MOVING_DOMAIN*mom_u_acc*yt;
3178  mom_u_adv[2] -= MOVING_DOMAIN*mom_u_acc*zt;
3179  dmom_u_adv_u[0] -= MOVING_DOMAIN*dmom_u_acc_u*xt;
3180  dmom_u_adv_u[1] -= MOVING_DOMAIN*dmom_u_acc_u*yt;
3181  dmom_u_adv_u[2] -= MOVING_DOMAIN*dmom_u_acc_u*zt;
3182  }
3183 
3184  if (NONCONSERVATIVE_FORM > 0.0)
3185  {
3186  mom_v_ham -= MOVING_DOMAIN*dmom_v_acc_v*(grad_v[0]*xt + grad_v[1]*yt + grad_v[2]*zt);
3187  dmom_v_ham_grad_v[0] -= MOVING_DOMAIN*dmom_v_acc_v*xt;
3188  dmom_v_ham_grad_v[1] -= MOVING_DOMAIN*dmom_v_acc_v*yt;
3189  dmom_v_ham_grad_v[2] -= MOVING_DOMAIN*dmom_v_acc_v*zt;
3190  }
3191  else
3192  {
3193  mom_v_adv[0] -= MOVING_DOMAIN*mom_v_acc*xt;
3194  mom_v_adv[1] -= MOVING_DOMAIN*mom_v_acc*yt;
3195  mom_v_adv[2] -= MOVING_DOMAIN*mom_v_acc*zt;
3196  dmom_v_adv_v[0] -= MOVING_DOMAIN*dmom_v_acc_v*xt;
3197  dmom_v_adv_v[1] -= MOVING_DOMAIN*dmom_v_acc_v*yt;
3198  dmom_v_adv_v[2] -= MOVING_DOMAIN*dmom_v_acc_v*zt;
3199  }
3200 
3201  if (NONCONSERVATIVE_FORM > 0.0)
3202  {
3203  mom_w_ham -= MOVING_DOMAIN*dmom_w_acc_w*(grad_w[0]*xt + grad_w[1]*yt + grad_w[2]*zt);
3204  dmom_w_ham_grad_w[0] -= MOVING_DOMAIN*dmom_w_acc_w*xt;
3205  dmom_w_ham_grad_w[1] -= MOVING_DOMAIN*dmom_w_acc_w*yt;
3206  dmom_w_ham_grad_w[2] -= MOVING_DOMAIN*dmom_w_acc_w*zt;
3207  }
3208  else
3209  {
3210  mom_w_adv[0] -= MOVING_DOMAIN*mom_w_acc*xt;
3211  mom_w_adv[1] -= MOVING_DOMAIN*mom_w_acc*yt;
3212  mom_w_adv[2] -= MOVING_DOMAIN*mom_w_acc*zt;
3213  dmom_w_adv_w[0] -= MOVING_DOMAIN*dmom_w_acc_w*xt;
3214  dmom_w_adv_w[1] -= MOVING_DOMAIN*dmom_w_acc_w*yt;
3215  dmom_w_adv_w[2] -= MOVING_DOMAIN*dmom_w_acc_w*zt;
3216  }
3217  //
3218  //calculate time derivative at quadrature points
3219  //
3220  if (q_dV_last.data()[eN_k] <= -100)
3221  q_dV_last.data()[eN_k] = dV;
3222  q_dV.data()[eN_k] = dV;
3223  ck.bdf(alphaBDF,
3224  q_mom_u_acc_beta_bdf.data()[eN_k]*q_dV_last.data()[eN_k]/dV,
3225  mom_u_acc,
3226  dmom_u_acc_u,
3227  mom_u_acc_t,
3228  dmom_u_acc_u_t);
3229  ck.bdf(alphaBDF,
3230  q_mom_v_acc_beta_bdf.data()[eN_k]*q_dV_last.data()[eN_k]/dV,
3231  mom_v_acc,
3232  dmom_v_acc_v,
3233  mom_v_acc_t,
3234  dmom_v_acc_v_t);
3235  ck.bdf(alphaBDF,
3236  q_mom_w_acc_beta_bdf.data()[eN_k]*q_dV_last.data()[eN_k]/dV,
3237  mom_w_acc,
3238  dmom_w_acc_w,
3239  mom_w_acc_t,
3240  dmom_w_acc_w_t);
3241 
3242  if (NONCONSERVATIVE_FORM > 0.0)
3243  {
3244  mom_u_acc_t *= dmom_u_acc_u;
3245  mom_v_acc_t *= dmom_v_acc_v;
3246  mom_w_acc_t *= dmom_w_acc_w;
3247  }
3248  //
3249  //calculate subgrid error (strong residual and adjoint)
3250  //
3251  //calculate strong residual
3252  pdeResidual_p = ck.Advection_strong(dmass_adv_u,grad_u) +
3253  ck.Advection_strong(dmass_adv_v,grad_v) +
3254  ck.Advection_strong(dmass_adv_w,grad_w) +
3255  DM2*MOVING_DOMAIN*ck.Reaction_strong(alphaBDF*(dV-q_dV_last.data()[eN_k])/dV - div_mesh_velocity) +
3256  ck.Reaction_strong(mass_source);
3257 
3258  if (NONCONSERVATIVE_FORM > 0.0)
3259  {
3260  dmom_adv_sge[0] = 0.0;
3261  dmom_adv_sge[1] = 0.0;
3262  dmom_adv_sge[2] = 0.0;
3263  dmom_ham_grad_sge[0] = inertial_term*dmom_u_acc_u*(q_velocity_sge.data()[eN_k_nSpace+0] - MOVING_DOMAIN*xt);
3264  dmom_ham_grad_sge[1] = inertial_term*dmom_u_acc_u*(q_velocity_sge.data()[eN_k_nSpace+1] - MOVING_DOMAIN*yt);
3265  dmom_ham_grad_sge[2] = inertial_term*dmom_u_acc_u*(q_velocity_sge.data()[eN_k_nSpace+2] - MOVING_DOMAIN*zt);
3266  }
3267  else
3268  {
3269  dmom_adv_sge[0] = inertial_term*dmom_u_acc_u*(q_velocity_sge.data()[eN_k_nSpace+0] - MOVING_DOMAIN*xt);
3270  dmom_adv_sge[1] = inertial_term*dmom_u_acc_u*(q_velocity_sge.data()[eN_k_nSpace+1] - MOVING_DOMAIN*yt);
3271  dmom_adv_sge[2] = inertial_term*dmom_u_acc_u*(q_velocity_sge.data()[eN_k_nSpace+2] - MOVING_DOMAIN*zt);
3272  dmom_ham_grad_sge[0] = 0.0;
3273  dmom_ham_grad_sge[1] = 0.0;
3274  dmom_ham_grad_sge[2] = 0.0;
3275  }
3276  double mv_tau[nSpace]=ZEROVEC;
3277  mv_tau[0] = dmom_adv_sge[0] + dmom_ham_grad_sge[0];
3278  mv_tau[1] = dmom_adv_sge[1] + dmom_ham_grad_sge[1];
3279  mv_tau[2] = dmom_adv_sge[2] + dmom_ham_grad_sge[2];
3280 
3281  pdeResidual_u = ck.Mass_strong(mom_u_acc_t) +
3282  ck.Advection_strong(dmom_adv_sge,grad_u) +
3283  ck.Hamiltonian_strong(dmom_ham_grad_sge,grad_u) +
3284  ck.Hamiltonian_strong(dmom_u_ham_grad_p,grad_p) +
3285  ck.Reaction_strong(mom_u_source) -
3286  ck.Reaction_strong(dmom_u_acc_u*u*div_mesh_velocity);
3287 
3288  pdeResidual_v = ck.Mass_strong(mom_v_acc_t) +
3289  ck.Advection_strong(dmom_adv_sge,grad_v) +
3290  ck.Hamiltonian_strong(dmom_ham_grad_sge,grad_v) +
3291  ck.Hamiltonian_strong(dmom_v_ham_grad_p,grad_p) +
3292  ck.Reaction_strong(mom_v_source) -
3293  ck.Reaction_strong(dmom_v_acc_v*v*div_mesh_velocity);
3294 
3295  pdeResidual_w = ck.Mass_strong(mom_w_acc_t) +
3296  ck.Advection_strong(dmom_adv_sge,grad_w) +
3297  ck.Hamiltonian_strong(dmom_ham_grad_sge,grad_w) +
3298  ck.Hamiltonian_strong(dmom_w_ham_grad_p,grad_p) +
3299  ck.Reaction_strong(mom_w_source) -
3300  ck.Reaction_strong(dmom_w_acc_w*w*div_mesh_velocity);
3301 
3302  //calculate tau and tau*Res
3303  //add contributions from mass and source terms
3304  double tmpR=dmom_u_acc_u_t + dmom_u_source[0];
3305  calculateSubgridError_tau(hFactor,
3306  elementDiameter.data()[eN],
3307  tmpR,//dmom_u_acc_u_t,
3308  dmom_u_acc_u,
3309  mv_tau,//dmom_adv_sge,
3310  mom_uu_diff_ten[1],
3311  dmom_u_ham_grad_p[0],
3312  tau_v0,
3313  tau_p0,
3314  q_cfl.data()[eN_k]);
3315 
3316  calculateSubgridError_tau(Ct_sge,Cd_sge,
3317  G,G_dd_G,tr_G,
3318  tmpR,//dmom_u_acc_u_t,
3319  mv_tau,//dmom_adv_sge,
3320  mom_uu_diff_ten[1],
3321  dmom_u_ham_grad_p[0],
3322  tau_v1,
3323  tau_p1,
3324  q_cfl.data()[eN_k]);
3325 
3326  tau_v = useMetrics*tau_v1+(1.0-useMetrics)*tau_v0;
3327  tau_p = useMetrics*tau_p1+(1.0-useMetrics)*tau_p0;
3328 
3330  tau_v,
3331  pdeResidual_p,
3332  pdeResidual_u,
3333  pdeResidual_v,
3334  pdeResidual_w,
3335  subgridError_p,
3336  subgridError_u,
3337  subgridError_v,
3338  subgridError_w);
3339  // velocity used in adjoint (VMS or RBLES, with or without lagging the grid scale velocity)
3340  dmom_adv_star[0] = inertial_term*dmom_u_acc_u*(q_velocity_sge.data()[eN_k_nSpace+0] - MOVING_DOMAIN*xt + useRBLES*subgridError_u);
3341  dmom_adv_star[1] = inertial_term*dmom_u_acc_u*(q_velocity_sge.data()[eN_k_nSpace+1] - MOVING_DOMAIN*yt + useRBLES*subgridError_v);
3342  dmom_adv_star[2] = inertial_term*dmom_u_acc_u*(q_velocity_sge.data()[eN_k_nSpace+2] - MOVING_DOMAIN*zt + useRBLES*subgridError_w);
3343 
3344  mom_u_adv[0] += inertial_term*dmom_u_acc_u*(useRBLES*subgridError_u*q_velocity_sge.data()[eN_k_nSpace+0]);
3345  mom_u_adv[1] += inertial_term*dmom_u_acc_u*(useRBLES*subgridError_v*q_velocity_sge.data()[eN_k_nSpace+0]);
3346  mom_u_adv[2] += inertial_term*dmom_u_acc_u*(useRBLES*subgridError_w*q_velocity_sge.data()[eN_k_nSpace+0]);
3347 
3348  mom_v_adv[0] += inertial_term*dmom_u_acc_u*(useRBLES*subgridError_u*q_velocity_sge.data()[eN_k_nSpace+1]);
3349  mom_v_adv[1] += inertial_term*dmom_u_acc_u*(useRBLES*subgridError_v*q_velocity_sge.data()[eN_k_nSpace+1]);
3350  mom_v_adv[2] += inertial_term*dmom_u_acc_u*(useRBLES*subgridError_w*q_velocity_sge.data()[eN_k_nSpace+1]);
3351 
3352  mom_w_adv[0] += inertial_term*dmom_u_acc_u*(useRBLES*subgridError_u*q_velocity_sge.data()[eN_k_nSpace+2]);
3353  mom_w_adv[1] += inertial_term*dmom_u_acc_u*(useRBLES*subgridError_v*q_velocity_sge.data()[eN_k_nSpace+2]);
3354  mom_w_adv[2] += inertial_term*dmom_u_acc_u*(useRBLES*subgridError_w*q_velocity_sge.data()[eN_k_nSpace+2]);
3355 
3356  // adjoint times the test functions
3357  for (int i=0;i<nDOF_test_element;i++)
3358  {
3359  register int i_nSpace = i*nSpace;
3360  Lstar_u_p[i]=ck.Advection_adjoint(dmass_adv_u,&p_grad_test_dV[i_nSpace]);
3361  Lstar_v_p[i]=ck.Advection_adjoint(dmass_adv_v,&p_grad_test_dV[i_nSpace]);
3362  Lstar_w_p[i]=ck.Advection_adjoint(dmass_adv_w,&p_grad_test_dV[i_nSpace]);
3363  }
3364  for (int i=0;i<nDOF_v_test_element;i++)
3365  {
3366  register int i_nSpace = i*nSpace;
3367  //use the same advection adjoint for all three since we're approximating the linearized adjoint
3368  Lstar_u_u[i]=ck.Advection_adjoint(dmom_adv_star,&vel_grad_test_dV[i_nSpace]);//cek COMP/INCOMP form have same adjoint
3369  Lstar_v_v[i]=ck.Advection_adjoint(dmom_adv_star,&vel_grad_test_dV[i_nSpace]);//ditto
3370  Lstar_w_w[i]=ck.Advection_adjoint(dmom_adv_star,&vel_grad_test_dV[i_nSpace]);//ditto
3371  Lstar_p_u[i]=ck.Hamiltonian_adjoint(dmom_u_ham_grad_p,&vel_grad_test_dV[i_nSpace]);
3372  Lstar_p_v[i]=ck.Hamiltonian_adjoint(dmom_v_ham_grad_p,&vel_grad_test_dV[i_nSpace]);
3373  Lstar_p_w[i]=ck.Hamiltonian_adjoint(dmom_w_ham_grad_p,&vel_grad_test_dV[i_nSpace]);
3374 
3375  //VRANS account for drag terms, diagonal only here ... decide if need off diagonal terms too
3376  Lstar_u_u[i]+=ck.Reaction_adjoint(dmom_u_source[0],vel_test_dV[i]);
3377  Lstar_v_v[i]+=ck.Reaction_adjoint(dmom_v_source[1],vel_test_dV[i]);
3378  Lstar_w_w[i]+=ck.Reaction_adjoint(dmom_w_source[2],vel_test_dV[i]);
3379  //
3380  }
3381 
3382  norm_Rv = sqrt(pdeResidual_u*pdeResidual_u + pdeResidual_v*pdeResidual_v + pdeResidual_w*pdeResidual_w);
3383  q_numDiff_u.data()[eN_k] = C_dc*norm_Rv*(useMetrics/sqrt(G_dd_G+1.0e-12) +
3384  (1.0-useMetrics)*hFactor*hFactor*elementDiameter.data()[eN]*elementDiameter.data()[eN]);
3385  q_numDiff_v.data()[eN_k] = q_numDiff_u.data()[eN_k];
3386  q_numDiff_w.data()[eN_k] = q_numDiff_u.data()[eN_k];
3387  numDiffMax = std::fmax(q_numDiff_u.data()[eN_k], numDiffMax);
3388  if(nParticles > 0)
3389  {
3390  //cek todo, this needs to be fixed for not exact
3391  double level_set_normal[nSpace];
3392  double sign=0.0;
3393  if (gf_s.useExact)
3394  {
3395  double norm_exact=0.0,norm_cut=0.0;
3396  if (use_ball_as_particle)
3397  {
3398  for (int I=0;I<nSpace;I++)
3399  {
3400  sign += ball_n[I]*gf_s.get_normal()[I];
3401  level_set_normal[I] = gf_s.get_normal()[I];
3402  norm_cut += level_set_normal[I]*level_set_normal[I];
3403  norm_exact += ball_n[I]*ball_n[I];
3404  }
3405  }
3406  else
3407  {
3408  for (int I=0;I<nSpace;I++)
3409  {
3410  sign += particle_signed_distance_normals.data()[eN_k_3d+I]*gf_s.get_normal()[I];
3411  level_set_normal[I] = gf_s.get_normal()[I];
3412  norm_cut += level_set_normal[I]*level_set_normal[I];
3413  norm_exact += particle_signed_distance_normals.data()[eN_k_3d+I]*particle_signed_distance_normals.data()[eN_k_3d+I];
3414  }
3415  }
3416  norm_cut = std::sqrt(norm_cut);
3417  norm_exact = std::sqrt(norm_exact);
3418  assert(std::fabs(1.0-norm_cut) < 1.0e-8);
3419  assert(std::fabs(1.0-norm_exact) < 1.0e-8);
3420  if (sign < 0.0)
3421  for (int I=0;I<nSpace;I++)
3422  level_set_normal[I]*=-1.0;
3423  /* if(icase_s==0)// && (1.0-sign*sign) > 1.0e-3) */
3424  /* { */
3425  /* std::cout<<"phi normal and cut normal divergent "<<eN<<'\t'<<k<<std::endl; */
3426  /* for (int I=0;I<nSpace;I++) */
3427  /* std::cout<<level_set_normal[I]<<'\t'<<particle_signed_distance_normals[eN_k_3d+I]<<std::endl; */
3428  /* } */
3429  }
3430  else
3431  {
3432  if (use_ball_as_particle)
3433  for (int I=0;I<nSpace;I++)
3434  level_set_normal[I] = ball_n[I];
3435  else
3436  for (int I=0;I<nSpace;I++)
3437  level_set_normal[I] = particle_signed_distance_normals.data()[eN_k_3d+I];
3438  }
3439  updateSolidParticleTerms(particle_index,
3440  NONCONSERVATIVE_FORM,
3441  eN < nElements_owned,
3442  particle_nitsche,
3443  dV,
3444  nParticles,
3445  nQuadraturePoints_global,
3446  &particle_signed_distances.data()[eN_k],
3447  level_set_normal,
3448  &particle_velocities.data()[eN_k_3d],
3449  particle_centroids.data(),
3450  use_ball_as_particle,
3451  ball_center.data(),
3452  ball_radius.data(),
3453  ball_velocity.data(),
3454  ball_angular_velocity.data(),
3455  ball_density.data(),
3456  porosity,
3457  particle_penalty_constant/h_phi,//penalty,
3458  particle_alpha,
3459  particle_beta,
3460  eps_rho,
3461  eps_mu,
3462  rho_0,
3463  nu_0,
3464  rho_1,
3465  nu_1,
3466  useVF,
3467  vf.data()[eN_k],
3468  phi.data()[eN_k],
3469  x,
3470  y,
3471  z,
3472  p,
3473  u,
3474  v,
3475  w,
3476  q_velocity_sge.data()[eN_k_nSpace+0],
3477  q_velocity_sge.data()[eN_k_nSpace+1],
3478  q_velocity_sge.data()[eN_k_nSpace+2],
3479  particle_eps,
3480  grad_u,
3481  grad_v,
3482  grad_w,
3483  mass_source_s,
3484  mom_u_source_s,
3485  mom_v_source_s,
3486  mom_w_source_s,
3487  dmom_u_source_s,
3488  dmom_v_source_s,
3489  dmom_w_source_s,
3490  mom_u_adv_s,
3491  mom_v_adv_s,
3492  mom_w_adv_s,
3493  dmom_u_adv_u_s,
3494  dmom_v_adv_v_s,
3495  dmom_w_adv_w_s,
3496  mom_u_ham_s,
3497  dmom_u_ham_grad_u_s,
3498  dmom_u_ham_grad_v_s,
3499  dmom_u_ham_grad_w_s,
3500  dmom_u_ham_u_s,
3501  dmom_u_ham_v_s,
3502  dmom_u_ham_w_s,
3503  mom_v_ham_s,
3504  dmom_v_ham_grad_u_s,
3505  dmom_v_ham_grad_v_s,
3506  dmom_v_ham_grad_w_s,
3507  dmom_v_ham_u_s,
3508  dmom_v_ham_v_s,
3509  dmom_v_ham_w_s,
3510  mom_w_ham_s,
3511  dmom_w_ham_grad_u_s,
3512  dmom_w_ham_grad_v_s,
3513  dmom_w_ham_grad_w_s,
3514  dmom_w_ham_u_s,
3515  dmom_w_ham_v_s,
3516  dmom_w_ham_w_s,
3517  mass_ham_s,
3518  dmass_ham_u_s,
3519  dmass_ham_v_s,
3520  dmass_ham_w_s,
3521  particle_netForces.data(),
3522  particle_netMoments.data(),
3523  particle_surfaceArea.data());
3524  }
3525  //
3526  //save momentum for time history and velocity for subgrid error
3527  //
3528  //cek this needs to go with the particle term updates if moved--or check particle_velocities[...] array
3529  //cek on cut cells this is getting set twice. For now it's identical because of our formulations (neither includes density so it's either velocity or porosity*velocity--same for both phases
3530  //cek but this won't be right when we use a modified basis because we'll need the whole phase velocity from its basis. hmm. special backward euler class that tracks both?
3531  //same situation with subgrid error velocity
3532  //cek since this is for the history, could try using the solid velocity inside the solid instead of just in inactive elements as before
3533  //this avoids using the fluid values inside the solid that necessarily over/undershoot to give the right values inside the fluid domain
3534  //but then the mass quadrature would represent a function that is no longer polynomial on the element so leaving it as element_active
3535  //for now--alternative would be:
3536  //if (phi_solid.data()[eN_k] > 0)
3537  if (element_active)
3538  {
3539  q_mom_u_acc.data()[eN_k] = mom_u_acc;
3540  q_mom_v_acc.data()[eN_k] = mom_v_acc;
3541  q_mom_w_acc.data()[eN_k] = mom_w_acc;
3542  //subgrid error uses grid scale velocity
3543  q_mass_adv.data()[eN_k_nSpace+0] = u;
3544  q_mass_adv.data()[eN_k_nSpace+1] = v;
3545  q_mass_adv.data()[eN_k_nSpace+2] = w;
3546  }
3547  else//use the solid velocity
3548  {
3549  if (use_ball_as_particle)
3550  {
3551  q_mom_u_acc.data()[eN_k] = particle_velocities.data()[eN_k_3d+0];
3552  q_mom_v_acc.data()[eN_k] = particle_velocities.data()[eN_k_3d+1];
3553  q_mom_w_acc.data()[eN_k] = particle_velocities.data()[eN_k_3d+2];
3554  q_mass_adv.data()[eN_k_nSpace+0] = particle_velocities.data()[eN_k_3d+0];
3555  q_mass_adv.data()[eN_k_nSpace+1] = particle_velocities.data()[eN_k_3d+1];
3556  q_mass_adv.data()[eN_k_nSpace+2] = particle_velocities.data()[eN_k_3d+2];
3557  }
3558  else
3559  {
3560  q_mom_u_acc.data()[eN_k] = particle_velocities.data()[particle_index*nQuadraturePoints_global + eN_k_3d+0];
3561  q_mom_v_acc.data()[eN_k] = particle_velocities.data()[particle_index*nQuadraturePoints_global + eN_k_3d+1];
3562  q_mom_w_acc.data()[eN_k] = particle_velocities.data()[particle_index*nQuadraturePoints_global + eN_k_3d+2];
3563  q_mass_adv.data()[eN_k_nSpace+0] = particle_velocities.data()[particle_index*nQuadraturePoints_global + eN_k_3d+0];
3564  q_mass_adv.data()[eN_k_nSpace+1] = particle_velocities.data()[particle_index*nQuadraturePoints_global + eN_k_3d+1];
3565  q_mass_adv.data()[eN_k_nSpace+2] = particle_velocities.data()[particle_index*nQuadraturePoints_global + eN_k_3d+2];
3566  }
3567  }
3568  //
3569  //update element residual
3570  //
3571  double mesh_vel[nSpace];
3572  mesh_vel[0] = xt;
3573  mesh_vel[1] = yt;
3574  mesh_vel[2] = zt;
3575  double H_f=1.0;
3576  if (gf.useExact && icase == 0)
3577  {
3578  if (fluid_phase == 0)
3579  H_f = gf.ImH(0.,0.);
3580  else
3581  H_f = gf.H(0.,0.);
3582  }
3583  else
3584  H_f = 1.0;
3585  if (icase == 0)
3586  {
3587  //std::cout<<"H_f "<<H_f<<" fluid_phase "<<fluid_phase<<" eN "<<eN<<std::endl;
3588  }
3589  else
3590  {
3591  assert(H_f == 1);
3592  }
3593  if ((eN < nElements_owned) && isActiveElement[eN])
3594  {
3595  domain_volume += H_s*dV*H_f;
3596  p_L1 += fabs(p_e)*H_s*dV*H_f;
3597  u_L1 += fabs(u_e)*H_s*dV*H_f;
3598  v_L1 += fabs(v_e)*H_s*dV*H_f;
3599  w_L1 += fabs(w_e)*H_s*dV*H_f;
3600  velocity_L1 += fabs(velocity_e)*H_s*dV*H_f;
3601 
3602  p_L2 += p_e*p_e*H_s*dV*H_f;
3603  u_L2 += u_e*u_e*H_s*dV*H_f;
3604  v_L2 += v_e*v_e*H_s*dV*H_f;
3605  w_L2 += w_e*w_e*H_s*dV*H_f;
3606  velocity_L2 += velocity_e*velocity_e*H_s*dV*H_f;
3607  p_dv += p*H_s*H_f*dV;
3608  pa_dv += q_u_0.data()[eN_k]*H_s*H_f*dV;
3609  total_volume+=H_s*H_f*dV;
3610  total_surface_area+=D_s*H_f*dV;
3611  if (phi_solid.data()[eN_k] >= 0.0)
3612  {
3613  p_LI = fmax(p_LI, fabs(p_e));
3614  u_LI = fmax(u_LI, fabs(u_e));
3615  v_LI = fmax(v_LI, fabs(v_e));
3616  w_LI = fmax(w_LI, fabs(w_e));
3617  velocity_LI = fmax(velocity_LI, fabs(velocity_e));
3618  }
3619  }
3620  for(int i=0;i<nDOF_test_element;i++)
3621  {
3622  register int i_nSpace=i*nSpace;
3623  elementResidual_mesh[i] += H_s*H_f*(ck.Reaction_weak(1.0,p_test_dV[i]) -
3624  ck.Reaction_weak(1.0,p_test_dV[i]*q_dV_last.data()[eN_k]/dV) -
3625  ck.Advection_weak(mesh_vel,&p_grad_test_dV[i_nSpace]));
3626  elementResidual_p[i] += H_s*H_f*(ck.Advection_weak(mass_adv,&p_grad_test_dV[i_nSpace])
3627  + ck.Hamiltonian_weak(mass_ham, p_test_dV[i])
3628  + DM*MOVING_DOMAIN*(ck.Reaction_weak(alphaBDF*1.0,p_test_dV[i]) -
3629  ck.Reaction_weak(alphaBDF*1.0,p_test_dV[i]*q_dV_last.data()[eN_k]/dV) -
3630  ck.Advection_weak(mesh_vel,&p_grad_test_dV[i_nSpace])) +
3631  ck.Reaction_weak(mass_source,p_test_dV[i]));
3632  if (nDOF_test_element == nDOF_v_test_element)
3633  {
3634  elementResidual_p[i] +=
3635  H_s*H_f*(PRESSURE_PROJECTION_STABILIZATION * ck.pressureProjection_weak(mom_uu_diff_ten[1], p, p_element_avg, p_test_ref.data()[k*nDOF_test_element+i], dV) +
3636  (1 - PRESSURE_PROJECTION_STABILIZATION) * ck.SubgridError(subgridError_u,Lstar_u_p[i]) +
3637  (1 - PRESSURE_PROJECTION_STABILIZATION) * ck.SubgridError(subgridError_v,Lstar_v_p[i]) +
3638  (1 - PRESSURE_PROJECTION_STABILIZATION) * ck.SubgridError(subgridError_w,Lstar_w_p[i]));
3639  }
3640  if (PRESSURE_PROJECTION_STABILIZATION==1. && mom_uu_diff_ten[1]==0.)
3641  {
3642  printf("Warning the Bochev-Dohrnmann-Gunzburger stabilization cannot be applied to inviscid fluids.");
3643  }
3644  if (nParticles > 0)//solid boundary terms
3645  {
3646  if (gf_s.D(0.,0.) == 0.0)
3647  assert(mass_source_s == 0.0);
3648  elementResidual_p[i] += H_f*(ck.Reaction_weak(mass_source_s,p_test_dV[i]));
3649  }
3650  }
3651  for(int i=0;i<nDOF_v_test_element;i++)
3652  {
3653  register int i_nSpace=i*nSpace;
3654  elementResidual_u[i] += H_s*H_f*(ck.Mass_weak(mom_u_acc_t,vel_test_dV[i]) +
3655  ck.Advection_weak(mom_u_adv,&vel_grad_test_dV[i_nSpace]) +
3656  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]) +
3657  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]) +
3658  ck.Diffusion_weak(sdInfo_u_w_rowptr.data(),sdInfo_u_w_colind.data(),mom_uw_diff_ten,grad_w,&vel_grad_test_dV[i_nSpace]) +
3659  ck.Reaction_weak(mom_u_source+NONCONSERVATIVE_FORM*dmom_u_acc_u*u*div_mesh_velocity,vel_test_dV[i]) +
3660  ck.Hamiltonian_weak(mom_u_ham,vel_test_dV[i]) +
3661  MOMENTUM_SGE*VELOCITY_SGE*ck.SubgridError(subgridError_u,Lstar_u_u[i]) +
3662  ck.NumericalDiffusion(q_numDiff_u_last.data()[eN_k],grad_u,&vel_grad_test_dV[i_nSpace]));
3663  elementResidual_v[i] += H_s*H_f*(ck.Mass_weak(mom_v_acc_t,vel_test_dV[i]) +
3664  ck.Advection_weak(mom_v_adv,&vel_grad_test_dV[i_nSpace]) +
3665  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]) +
3666  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]) +
3667  ck.Diffusion_weak(sdInfo_v_w_rowptr.data(),sdInfo_v_w_colind.data(),mom_vw_diff_ten,grad_w,&vel_grad_test_dV[i_nSpace]) +
3668  ck.Reaction_weak(mom_v_source+NONCONSERVATIVE_FORM*dmom_v_acc_v*v*div_mesh_velocity,vel_test_dV[i]) +
3669  ck.Hamiltonian_weak(mom_v_ham,vel_test_dV[i]) +
3670  MOMENTUM_SGE*VELOCITY_SGE*ck.SubgridError(subgridError_v,Lstar_v_v[i]) +
3671  ck.NumericalDiffusion(q_numDiff_v_last.data()[eN_k],grad_v,&vel_grad_test_dV[i_nSpace]));
3672  elementResidual_w[i] += H_s*H_f*(ck.Mass_weak(mom_w_acc_t,vel_test_dV[i]) +
3673  ck.Advection_weak(mom_w_adv,&vel_grad_test_dV[i_nSpace]) +
3674  ck.Diffusion_weak(sdInfo_w_u_rowptr.data(),sdInfo_w_u_colind.data(),mom_wu_diff_ten,grad_u,&vel_grad_test_dV[i_nSpace]) +
3675  ck.Diffusion_weak(sdInfo_w_v_rowptr.data(),sdInfo_w_v_colind.data(),mom_wv_diff_ten,grad_v,&vel_grad_test_dV[i_nSpace]) +
3676  ck.Diffusion_weak(sdInfo_w_w_rowptr.data(),sdInfo_w_w_colind.data(),mom_ww_diff_ten,grad_w,&vel_grad_test_dV[i_nSpace]) +
3677  ck.Reaction_weak(mom_w_source+NONCONSERVATIVE_FORM*dmom_w_acc_w*w*div_mesh_velocity,vel_test_dV[i]) +
3678  ck.Hamiltonian_weak(mom_w_ham,vel_test_dV[i]) +
3679  MOMENTUM_SGE*VELOCITY_SGE*ck.SubgridError(subgridError_w,Lstar_w_w[i]) +
3680  ck.NumericalDiffusion(q_numDiff_w_last.data()[eN_k],grad_w,&vel_grad_test_dV[i_nSpace]));
3681  elementResidual_u[i] += H_s*H_f*MOMENTUM_SGE*PRESSURE_SGE*ck.SubgridError(subgridError_p,Lstar_p_u[i]);
3682  elementResidual_v[i] += H_s*H_f*MOMENTUM_SGE*PRESSURE_SGE*ck.SubgridError(subgridError_p,Lstar_p_v[i]);
3683  elementResidual_w[i] += H_s*H_f*MOMENTUM_SGE*PRESSURE_SGE*ck.SubgridError(subgridError_p,Lstar_p_w[i]);
3684  if (nParticles > 0)//solid boundary terms
3685  {
3686  elementResidual_u[i] += H_f*(ck.Advection_weak(mom_u_adv_s,&vel_grad_test_dV[i_nSpace]) +
3687  ck.Reaction_weak(mom_u_source_s,vel_test_dV[i]) +
3688  ck.Hamiltonian_weak(mom_u_ham_s,vel_test_dV[i]));
3689  elementResidual_v[i] += H_f*(ck.Advection_weak(mom_v_adv_s,&vel_grad_test_dV[i_nSpace]) +
3690  ck.Reaction_weak(mom_v_source_s,vel_test_dV[i]) +
3691  ck.Hamiltonian_weak(mom_v_ham_s,vel_test_dV[i]));
3692  elementResidual_w[i] += H_f*(ck.Advection_weak(mom_w_adv_s,&vel_grad_test_dV[i_nSpace]) +
3693  ck.Reaction_weak(mom_w_source_s,vel_test_dV[i]) +
3694  ck.Hamiltonian_weak(mom_w_ham_s,vel_test_dV[i]));
3695  }
3696  }//i
3697  //estimate the numerical viscosity combining shock capturing and VMS/SUPG
3698  numerical_viscosity.data()[eN_k] = q_numDiff_u_last.data()[eN_k] + MOMENTUM_SGE*VELOCITY_SGE*tau_v*(dmom_adv_star[0]*dmom_adv_star[0]+
3699  dmom_adv_star[1]*dmom_adv_star[1]+
3700  dmom_adv_star[2]*dmom_adv_star[2]);
3701  if (!isActiveElement[eN])
3702  {
3703  assert(std::fabs(gf_s.H(particle_eps,phi_solid.data()[eN_k])) == 0.0);
3704  assert(std::fabs(gf_s.D(particle_eps,phi_solid.data()[eN_k])) == 0.0);
3705  }
3706  }//k
3707  }//fluid_phase
3708 #ifdef MAXNUMDIFF
3709  for(int k=0;k<nQuadraturePoints_element;k++)
3710  {
3711  //compute indices and declare local storage
3712  register int eN_k = eN*nQuadraturePoints_element+k;
3713  q_numDiff_u.data()[eN_k] = numDiffMax;
3714  q_numDiff_v.data()[eN_k] = numDiffMax;
3715  q_numDiff_w.data()[eN_k] = numDiffMax;
3716  }
3717 #endif
3718  //
3719  //load element into global residual and save element residual
3720  //
3721  for(int i=0;i<nDOF_test_element;i++)
3722  {
3723  register int eN_i=eN*nDOF_test_element+i;
3724  elementResidual_p_save.data()[eN_i] += elementResidual_p[i];
3725  mesh_volume_conservation_element_weak += elementResidual_mesh[i];
3726  if (!isActiveElement[eN])
3727  {
3728  assert(elementResidual_p[i]==0.0);
3729  }
3730  globalResidual.data()[offset_p+stride_p*rp_l2g.data()[eN_i]]+=elementResidual_p[i];
3731  if (element_active)
3732  {
3733  isActiveR.data()[offset_p+stride_p*rp_l2g.data()[eN_i]] = 1.0;
3734  isActiveDOF_p.data()[p_l2g.data()[eN_i]] = 1.0;
3735  }
3736  }
3737  for(int i=0;i<nDOF_v_test_element;i++)
3738  {
3739  register int eN_i=eN*nDOF_v_test_element+i;
3740  if (!isActiveElement[eN])
3741  {
3742  assert(elementResidual_u[i]==0.0);
3743  assert(elementResidual_v[i]==0.0);
3744  assert(elementResidual_w[i]==0.0);
3745  }
3746  globalResidual.data()[offset_u+stride_u*rvel_l2g.data()[eN_i]]+=elementResidual_u[i];
3747  globalResidual.data()[offset_v+stride_v*rvel_l2g.data()[eN_i]]+=elementResidual_v[i];
3748  globalResidual.data()[offset_w+stride_w*rvel_l2g.data()[eN_i]]+=elementResidual_w[i];
3749  if (element_active)
3750  {
3751  isActiveR.data()[offset_u+stride_u*rvel_l2g.data()[eN_i]] = 1.0;
3752  isActiveR.data()[offset_v+stride_v*rvel_l2g.data()[eN_i]] = 1.0;
3753  isActiveR.data()[offset_w+stride_w*rvel_l2g.data()[eN_i]] = 1.0;
3754  isActiveDOF_vel.data()[vel_l2g.data()[eN_i]] = 1.0;
3755  }
3756  double x = mesh_dof.data()[3*mesh_l2g.data()[eN_i]+0],
3757  y = mesh_dof.data()[3*mesh_l2g.data()[eN_i]+1],
3758  z = mesh_dof.data()[3*mesh_l2g.data()[eN_i]+2];//cek hack: need lagrange nodes for higher order
3759 
3760  get_velocity_to_ith_ball(nParticles,ball_center.data(),ball_radius.data(),
3761  ball_velocity.data(),ball_angular_velocity.data(),
3762  particle_index,x,y,z,
3763  ball_u.data()[vel_l2g.data()[eN_i]], ball_v.data()[vel_l2g.data()[eN_i]], ball_w.data()[vel_l2g.data()[eN_i]]);
3764  }//i
3765  mesh_volume_conservation += mesh_volume_conservation_element;
3766  mesh_volume_conservation_weak += mesh_volume_conservation_element_weak;
3767  mesh_volume_conservation_err_max=fmax(mesh_volume_conservation_err_max,fabs(mesh_volume_conservation_element));
3768  mesh_volume_conservation_err_max_weak=fmax(mesh_volume_conservation_err_max_weak,fabs(mesh_volume_conservation_element_weak));
3769  }//elements
3770  std::set<int>::iterator it=cutfem_boundaries.begin();
3771  while(it!=cutfem_boundaries.end())
3772  {
3773  if(isActiveElement[elementBoundaryElementsArray[(*it)*2+0]] && isActiveElement[elementBoundaryElementsArray[(*it)*2+1]])
3774  {
3775  std::map<int,double> DWp_Dn_jump, DW_Dn_jump;
3776  register double gamma_cutfem=ghost_penalty_constant,gamma_cutfem_p=ghost_penalty_constant,h_cutfem=elementBoundaryDiameter.data()[*it];
3777  int eN_nDOF_v_trial_element = elementBoundaryElementsArray.data()[(*it)*2+0]*nDOF_v_trial_element;
3778  //See Massing Schott Wall 2018
3779  //cek todo modify for two-fluids: rho_0 != rho_1
3780  double norm_v=0.0;
3781  for (int i_offset=1;i_offset<nDOF_v_trial_element;i_offset++)//MSW18 is just on face, so trying to just use face dof
3782  {
3783  int i = (cutfem_local_boundaries[*it] + i_offset)%nDOF_v_trial_element;
3784  double u=u_old_dof.data()[vel_l2g.data()[eN_nDOF_v_trial_element+i]],
3785  v=v_old_dof.data()[vel_l2g.data()[eN_nDOF_v_trial_element+i]],
3786  w=w_old_dof.data()[vel_l2g.data()[eN_nDOF_v_trial_element+i]];
3787  norm_v=fmax(norm_v,sqrt(u*u+v*v+w*w));
3788  }
3789  double gamma_v_dim = rho_0*(nu_0 + norm_v*h_cutfem + alphaBDF*h_cutfem*h_cutfem);
3790  gamma_cutfem_p *= h_cutfem*h_cutfem/gamma_v_dim;
3791  if (NONCONSERVATIVE_FORM)
3792  gamma_cutfem*=gamma_v_dim;
3793  else
3794  gamma_cutfem*=(gamma_v_dim/rho_0);
3795  for (int kb=0;kb<nQuadraturePoints_elementBoundary;kb++)
3796  {
3797  register double Dp_Dn_jump=0.0, Du_Dn_jump=0.0, Dv_Dn_jump=0.0, Dw_Dn_jump=0.0, dS;
3798  for (int eN_side=0;eN_side < 2; eN_side++)
3799  {
3800  register int ebN = *it,
3801  eN = elementBoundaryElementsArray.data()[ebN*2+eN_side];
3802  for (int i=0;i<nDOF_test_element;i++)
3803  {
3804  DWp_Dn_jump[rp_l2g.data()[eN*nDOF_test_element+i]] = 0.0;
3805  }
3806  for (int i=0;i<nDOF_v_test_element;i++)
3807  {
3808  DW_Dn_jump[rvel_l2g.data()[eN*nDOF_v_test_element+i]] = 0.0;
3809  }
3810  }
3811  for (int eN_side=0;eN_side < 2; eN_side++)
3812  {
3813  register int ebN = *it,
3814  eN = elementBoundaryElementsArray[ebN*2+eN_side],
3815  ebN_local = elementBoundaryLocalElementBoundariesArray[ebN*2+eN_side],
3816  eN_nDOF_trial_element = eN*nDOF_trial_element,
3817  eN_nDOF_v_trial_element = eN*nDOF_v_trial_element,
3818  ebN_local_kb = ebN_local*nQuadraturePoints_elementBoundary+kb,
3819  ebN_local_kb_nSpace = ebN_local_kb*nSpace;
3820  register double p_int=0.0,
3821  u_int=0.0,
3822  v_int=0.0,
3823  w_int=0.0,
3824  grad_p_int[nSpace]=ZEROVEC,
3825  grad_u_int[nSpace]=ZEROVEC,
3826  grad_v_int[nSpace]=ZEROVEC,
3827  grad_w_int[nSpace]=ZEROVEC,
3828  jac_int[nSpace*nSpace],
3829  jacDet_int,
3830  jacInv_int[nSpace*nSpace],
3831  boundaryJac[nSpace*(nSpace-1)],
3832  metricTensor[(nSpace-1)*(nSpace-1)],
3833  metricTensorDetSqrt,
3834  p_test_dS[nDOF_test_element],vel_test_dS[nDOF_v_test_element],
3835  p_grad_trial_trace[nDOF_trial_element*nSpace],vel_grad_trial_trace[nDOF_v_trial_element*nSpace],
3836  p_grad_test_dS[nDOF_trial_element*nSpace],vel_grad_test_dS[nDOF_v_trial_element*nSpace],
3837  normal[nSpace],x_int,y_int,z_int,xt_int,yt_int,zt_int,integralScaling,
3838  G[nSpace*nSpace],G_dd_G,tr_G,h_phi,h_penalty,penalty,
3839  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;
3840  //compute information about mapping from reference element to physical element
3841  ck.calculateMapping_elementBoundary(eN,
3842  ebN_local,
3843  kb,
3844  ebN_local_kb,
3845  mesh_dof.data(),
3846  mesh_l2g.data(),
3847  mesh_trial_trace_ref.data(),
3848  mesh_grad_trial_trace_ref.data(),
3849  boundaryJac_ref.data(),
3850  jac_int,
3851  jacDet_int,
3852  jacInv_int,
3853  boundaryJac,
3854  metricTensor,
3855  metricTensorDetSqrt,
3856  normal_ref.data(),
3857  normal,
3858  x_int,y_int,z_int);
3859  //todo: check that physical coordinates match
3860  ck.calculateMappingVelocity_elementBoundary(eN,
3861  ebN_local,
3862  kb,
3863  ebN_local_kb,
3864  mesh_velocity_dof.data(),
3865  mesh_l2g.data(),
3866  mesh_trial_trace_ref.data(),
3867  xt_int,yt_int,zt_int,
3868  normal,
3869  boundaryJac,
3870  metricTensor,
3871  integralScaling);
3872  dS = metricTensorDetSqrt*dS_ref.data()[kb];
3873  //compute shape and solution information
3874  //shape
3875  ck.gradTrialFromRef(&p_grad_trial_trace_ref.data()[ebN_local_kb_nSpace*nDOF_trial_element],jacInv_int,p_grad_trial_trace);
3876  ck_v.gradTrialFromRef(&vel_grad_trial_trace_ref.data()[ebN_local_kb_nSpace*nDOF_v_trial_element],jacInv_int,vel_grad_trial_trace);
3877  //solution and gradients
3878  ck.valFromDOF(p_dof.data(),&p_l2g.data()[eN_nDOF_trial_element],&p_trial_trace_ref.data()[ebN_local_kb*nDOF_test_element],p_int);
3879  ck_v.valFromDOF(u_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],&vel_trial_trace_ref.data()[ebN_local_kb*nDOF_v_test_element],u_int);
3880  ck_v.valFromDOF(v_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],&vel_trial_trace_ref.data()[ebN_local_kb*nDOF_v_test_element],v_int);
3881  ck_v.valFromDOF(w_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],&vel_trial_trace_ref.data()[ebN_local_kb*nDOF_v_test_element],w_int);
3882  ck.gradFromDOF(p_dof.data(),&p_l2g.data()[eN_nDOF_trial_element],p_grad_trial_trace,grad_p_int);
3883  ck_v.gradFromDOF(u_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],vel_grad_trial_trace,grad_u_int);
3884  ck_v.gradFromDOF(v_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],vel_grad_trial_trace,grad_v_int);
3885  ck_v.gradFromDOF(w_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],vel_grad_trial_trace,grad_w_int);
3886  for (int I=0;I<nSpace;I++)
3887  {
3888  Dp_Dn_jump += grad_p_int[I]*normal[I];
3889  Du_Dn_jump += grad_u_int[I]*normal[I];
3890  Dv_Dn_jump += grad_v_int[I]*normal[I];
3891  Dw_Dn_jump += grad_w_int[I]*normal[I];
3892  }
3893  for (int i=0;i<nDOF_test_element;i++)
3894  {
3895  for (int I=0;I<nSpace;I++)
3896  DWp_Dn_jump[rp_l2g[eN_nDOF_trial_element+i]] += p_grad_trial_trace[i*nSpace+I]*normal[I];
3897  }
3898  for (int i=0;i<nDOF_v_test_element;i++)
3899  {
3900  for (int I=0;I<nSpace;I++)
3901  DW_Dn_jump[rvel_l2g[eN_nDOF_v_trial_element+i]] += vel_grad_trial_trace[i*nSpace+I]*normal[I];
3902  }
3903  }//eN_side
3904  for (std::map<int,double>::iterator W_it=DWp_Dn_jump.begin(); W_it!=DWp_Dn_jump.end(); ++W_it)
3905  {
3906  int i_global = W_it->first;
3907  double DWp_Dn_jump_i = W_it->second;
3908  globalResidual.data()[offset_p+stride_p*i_global]+=gamma_cutfem_p*h_cutfem*Dp_Dn_jump*DWp_Dn_jump_i*dS;
3909  }
3910  for (std::map<int,double>::iterator W_it=DW_Dn_jump.begin(); W_it!=DW_Dn_jump.end(); ++W_it)
3911  {
3912  int i_global = W_it->first;
3913  double DW_Dn_jump_i = W_it->second;
3914  globalResidual.data()[offset_u+stride_u*i_global]+=gamma_cutfem*h_cutfem*Du_Dn_jump*DW_Dn_jump_i*dS;
3915  globalResidual.data()[offset_v+stride_v*i_global]+=gamma_cutfem*h_cutfem*Dv_Dn_jump*DW_Dn_jump_i*dS;
3916  globalResidual.data()[offset_w+stride_w*i_global]+=gamma_cutfem*h_cutfem*Dw_Dn_jump*DW_Dn_jump_i*dS;
3917  }//i
3918  }//kb
3919  it++;
3920  }
3921  else
3922  {
3923  it = cutfem_boundaries.erase(it);
3924  }
3925  }//cutfem element boundaries
3926  //
3927  //loop over exterior element boundaries to calculate surface integrals and load into element and global residuals
3928  //
3929  //ebNE is the Exterior element boundary INdex
3930  //ebN is the element boundary INdex
3931  //eN is the element index
3932  for (int ebNE = 0; ebNE < nExteriorElementBoundaries_global; ebNE++)
3933  {
3934  register int ebN = exteriorElementBoundariesArray.data()[ebNE],
3935  eN = elementBoundaryElementsArray.data()[ebN*2+0],
3936  ebN_local = elementBoundaryLocalElementBoundariesArray.data()[ebN*2+0],
3937  eN_nDOF_trial_element = eN*nDOF_trial_element,
3938  eN_nDOF_v_trial_element = eN*nDOF_v_trial_element;
3939  if (boundaryFlags[ebN] < 1)
3940  continue;
3941  register double elementResidual_mesh[nDOF_test_element],
3942  elementResidual_p[nDOF_test_element],
3943  elementResidual_u[nDOF_v_test_element],
3944  elementResidual_v[nDOF_v_test_element],
3945  elementResidual_w[nDOF_v_test_element],
3946  eps_rho,eps_mu;
3947  for (int i=0;i<nDOF_test_element;i++)
3948  {
3949  elementResidual_mesh[i]=0.0;
3950  elementResidual_p[i]=0.0;
3951  }
3952  for (int i=0;i<nDOF_v_test_element;i++)
3953  {
3954  elementResidual_u[i]=0.0;
3955  elementResidual_v[i]=0.0;
3956  elementResidual_w[i]=0.0;
3957  }
3958  double element_phi[nDOF_mesh_trial_element], element_phi_s[nDOF_mesh_trial_element];
3959  for (int j=0;j<nDOF_mesh_trial_element;j++)
3960  {
3961  register int eN_j = eN*nDOF_mesh_trial_element+j;
3962  element_phi[j] = phi_nodes.data()[p_l2g.data()[eN_j]];
3963  element_phi_s[j] = phi_solid_nodes[p_l2g.data()[eN_j]];
3964  }
3965  double element_nodes[nDOF_mesh_trial_element*3];
3966  for (int i=0;i<nDOF_mesh_trial_element;i++)
3967  {
3968  register int eN_i=eN*nDOF_mesh_trial_element+i;
3969  for(int I=0;I<3;I++)
3970  element_nodes[i*3 + I] = mesh_dof[mesh_l2g.data()[eN_i]*3 + I];
3971  }//i
3972  double mesh_dof_ref[nDOF_mesh_trial_element*3]={0.,0.,0.,1.,0.,0.,0.,1.,0.,0.,0.,1.};
3973  double xb_ref_calc[nQuadraturePoints_elementBoundary*3];
3974  for (int kb=0;kb<nQuadraturePoints_elementBoundary;kb++)
3975  {
3976  double x=0.0,y=0.0,z=0.0;
3977  for (int j=0;j<nDOF_mesh_trial_element;j++)
3978  {
3979  int ebN_local_kb = ebN_local*nQuadraturePoints_elementBoundary+kb;
3980  int ebN_local_kb_j = ebN_local_kb*nDOF_mesh_trial_element+j;
3981  x += mesh_dof_ref[j*3+0]*mesh_trial_trace_ref.data()[ebN_local_kb_j];
3982  y += mesh_dof_ref[j*3+1]*mesh_trial_trace_ref.data()[ebN_local_kb_j];
3983  z += mesh_dof_ref[j*3+2]*mesh_trial_trace_ref.data()[ebN_local_kb_j];
3984  }
3985  xb_ref_calc[3*kb+0] = x;
3986  xb_ref_calc[3*kb+1] = y;
3987  xb_ref_calc[3*kb+2] = z;
3988  }
3989  int icase_s = gf_s.calculate(element_phi_s, element_nodes, xb_ref_calc, true);
3990 #ifdef IFEM
3991  int icase = gf.calculate(element_phi, element_nodes, xb_ref.data(), -rho_1*g.data()[1], -rho_0*g.data()[1],true,true);
3992 #else
3993  int icase = gf.calculate(element_phi, element_nodes, xb_ref.data(), 1.0,1.0,true,false);
3994 #endif
3995  //cek todo needs modification for twophase flow ibm
3996  for (int kb=0;kb<nQuadraturePoints_elementBoundary;kb++)
3997  {
3998  register int ebNE_kb = ebNE*nQuadraturePoints_elementBoundary+kb,
3999  ebNE_kb_nSpace = ebNE_kb*nSpace,
4000  ebN_local_kb = ebN_local*nQuadraturePoints_elementBoundary+kb,
4001  ebN_local_kb_nSpace = ebN_local_kb*nSpace;
4002  register double phi_s_ext=0.0,
4003  p_ext=0.0,
4004  u_ext=0.0,
4005  v_ext=0.0,
4006  w_ext=0.0,
4007  grad_p_ext[nSpace]=ZEROVEC,
4008  grad_u_ext[nSpace]=ZEROVEC,
4009  grad_v_ext[nSpace]=ZEROVEC,
4010  grad_w_ext[nSpace]=ZEROVEC,
4011  p_old=0.0,u_old=0.0,v_old=0.0,w_old=0.0,
4012  grad_p_old[nSpace]=ZEROVEC,grad_u_old[nSpace]=ZEROVEC,grad_v_old[nSpace]=ZEROVEC,grad_w_old[nSpace]=ZEROVEC,
4013  mom_u_acc_ext=0.0,
4014  dmom_u_acc_u_ext=0.0,
4015  mom_v_acc_ext=0.0,
4016  dmom_v_acc_v_ext=0.0,
4017  mom_w_acc_ext=0.0,
4018  dmom_w_acc_w_ext=0.0,
4019  mass_adv_ext[nSpace]=ZEROVEC,
4020  dmass_adv_u_ext[nSpace]=ZEROVEC,
4021  dmass_adv_v_ext[nSpace]=ZEROVEC,
4022  dmass_adv_w_ext[nSpace]=ZEROVEC,
4023  mom_u_adv_ext[nSpace]=ZEROVEC,
4024  dmom_u_adv_u_ext[nSpace]=ZEROVEC,
4025  dmom_u_adv_v_ext[nSpace]=ZEROVEC,
4026  dmom_u_adv_w_ext[nSpace]=ZEROVEC,
4027  mom_v_adv_ext[nSpace]=ZEROVEC,
4028  dmom_v_adv_u_ext[nSpace]=ZEROVEC,
4029  dmom_v_adv_v_ext[nSpace]=ZEROVEC,
4030  dmom_v_adv_w_ext[nSpace]=ZEROVEC,
4031  mom_w_adv_ext[nSpace]=ZEROVEC,
4032  dmom_w_adv_u_ext[nSpace]=ZEROVEC,
4033  dmom_w_adv_v_ext[nSpace]=ZEROVEC,
4034  dmom_w_adv_w_ext[nSpace]=ZEROVEC,
4035  mom_uu_diff_ten_ext[nSpace]=ZEROVEC,
4036  mom_vv_diff_ten_ext[nSpace]=ZEROVEC,
4037  mom_ww_diff_ten_ext[nSpace]=ZEROVEC,
4038  mom_uv_diff_ten_ext[1],
4039  mom_uw_diff_ten_ext[1],
4040  mom_vu_diff_ten_ext[1],
4041  mom_vw_diff_ten_ext[1],
4042  mom_wu_diff_ten_ext[1],
4043  mom_wv_diff_ten_ext[1],
4044  mom_u_source_ext=0.0,
4045  mom_v_source_ext=0.0,
4046  mom_w_source_ext=0.0,
4047  mom_u_ham_ext=0.0,
4048  dmom_u_ham_grad_p_ext[nSpace]=ZEROVEC,
4049  dmom_u_ham_grad_u_ext[nSpace]=ZEROVEC,
4050  dmom_u_ham_u_ext=0.0,
4051  dmom_u_ham_v_ext=0.0,
4052  dmom_u_ham_w_ext=0.0,
4053  mom_v_ham_ext=0.0,
4054  dmom_v_ham_grad_p_ext[nSpace]=ZEROVEC,
4055  dmom_v_ham_grad_v_ext[nSpace]=ZEROVEC,
4056  dmom_v_ham_u_ext=0.0,
4057  dmom_v_ham_v_ext=0.0,
4058  dmom_v_ham_w_ext=0.0,
4059  mom_w_ham_ext=0.0,
4060  dmom_w_ham_grad_p_ext[nSpace]=ZEROVEC,
4061  dmom_w_ham_grad_w_ext[nSpace]=ZEROVEC,
4062  dmom_w_ham_u_ext=0.0,
4063  dmom_w_ham_v_ext=0.0,
4064  dmom_w_ham_w_ext=0.0,
4065  dmom_u_adv_p_ext[nSpace]=ZEROVEC,
4066  dmom_v_adv_p_ext[nSpace]=ZEROVEC,
4067  dmom_w_adv_p_ext[nSpace]=ZEROVEC,
4068  flux_mass_ext=0.0,
4069  flux_mom_u_adv_ext=0.0,
4070  flux_mom_v_adv_ext=0.0,
4071  flux_mom_w_adv_ext=0.0,
4072  flux_mom_uu_diff_ext=0.0,
4073  flux_mom_uv_diff_ext=0.0,
4074  flux_mom_uw_diff_ext=0.0,
4075  flux_mom_vu_diff_ext=0.0,
4076  flux_mom_vv_diff_ext=0.0,
4077  flux_mom_vw_diff_ext=0.0,
4078  flux_mom_wu_diff_ext=0.0,
4079  flux_mom_wv_diff_ext=0.0,
4080  flux_mom_ww_diff_ext=0.0,
4081  bc_p_ext=0.0,
4082  bc_u_ext=0.0,
4083  bc_v_ext=0.0,
4084  bc_w_ext=0.0,
4085  bc_mom_u_acc_ext=0.0,
4086  bc_dmom_u_acc_u_ext=0.0,
4087  bc_mom_v_acc_ext=0.0,
4088  bc_dmom_v_acc_v_ext=0.0,
4089  bc_mom_w_acc_ext=0.0,
4090  bc_dmom_w_acc_w_ext=0.0,
4091  bc_mass_adv_ext[nSpace]=ZEROVEC,
4092  bc_dmass_adv_u_ext[nSpace]=ZEROVEC,
4093  bc_dmass_adv_v_ext[nSpace]=ZEROVEC,
4094  bc_dmass_adv_w_ext[nSpace]=ZEROVEC,
4095  bc_mom_u_adv_ext[nSpace]=ZEROVEC,
4096  bc_dmom_u_adv_u_ext[nSpace]=ZEROVEC,
4097  bc_dmom_u_adv_v_ext[nSpace]=ZEROVEC,
4098  bc_dmom_u_adv_w_ext[nSpace]=ZEROVEC,
4099  bc_mom_v_adv_ext[nSpace]=ZEROVEC,
4100  bc_dmom_v_adv_u_ext[nSpace]=ZEROVEC,
4101  bc_dmom_v_adv_v_ext[nSpace]=ZEROVEC,
4102  bc_dmom_v_adv_w_ext[nSpace]=ZEROVEC,
4103  bc_mom_w_adv_ext[nSpace]=ZEROVEC,
4104  bc_dmom_w_adv_u_ext[nSpace]=ZEROVEC,
4105  bc_dmom_w_adv_v_ext[nSpace]=ZEROVEC,
4106  bc_dmom_w_adv_w_ext[nSpace]=ZEROVEC,
4107  bc_mom_uu_diff_ten_ext[nSpace]=ZEROVEC,
4108  bc_mom_vv_diff_ten_ext[nSpace]=ZEROVEC,
4109  bc_mom_ww_diff_ten_ext[nSpace]=ZEROVEC,
4110  bc_mom_uv_diff_ten_ext[1],
4111  bc_mom_uw_diff_ten_ext[1],
4112  bc_mom_vu_diff_ten_ext[1],
4113  bc_mom_vw_diff_ten_ext[1],
4114  bc_mom_wu_diff_ten_ext[1],
4115  bc_mom_wv_diff_ten_ext[1],
4116  bc_mom_u_source_ext=0.0,
4117  bc_mom_v_source_ext=0.0,
4118  bc_mom_w_source_ext=0.0,
4119  bc_mom_u_ham_ext=0.0,
4120  bc_dmom_u_ham_grad_p_ext[nSpace]=ZEROVEC,
4121  bc_dmom_u_ham_grad_u_ext[nSpace]=ZEROVEC,
4122  bc_dmom_u_ham_u_ext=0.0,
4123  bc_dmom_u_ham_v_ext=0.0,
4124  bc_dmom_u_ham_w_ext=0.0,
4125  bc_mom_v_ham_ext=0.0,
4126  bc_dmom_v_ham_grad_p_ext[nSpace]=ZEROVEC,
4127  bc_dmom_v_ham_grad_v_ext[nSpace]=ZEROVEC,
4128  bc_dmom_v_ham_u_ext=0.0,
4129  bc_dmom_v_ham_v_ext=0.0,
4130  bc_dmom_v_ham_w_ext=0.0,
4131  bc_mom_w_ham_ext=0.0,
4132  bc_dmom_w_ham_grad_p_ext[nSpace]=ZEROVEC,
4133  bc_dmom_w_ham_grad_w_ext[nSpace]=ZEROVEC,
4134  bc_dmom_w_ham_u_ext=0.0,
4135  bc_dmom_w_ham_v_ext=0.0,
4136  bc_dmom_w_ham_w_ext=0.0,
4137  jac_ext[nSpace*nSpace],
4138  jacDet_ext,
4139  jacInv_ext[nSpace*nSpace],
4140  boundaryJac[nSpace*(nSpace-1)],
4141  metricTensor[(nSpace-1)*(nSpace-1)],
4142  metricTensorDetSqrt,
4143  dS,p_test_dS[nDOF_test_element],vel_test_dS[nDOF_v_test_element],
4144  p_grad_trial_trace[nDOF_trial_element*nSpace],vel_grad_trial_trace[nDOF_v_trial_element*nSpace],
4145  vel_grad_test_dS[nDOF_v_trial_element*nSpace],
4146  normal[nSpace],x_ext,y_ext,z_ext,xt_ext,yt_ext,zt_ext,integralScaling,
4147  //VRANS
4148  porosity_ext,
4149  //
4150  G[nSpace*nSpace],G_dd_G,tr_G,h_phi,h_penalty,penalty,
4151  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;
4152  //compute information about mapping from reference element to physical element
4153  gf_s.set_boundary_quad(kb);
4154  gf.set_boundary_quad(kb);
4155  ck.calculateMapping_elementBoundary(eN,
4156  ebN_local,
4157  kb,
4158  ebN_local_kb,
4159  mesh_dof.data(),
4160  mesh_l2g.data(),
4161  mesh_trial_trace_ref.data(),
4162  mesh_grad_trial_trace_ref.data(),
4163  boundaryJac_ref.data(),
4164  jac_ext,
4165  jacDet_ext,
4166  jacInv_ext,
4167  boundaryJac,
4168  metricTensor,
4169  metricTensorDetSqrt,
4170  normal_ref.data(),
4171  normal,
4172  x_ext,y_ext,z_ext);
4173  ck.calculateMappingVelocity_elementBoundary(eN,
4174  ebN_local,
4175  kb,
4176  ebN_local_kb,
4177  mesh_velocity_dof.data(),
4178  mesh_l2g.data(),
4179  mesh_trial_trace_ref.data(),
4180  xt_ext,yt_ext,zt_ext,
4181  normal,
4182  boundaryJac,
4183  metricTensor,
4184  integralScaling);
4185  //xt_ext=0.0;yt_ext=0.0;zt_ext=0.0;
4186  //std::cout<<"xt_ext "<<xt_ext<<'\t'<<yt_ext<<'\t'<<zt_ext<<std::endl;
4187  //std::cout<<"x_ext "<<x_ext<<'\t'<<y_ext<<'\t'<<z_ext<<std::endl;
4188  //std::cout<<"integralScaling - metricTensorDetSrt ==============================="<<integralScaling-metricTensorDetSqrt<<std::endl;
4189  /* std::cout<<"metricTensorDetSqrt "<<metricTensorDetSqrt */
4190  /* <<"dS_ref.data()[kb]"<<dS_ref.data()[kb]<<std::endl; */
4191  //dS = ((1.0-MOVING_DOMAIN)*metricTensorDetSqrt + MOVING_DOMAIN*integralScaling)*dS_ref.data()[kb];//cek need to test effect on accuracy
4192  dS = metricTensorDetSqrt*dS_ref.data()[kb];
4193  //get the metric tensor
4194  //cek todo use symmetry
4195  ck.calculateG(jacInv_ext,G,G_dd_G,tr_G);
4196  ck.calculateGScale(G,&ebqe_normal_phi_ext.data()[ebNE_kb_nSpace],h_phi);
4197 
4198  eps_rho = epsFact_rho*(useMetrics*h_phi+(1.0-useMetrics)*elementDiameter.data()[eN]);
4199  eps_mu = epsFact_mu *(useMetrics*h_phi+(1.0-useMetrics)*elementDiameter.data()[eN]);
4200 
4201  //compute shape and solution information
4202  //shape
4203  ck.gradTrialFromRef(&p_grad_trial_trace_ref.data()[ebN_local_kb_nSpace*nDOF_trial_element],jacInv_ext,p_grad_trial_trace);
4204  ck_v.gradTrialFromRef(&vel_grad_trial_trace_ref.data()[ebN_local_kb_nSpace*nDOF_v_trial_element],jacInv_ext,vel_grad_trial_trace);
4205  //solution and gradients
4206  ck.valFromDOF(p_dof.data(),&p_l2g.data()[eN_nDOF_trial_element],&p_trial_trace_ref.data()[ebN_local_kb*nDOF_test_element],p_ext);
4207  ck_v.valFromDOF(u_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],&vel_trial_trace_ref.data()[ebN_local_kb*nDOF_v_test_element],u_ext);
4208  ck_v.valFromDOF(v_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],&vel_trial_trace_ref.data()[ebN_local_kb*nDOF_v_test_element],v_ext);
4209  ck_v.valFromDOF(w_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],&vel_trial_trace_ref.data()[ebN_local_kb*nDOF_v_test_element],w_ext);
4210  ck.valFromDOF(p_old_dof.data(),&p_l2g.data()[eN_nDOF_trial_element],&p_trial_trace_ref.data()[ebN_local_kb*nDOF_test_element],p_old);
4211  ck_v.valFromDOF(u_old_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],&vel_trial_trace_ref.data()[ebN_local_kb*nDOF_v_test_element],u_old);
4212  ck_v.valFromDOF(v_old_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],&vel_trial_trace_ref.data()[ebN_local_kb*nDOF_v_test_element],v_old);
4213  ck_v.valFromDOF(w_old_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],&vel_trial_trace_ref.data()[ebN_local_kb*nDOF_v_test_element],w_old);
4214  ck.gradFromDOF(p_dof.data(),&p_l2g.data()[eN_nDOF_trial_element],p_grad_trial_trace,grad_p_ext);
4215  ck_v.gradFromDOF(u_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],vel_grad_trial_trace,grad_u_ext);
4216  ck_v.gradFromDOF(v_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],vel_grad_trial_trace,grad_v_ext);
4217  ck_v.gradFromDOF(w_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],vel_grad_trial_trace,grad_w_ext);
4218  ck.gradFromDOF(p_old_dof.data(),&p_l2g.data()[eN_nDOF_trial_element],p_grad_trial_trace,grad_p_old);
4219  ck_v.gradFromDOF(u_old_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],vel_grad_trial_trace,grad_u_old);
4220  ck_v.gradFromDOF(v_old_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],vel_grad_trial_trace,grad_v_old);
4221  ck_v.gradFromDOF(w_old_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],vel_grad_trial_trace,grad_w_old);
4222  ck.valFromDOF(phi_solid_nodes.data(),&p_l2g.data()[eN_nDOF_trial_element],&p_trial_trace_ref.data()[ebN_local_kb*nDOF_test_element],phi_s_ext);
4223  //precalculate test function products with integration weights
4224  for (int j=0;j<nDOF_test_element;j++)
4225  {
4226  p_test_dS[j] = p_test_trace_ref.data()[ebN_local_kb*nDOF_test_element+j]*dS;
4227  }
4228  for (int j=0;j<nDOF_v_test_element;j++)
4229  {
4230  vel_test_dS[j] = vel_test_trace_ref.data()[ebN_local_kb*nDOF_v_test_element+j]*dS;
4231  for (int I=0;I<nSpace;I++)
4232  vel_grad_test_dS[j*nSpace+I] = vel_grad_trial_trace[j*nSpace+I]*dS;//assume test_j = trial_j
4233  }
4234  bc_p_ext = isDOFBoundary_p.data()[ebNE_kb]*ebqe_bc_p_ext.data()[ebNE_kb]+(1-isDOFBoundary_p.data()[ebNE_kb])*p_ext;
4235  //note, our convention is that bc values at moving boundaries are relative to boundary velocity so we add it here
4236  bc_u_ext = isDOFBoundary_u.data()[ebNE_kb]*(ebqe_bc_u_ext.data()[ebNE_kb] + MOVING_DOMAIN*xt_ext) + (1-isDOFBoundary_u.data()[ebNE_kb])*u_ext;
4237  bc_v_ext = isDOFBoundary_v.data()[ebNE_kb]*(ebqe_bc_v_ext.data()[ebNE_kb] + MOVING_DOMAIN*yt_ext) + (1-isDOFBoundary_v.data()[ebNE_kb])*v_ext;
4238  bc_w_ext = isDOFBoundary_w.data()[ebNE_kb]*(ebqe_bc_w_ext.data()[ebNE_kb] + MOVING_DOMAIN*zt_ext) + (1-isDOFBoundary_w.data()[ebNE_kb])*w_ext;
4239  //VRANS
4240  porosity_ext = ebqe_porosity_ext.data()[ebNE_kb];
4241  //
4242  //calculate the pde coefficients using the solution and the boundary values for the solution
4243  //
4244  double eddy_viscosity_ext(0.),bc_eddy_viscosity_ext(0.); //not interested in saving boundary eddy viscosity for now
4245  if (use_ball_as_particle == 1 && nParticles > 0)
4246  {
4247  get_distance_to_ball(nParticles, ball_center.data(), ball_radius.data(),x_ext,y_ext,z_ext,ebqe_phi_s.data()[ebNE_kb]);
4248  }
4249  //else ebqe_phi_s.data()[ebNE_kb] is computed in Prestep
4250  const double particle_eps = particle_epsFact*(useMetrics*h_phi+(1.0-useMetrics)*elementDiameter[eN]);
4251 
4252  //cek needs to be fixed for two-phase ifem
4253  double H = (1.0-useVF)*gf.H(eps_rho,ebqe_phi_ext[ebNE_kb]) + useVF*fmin(1.0,fmax(0.0,ebqe_vf_ext[ebNE_kb]));
4254  double ImH = (1.0-useVF)*gf.ImH(eps_rho,ebqe_phi_ext[ebNE_kb]) + useVF*(1.0-fmin(1.0,fmax(0.0,ebqe_vf_ext[ebNE_kb])));
4255  double rho = rho_0*ImH + rho_1*H;
4256  double nu = nu_0*ImH + nu_1*H;
4257  //
4258  evaluateCoefficients(NONCONSERVATIVE_FORM,
4259  sigma,
4260  rho,
4261  nu,
4262  elementDiameter.data()[eN],
4263  smagorinskyConstant,
4264  turbulenceClosureModel,
4265  g.data(),
4266  useVF,
4267  ebqe_vf_ext.data()[ebNE_kb],
4268  ebqe_phi_ext.data()[ebNE_kb],
4269  &ebqe_normal_phi_ext.data()[ebNE_kb_nSpace],
4270  ebqe_kappa_phi_ext.data()[ebNE_kb],
4271  //VRANS
4272  porosity_ext,
4273  //
4274  ebqe_phi_s.data()[ebNE_kb],
4275  p_old,
4276  u_old,
4277  v_old,
4278  w_old,
4279  grad_p_old,
4280  grad_u_old,
4281  grad_v_old,
4282  grad_w_old,
4283  p_ext,
4284  grad_p_ext,
4285  grad_u_ext,
4286  grad_v_ext,
4287  grad_w_ext,
4288  u_ext,
4289  v_ext,
4290  w_ext,
4291  LAG_LES,
4292  ebqe_eddy_viscosity.data()[ebNE_kb],
4293  ebqe_eddy_viscosity_last.data()[ebNE_kb],
4294  mom_u_acc_ext,
4295  dmom_u_acc_u_ext,
4296  mom_v_acc_ext,
4297  dmom_v_acc_v_ext,
4298  mom_w_acc_ext,
4299  dmom_w_acc_w_ext,
4300  mass_adv_ext,
4301  dmass_adv_u_ext,
4302  dmass_adv_v_ext,
4303  dmass_adv_w_ext,
4304  mom_u_adv_ext,
4305  dmom_u_adv_u_ext,
4306  dmom_u_adv_v_ext,
4307  dmom_u_adv_w_ext,
4308  mom_v_adv_ext,
4309  dmom_v_adv_u_ext,
4310  dmom_v_adv_v_ext,
4311  dmom_v_adv_w_ext,
4312  mom_w_adv_ext,
4313  dmom_w_adv_u_ext,
4314  dmom_w_adv_v_ext,
4315  dmom_w_adv_w_ext,
4316  mom_uu_diff_ten_ext,
4317  mom_vv_diff_ten_ext,
4318  mom_ww_diff_ten_ext,
4319  mom_uv_diff_ten_ext,
4320  mom_uw_diff_ten_ext,
4321  mom_vu_diff_ten_ext,
4322  mom_vw_diff_ten_ext,
4323  mom_wu_diff_ten_ext,
4324  mom_wv_diff_ten_ext,
4325  mom_u_source_ext,
4326  mom_v_source_ext,
4327  mom_w_source_ext,
4328  mom_u_ham_ext,
4329  dmom_u_ham_grad_p_ext,
4330  dmom_u_ham_grad_u_ext,
4331  dmom_u_ham_u_ext,
4332  dmom_u_ham_v_ext,
4333  dmom_u_ham_w_ext,
4334  mom_v_ham_ext,
4335  dmom_v_ham_grad_p_ext,
4336  dmom_v_ham_grad_v_ext,
4337  dmom_v_ham_u_ext,
4338  dmom_v_ham_v_ext,
4339  dmom_v_ham_w_ext,
4340  mom_w_ham_ext,
4341  dmom_w_ham_grad_p_ext,
4342  dmom_w_ham_grad_w_ext,
4343  dmom_w_ham_u_ext,
4344  dmom_w_ham_v_ext,
4345  dmom_w_ham_w_ext,
4346  0.0,
4347  0.0,
4348  0.0);
4349  //cek needs to be fixed for two-phase ifem
4350  H = (1.0-useVF)*gf.H(eps_rho,bc_ebqe_phi_ext[ebNE_kb]) + useVF*fmin(1.0,fmax(0.0,bc_ebqe_vf_ext[ebNE_kb]));
4351  ImH = (1.0-useVF)*gf.ImH(eps_rho,bc_ebqe_phi_ext[ebNE_kb]) + useVF*(1.0-fmin(1.0,fmax(0.0,bc_ebqe_vf_ext[ebNE_kb])));
4352  rho = rho_0*ImH + rho_1*H;
4353  nu = nu_0*ImH + nu_1*H;
4354  //
4355  evaluateCoefficients(NONCONSERVATIVE_FORM,
4356  sigma,
4357  rho,
4358  nu,
4359  elementDiameter.data()[eN],
4360  smagorinskyConstant,
4361  turbulenceClosureModel,
4362  g.data(),
4363  useVF,
4364  bc_ebqe_vf_ext.data()[ebNE_kb],
4365  bc_ebqe_phi_ext.data()[ebNE_kb],
4366  &ebqe_normal_phi_ext.data()[ebNE_kb_nSpace],
4367  ebqe_kappa_phi_ext.data()[ebNE_kb],
4368  //VRANS
4369  porosity_ext,
4370  //
4371  ebqe_phi_s.data()[ebNE_kb],
4372  p_old,
4373  u_old,
4374  v_old,
4375  w_old,
4376  grad_p_old,
4377  grad_u_old,
4378  grad_v_old,
4379  grad_w_old,
4380  bc_p_ext,
4381  grad_p_ext,
4382  grad_u_ext,
4383  grad_v_ext,
4384  grad_w_ext,
4385  bc_u_ext,
4386  bc_v_ext,
4387  bc_w_ext,
4388  LAG_LES,
4389  bc_eddy_viscosity_ext,
4390  ebqe_eddy_viscosity_last.data()[ebNE_kb],
4391  bc_mom_u_acc_ext,
4392  bc_dmom_u_acc_u_ext,
4393  bc_mom_v_acc_ext,
4394  bc_dmom_v_acc_v_ext,
4395  bc_mom_w_acc_ext,
4396  bc_dmom_w_acc_w_ext,
4397  bc_mass_adv_ext,
4398  bc_dmass_adv_u_ext,
4399  bc_dmass_adv_v_ext,
4400  bc_dmass_adv_w_ext,
4401  bc_mom_u_adv_ext,
4402  bc_dmom_u_adv_u_ext,
4403  bc_dmom_u_adv_v_ext,
4404  bc_dmom_u_adv_w_ext,
4405  bc_mom_v_adv_ext,
4406  bc_dmom_v_adv_u_ext,
4407  bc_dmom_v_adv_v_ext,
4408  bc_dmom_v_adv_w_ext,
4409  bc_mom_w_adv_ext,
4410  bc_dmom_w_adv_u_ext,
4411  bc_dmom_w_adv_v_ext,
4412  bc_dmom_w_adv_w_ext,
4413  bc_mom_uu_diff_ten_ext,
4414  bc_mom_vv_diff_ten_ext,
4415  bc_mom_ww_diff_ten_ext,
4416  bc_mom_uv_diff_ten_ext,
4417  bc_mom_uw_diff_ten_ext,
4418  bc_mom_vu_diff_ten_ext,
4419  bc_mom_vw_diff_ten_ext,
4420  bc_mom_wu_diff_ten_ext,
4421  bc_mom_wv_diff_ten_ext,
4422  bc_mom_u_source_ext,
4423  bc_mom_v_source_ext,
4424  bc_mom_w_source_ext,
4425  bc_mom_u_ham_ext,
4426  bc_dmom_u_ham_grad_p_ext,
4427  bc_dmom_u_ham_grad_u_ext,
4428  bc_dmom_u_ham_u_ext,
4429  bc_dmom_u_ham_v_ext,
4430  bc_dmom_u_ham_w_ext,
4431  bc_mom_v_ham_ext,
4432  bc_dmom_v_ham_grad_p_ext,
4433  bc_dmom_v_ham_grad_v_ext,
4434  bc_dmom_v_ham_u_ext,
4435  bc_dmom_v_ham_v_ext,
4436  bc_dmom_v_ham_w_ext,
4437  bc_mom_w_ham_ext,
4438  bc_dmom_w_ham_grad_p_ext,
4439  bc_dmom_w_ham_grad_w_ext,
4440  bc_dmom_w_ham_u_ext,
4441  bc_dmom_w_ham_v_ext,
4442  bc_dmom_w_ham_w_ext,
4443  0.0,
4444  0.0,
4445  0.0);
4446 
4447  //Turbulence closure model
4448  if (turbulenceClosureModel >= 3)
4449  {
4450  const double turb_var_grad_0_dummy[nSpace] = ZEROVEC;
4451  const double c_mu = 0.09;//mwf hack
4452  updateTurbulenceClosure(NONCONSERVATIVE_FORM,
4453  turbulenceClosureModel,
4454  eps_rho,
4455  eps_mu,
4456  rho_0,
4457  nu_0,
4458  rho_1,
4459  nu_1,
4460  useVF,
4461  ebqe_vf_ext.data()[ebNE_kb],
4462  ebqe_phi_ext.data()[ebNE_kb],
4463  porosity_ext,
4464  c_mu, //mwf hack
4465  ebqe_turb_var_0.data()[ebNE_kb],
4466  ebqe_turb_var_1.data()[ebNE_kb],
4467  turb_var_grad_0_dummy, //not needed
4468  ebqe_eddy_viscosity.data()[ebNE_kb],
4469  mom_uu_diff_ten_ext,
4470  mom_vv_diff_ten_ext,
4471  mom_ww_diff_ten_ext,
4472  mom_uv_diff_ten_ext,
4473  mom_uw_diff_ten_ext,
4474  mom_vu_diff_ten_ext,
4475  mom_vw_diff_ten_ext,
4476  mom_wu_diff_ten_ext,
4477  mom_wv_diff_ten_ext,
4478  mom_u_source_ext,
4479  mom_v_source_ext,
4480  mom_w_source_ext);
4481 
4482  updateTurbulenceClosure(NONCONSERVATIVE_FORM,
4483  turbulenceClosureModel,
4484  eps_rho,
4485  eps_mu,
4486  rho_0,
4487  nu_0,
4488  rho_1,
4489  nu_1,
4490  useVF,
4491  bc_ebqe_vf_ext.data()[ebNE_kb],
4492  bc_ebqe_phi_ext.data()[ebNE_kb],
4493  porosity_ext,
4494  c_mu, //mwf hack
4495  ebqe_turb_var_0.data()[ebNE_kb],
4496  ebqe_turb_var_1.data()[ebNE_kb],
4497  turb_var_grad_0_dummy, //not needed
4498  bc_eddy_viscosity_ext,
4499  bc_mom_uu_diff_ten_ext,
4500  bc_mom_vv_diff_ten_ext,
4501  bc_mom_ww_diff_ten_ext,
4502  bc_mom_uv_diff_ten_ext,
4503  bc_mom_uw_diff_ten_ext,
4504  bc_mom_vu_diff_ten_ext,
4505  bc_mom_vw_diff_ten_ext,
4506  bc_mom_wu_diff_ten_ext,
4507  bc_mom_wv_diff_ten_ext,
4508  bc_mom_u_source_ext,
4509  bc_mom_v_source_ext,
4510  bc_mom_w_source_ext);
4511  }
4512 
4513 
4514  //
4515  //moving domain
4516  //
4517  if (NONCONSERVATIVE_FORM > 0.0)
4518  {
4519  mom_u_ham_ext -= MOVING_DOMAIN*dmom_u_acc_u_ext*(grad_u_ext[0]*xt_ext + grad_u_ext[1]*yt_ext + grad_u_ext[2]*zt_ext);
4520  dmom_u_ham_grad_u_ext[0] -= MOVING_DOMAIN*dmom_u_acc_u_ext*xt_ext;
4521  dmom_u_ham_grad_u_ext[1] -= MOVING_DOMAIN*dmom_u_acc_u_ext*yt_ext;
4522  dmom_u_ham_grad_u_ext[2] -= MOVING_DOMAIN*dmom_u_acc_u_ext*zt_ext;
4523  }
4524  else
4525  {
4526  mom_u_adv_ext[0] -= MOVING_DOMAIN*mom_u_acc_ext*xt_ext;
4527  mom_u_adv_ext[1] -= MOVING_DOMAIN*mom_u_acc_ext*yt_ext;
4528  mom_u_adv_ext[2] -= MOVING_DOMAIN*mom_u_acc_ext*zt_ext;
4529  dmom_u_adv_u_ext[0] -= MOVING_DOMAIN*dmom_u_acc_u_ext*xt_ext;
4530  dmom_u_adv_u_ext[1] -= MOVING_DOMAIN*dmom_u_acc_u_ext*yt_ext;
4531  dmom_u_adv_u_ext[2] -= MOVING_DOMAIN*dmom_u_acc_u_ext*zt_ext;
4532  }
4533 
4534 
4535  if (NONCONSERVATIVE_FORM > 0.0)
4536  {
4537  mom_v_ham_ext -= MOVING_DOMAIN*dmom_v_acc_v_ext*(grad_v_ext[0]*xt_ext + grad_v_ext[1]*yt_ext + grad_v_ext[2]*zt_ext);
4538  dmom_v_ham_grad_v_ext[0] -= MOVING_DOMAIN*dmom_v_acc_v_ext*xt_ext;
4539  dmom_v_ham_grad_v_ext[1] -= MOVING_DOMAIN*dmom_v_acc_v_ext*yt_ext;
4540  dmom_v_ham_grad_v_ext[2] -= MOVING_DOMAIN*dmom_v_acc_v_ext*zt_ext;
4541  }
4542  else
4543  {
4544  mom_v_adv_ext[0] -= MOVING_DOMAIN*mom_v_acc_ext*xt_ext;
4545  mom_v_adv_ext[1] -= MOVING_DOMAIN*mom_v_acc_ext*yt_ext;
4546  mom_v_adv_ext[2] -= MOVING_DOMAIN*mom_v_acc_ext*zt_ext;
4547  dmom_v_adv_v_ext[0] -= MOVING_DOMAIN*dmom_v_acc_v_ext*xt_ext;
4548  dmom_v_adv_v_ext[1] -= MOVING_DOMAIN*dmom_v_acc_v_ext*yt_ext;
4549  dmom_v_adv_v_ext[2] -= MOVING_DOMAIN*dmom_v_acc_v_ext*zt_ext;
4550  }
4551 
4552 
4553  if (NONCONSERVATIVE_FORM > 0.0)
4554  {
4555  mom_w_ham_ext -= MOVING_DOMAIN*dmom_w_acc_w_ext*(grad_w_ext[0]*xt_ext + grad_w_ext[1]*yt_ext + grad_w_ext[2]*zt_ext);
4556  dmom_w_ham_grad_w_ext[0] -= MOVING_DOMAIN*dmom_w_acc_w_ext*xt_ext;
4557  dmom_w_ham_grad_w_ext[1] -= MOVING_DOMAIN*dmom_w_acc_w_ext*yt_ext;
4558  dmom_w_ham_grad_w_ext[2] -= MOVING_DOMAIN*dmom_w_acc_w_ext*zt_ext;
4559  }
4560  else
4561  {
4562  mom_w_adv_ext[0] -= MOVING_DOMAIN*mom_w_acc_ext*xt_ext;
4563  mom_w_adv_ext[1] -= MOVING_DOMAIN*mom_w_acc_ext*yt_ext;
4564  mom_w_adv_ext[2] -= MOVING_DOMAIN*mom_w_acc_ext*zt_ext;
4565  dmom_w_adv_w_ext[0] -= MOVING_DOMAIN*dmom_w_acc_w_ext*xt_ext;
4566  dmom_w_adv_w_ext[1] -= MOVING_DOMAIN*dmom_w_acc_w_ext*yt_ext;
4567  dmom_w_adv_w_ext[2] -= MOVING_DOMAIN*dmom_w_acc_w_ext*zt_ext;
4568  }
4569 
4570  //bc's
4571  if (NONCONSERVATIVE_FORM < 1.0)
4572  {
4573  bc_mom_u_adv_ext[0] -= MOVING_DOMAIN*bc_mom_u_acc_ext*xt_ext;
4574  bc_mom_u_adv_ext[1] -= MOVING_DOMAIN*bc_mom_u_acc_ext*yt_ext;
4575  bc_mom_u_adv_ext[2] -= MOVING_DOMAIN*bc_mom_u_acc_ext*zt_ext;
4576 
4577  bc_mom_v_adv_ext[0] -= MOVING_DOMAIN*bc_mom_v_acc_ext*xt_ext;
4578  bc_mom_v_adv_ext[1] -= MOVING_DOMAIN*bc_mom_v_acc_ext*yt_ext;
4579  bc_mom_v_adv_ext[2] -= MOVING_DOMAIN*bc_mom_v_acc_ext*zt_ext;
4580 
4581  bc_mom_w_adv_ext[0] -= MOVING_DOMAIN*bc_mom_w_acc_ext*xt_ext;
4582  bc_mom_w_adv_ext[1] -= MOVING_DOMAIN*bc_mom_w_acc_ext*yt_ext;
4583  bc_mom_w_adv_ext[2] -= MOVING_DOMAIN*bc_mom_w_acc_ext*zt_ext;
4584  }
4585  //
4586  //calculate the numerical fluxes
4587  //
4588  ck.calculateGScale(G,normal,h_penalty);
4589  penalty = useMetrics*C_b/h_penalty + (1.0-useMetrics)*ebqe_penalty_ext.data()[ebNE_kb];
4590  exteriorNumericalAdvectiveFlux(NONCONSERVATIVE_FORM,
4591  isDOFBoundary_p.data()[ebNE_kb],
4592  isDOFBoundary_u.data()[ebNE_kb],
4593  isDOFBoundary_v.data()[ebNE_kb],
4594  isDOFBoundary_w.data()[ebNE_kb],
4595  isAdvectiveFluxBoundary_p.data()[ebNE_kb],
4596  isAdvectiveFluxBoundary_u.data()[ebNE_kb],
4597  isAdvectiveFluxBoundary_v.data()[ebNE_kb],
4598  isAdvectiveFluxBoundary_w.data()[ebNE_kb],
4599  dmom_u_ham_grad_p_ext[0],//=1/rho,
4600  bc_dmom_u_ham_grad_p_ext[0],//=1/bc_rho,
4601  normal,
4602  bc_p_ext,
4603  bc_u_ext,
4604  bc_v_ext,
4605  bc_w_ext,
4606  bc_mass_adv_ext,
4607  bc_mom_u_adv_ext,
4608  bc_mom_v_adv_ext,
4609  bc_mom_w_adv_ext,
4610  ebqe_bc_flux_mass_ext.data()[ebNE_kb]+MOVING_DOMAIN*(xt_ext*normal[0]+yt_ext*normal[1]+zt_ext*normal[2]),//BC is relative mass flux
4611  ebqe_bc_flux_mom_u_adv_ext.data()[ebNE_kb],
4612  ebqe_bc_flux_mom_v_adv_ext.data()[ebNE_kb],
4613  ebqe_bc_flux_mom_w_adv_ext.data()[ebNE_kb],
4614  p_ext,
4615  u_ext,
4616  v_ext,
4617  w_ext,
4618  mass_adv_ext,
4619  mom_u_adv_ext,
4620  mom_v_adv_ext,
4621  mom_w_adv_ext,
4622  dmass_adv_u_ext,
4623  dmass_adv_v_ext,
4624  dmass_adv_w_ext,
4625  dmom_u_adv_p_ext,
4626  dmom_u_ham_grad_u_ext,
4627  dmom_u_adv_u_ext,
4628  dmom_u_adv_v_ext,
4629  dmom_u_adv_w_ext,
4630  dmom_v_adv_p_ext,
4631  dmom_v_adv_u_ext,
4632  dmom_v_adv_v_ext,
4633  dmom_v_adv_w_ext,
4634  dmom_w_adv_p_ext,
4635  dmom_w_adv_u_ext,
4636  dmom_w_adv_v_ext,
4637  dmom_w_adv_w_ext,
4638  flux_mass_ext,
4639  flux_mom_u_adv_ext,
4640  flux_mom_v_adv_ext,
4641  flux_mom_w_adv_ext,
4642  &ebqe_velocity.data()[ebNE_kb_nSpace]);
4643  for (int I=0;I<nSpace;I++)
4644  ebqe_velocity.data()[ebNE_kb_nSpace+I]/=porosity_ext;
4646  ebqe_phi_ext.data()[ebNE_kb],
4647  sdInfo_u_u_rowptr.data(),
4648  sdInfo_u_u_colind.data(),
4649  isDOFBoundary_u.data()[ebNE_kb],
4650  isDiffusiveFluxBoundary_u.data()[ebNE_kb],
4651  normal,
4652  bc_mom_uu_diff_ten_ext,
4653  bc_u_ext,
4654  ebqe_bc_flux_u_diff_ext.data()[ebNE_kb],
4655  mom_uu_diff_ten_ext,
4656  grad_u_ext,
4657  u_ext,
4658  penalty,//ebqe_penalty_ext.data()[ebNE_kb],
4659  flux_mom_uu_diff_ext);
4661  ebqe_phi_ext.data()[ebNE_kb],
4662  sdInfo_u_v_rowptr.data(),
4663  sdInfo_u_v_colind.data(),
4664  isDOFBoundary_v.data()[ebNE_kb],
4665  isDiffusiveFluxBoundary_v.data()[ebNE_kb],
4666  normal,
4667  bc_mom_uv_diff_ten_ext,
4668  bc_v_ext,
4669  0.0,//assume all of the flux gets applied in diagonal component
4670  mom_uv_diff_ten_ext,
4671  grad_v_ext,
4672  v_ext,
4673  penalty,//ebqe_penalty_ext.data()[ebNE_kb],
4674  flux_mom_uv_diff_ext);
4676  ebqe_phi_ext.data()[ebNE_kb],
4677  sdInfo_u_w_rowptr.data(),
4678  sdInfo_u_w_colind.data(),
4679  isDOFBoundary_w.data()[ebNE_kb],
4680  isDiffusiveFluxBoundary_w.data()[ebNE_kb],
4681  normal,
4682  bc_mom_uw_diff_ten_ext,
4683  bc_w_ext,
4684  0.0,//see above
4685  mom_uw_diff_ten_ext,
4686  grad_w_ext,
4687  w_ext,
4688  penalty,//ebqe_penalty_ext.data()[ebNE_kb],
4689  flux_mom_uw_diff_ext);
4691  ebqe_phi_ext.data()[ebNE_kb],
4692  sdInfo_v_u_rowptr.data(),
4693  sdInfo_v_u_colind.data(),
4694  isDOFBoundary_u.data()[ebNE_kb],
4695  isDiffusiveFluxBoundary_u.data()[ebNE_kb],
4696  normal,
4697  bc_mom_vu_diff_ten_ext,
4698  bc_u_ext,
4699  0.0,//see above
4700  mom_vu_diff_ten_ext,
4701  grad_u_ext,
4702  u_ext,
4703  penalty,//ebqe_penalty_ext.data()[ebNE_kb],
4704  flux_mom_vu_diff_ext);
4706  ebqe_phi_ext.data()[ebNE_kb],
4707  sdInfo_v_v_rowptr.data(),
4708  sdInfo_v_v_colind.data(),
4709  isDOFBoundary_v.data()[ebNE_kb],
4710  isDiffusiveFluxBoundary_v.data()[ebNE_kb],
4711  normal,
4712  bc_mom_vv_diff_ten_ext,
4713  bc_v_ext,
4714  ebqe_bc_flux_v_diff_ext.data()[ebNE_kb],
4715  mom_vv_diff_ten_ext,
4716  grad_v_ext,
4717  v_ext,
4718  penalty,//ebqe_penalty_ext.data()[ebNE_kb],
4719  flux_mom_vv_diff_ext);
4721  ebqe_phi_ext.data()[ebNE_kb],
4722  sdInfo_v_w_rowptr.data(),
4723  sdInfo_v_w_colind.data(),
4724  isDOFBoundary_w.data()[ebNE_kb],
4725  isDiffusiveFluxBoundary_w.data()[ebNE_kb],
4726  normal,
4727  bc_mom_vw_diff_ten_ext,
4728  bc_w_ext,
4729  0.0,//see above
4730  mom_vw_diff_ten_ext,
4731  grad_w_ext,
4732  w_ext,
4733  penalty,//ebqe_penalty_ext.data()[ebNE_kb],
4734  flux_mom_vw_diff_ext);
4736  ebqe_phi_ext.data()[ebNE_kb],
4737  sdInfo_w_u_rowptr.data(),
4738  sdInfo_w_u_colind.data(),
4739  isDOFBoundary_u.data()[ebNE_kb],
4740  isDiffusiveFluxBoundary_u.data()[ebNE_kb],
4741  normal,
4742  bc_mom_wu_diff_ten_ext,
4743  bc_u_ext,
4744  0.0,//see above
4745  mom_wu_diff_ten_ext,
4746  grad_u_ext,
4747  u_ext,
4748  penalty,//ebqe_penalty_ext.data()[ebNE_kb],
4749  flux_mom_wu_diff_ext);
4751  ebqe_phi_ext.data()[ebNE_kb],
4752  sdInfo_w_v_rowptr.data(),
4753  sdInfo_w_v_colind.data(),
4754  isDOFBoundary_v.data()[ebNE_kb],
4755  isDiffusiveFluxBoundary_v.data()[ebNE_kb],
4756  normal,
4757  bc_mom_wv_diff_ten_ext,
4758  bc_v_ext,
4759  0.0,//see above
4760  mom_wv_diff_ten_ext,
4761  grad_v_ext,
4762  v_ext,
4763  penalty,//ebqe_penalty_ext.data()[ebNE_kb],
4764  flux_mom_wv_diff_ext);
4766  ebqe_phi_ext.data()[ebNE_kb],
4767  sdInfo_w_w_rowptr.data(),
4768  sdInfo_w_w_colind.data(),
4769  isDOFBoundary_w.data()[ebNE_kb],
4770  isDiffusiveFluxBoundary_w.data()[ebNE_kb],
4771  normal,
4772  bc_mom_ww_diff_ten_ext,
4773  bc_w_ext,
4774  ebqe_bc_flux_w_diff_ext.data()[ebNE_kb],
4775  mom_ww_diff_ten_ext,
4776  grad_w_ext,
4777  w_ext,
4778  penalty,//ebqe_penalty_ext.data()[ebNE_kb],
4779  flux_mom_ww_diff_ext);
4780  flux.data()[ebN*nQuadraturePoints_elementBoundary+kb] = flux_mass_ext;
4781  /* std::cout<<"external u,v,u_n " */
4782  /* <<ebqe_velocity.data()[ebNE_kb_nSpace+0]<<'\t' */
4783  /* <<ebqe_velocity.data()[ebNE_kb_nSpace+1]<<'\t' */
4784  /* <<flux.data()[ebN*nQuadraturePoints_elementBoundary+kb]<<std::endl; */
4785  //
4786  //integrate the net force and moment on flagged boundaries
4787  //
4788  if (ebN < nElementBoundaries_owned)
4789  {
4790  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
4791  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];
4792  force_v_z = (flux_mom_w_adv_ext + flux_mom_wu_diff_ext + flux_mom_wv_diff_ext + flux_mom_ww_diff_ext)/dmom_u_ham_grad_p_ext[0];
4793 
4794  force_p_x = p_ext*normal[0];
4795  force_p_y = p_ext*normal[1];
4796  force_p_z = p_ext*normal[2];
4797 
4798  force_x = force_p_x + force_v_x;
4799  force_y = force_p_y + force_v_y;
4800  force_z = force_p_z + force_v_z;
4801 
4802  r_x = x_ext - barycenters.data()[3*boundaryFlags.data()[ebN]+0];
4803  r_y = y_ext - barycenters.data()[3*boundaryFlags.data()[ebN]+1];
4804  r_z = z_ext - barycenters.data()[3*boundaryFlags.data()[ebN]+2];
4805 
4806  wettedAreas.data()[boundaryFlags.data()[ebN]] += dS*(1.0-ebqe_vf_ext.data()[ebNE_kb]);
4807 
4808  netForces_p.data()[3*boundaryFlags.data()[ebN]+0] += force_p_x*dS;
4809  netForces_p.data()[3*boundaryFlags.data()[ebN]+1] += force_p_y*dS;
4810  netForces_p.data()[3*boundaryFlags.data()[ebN]+2] += force_p_z*dS;
4811 
4812  netForces_v.data()[3*boundaryFlags.data()[ebN]+0] += force_v_x*dS;
4813  netForces_v.data()[3*boundaryFlags.data()[ebN]+1] += force_v_y*dS;
4814  netForces_v.data()[3*boundaryFlags.data()[ebN]+2] += force_v_z*dS;
4815 
4816  netMoments.data()[3*boundaryFlags.data()[ebN]+0] += (r_y*force_z - r_z*force_y)*dS;
4817  netMoments.data()[3*boundaryFlags.data()[ebN]+1] += (r_z*force_x - r_x*force_z)*dS;
4818  netMoments.data()[3*boundaryFlags.data()[ebN]+2] += (r_x*force_y - r_y*force_x)*dS;
4819  }
4820  //
4821  //update residuals
4822  //
4823  const double H_s = gf_s.H(particle_eps, ebqe_phi_s.data()[ebNE_kb]);
4824  if (isActiveElement[eN])
4825  { //if boundary flag positive, then include flux contributions on interpart boundaries
4826  total_flux += flux_mass_ext*dS;
4827  for (int i=0;i<nDOF_test_element;i++)
4828  {
4829  elementResidual_mesh[i] -= H_s*ck.ExteriorElementBoundaryFlux(MOVING_DOMAIN*(xt_ext*normal[0]+yt_ext*normal[1]+zt_ext*normal[2]),p_test_dS[i]);
4830  elementResidual_p[i] += H_s*ck.ExteriorElementBoundaryFlux(flux_mass_ext,p_test_dS[i]);
4831  elementResidual_p[i] -= H_s*DM*ck.ExteriorElementBoundaryFlux(MOVING_DOMAIN*(xt_ext*normal[0]+yt_ext*normal[1]+zt_ext*normal[2]),p_test_dS[i]);
4832  globalConservationError += H_s*ck.ExteriorElementBoundaryFlux(flux_mass_ext,p_test_dS[i]);
4833  }
4834  for (int i=0;i<nDOF_v_test_element;i++)
4835  {
4836  elementResidual_u[i] += H_s*(ck.ExteriorElementBoundaryFlux(flux_mom_u_adv_ext,vel_test_dS[i])+
4837  ck.ExteriorElementBoundaryFlux(flux_mom_uu_diff_ext,vel_test_dS[i])+
4838  ck.ExteriorElementBoundaryFlux(flux_mom_uv_diff_ext,vel_test_dS[i])+
4839  ck.ExteriorElementBoundaryFlux(flux_mom_uw_diff_ext,vel_test_dS[i])+
4840  ck.ExteriorElementBoundaryDiffusionAdjoint(isDOFBoundary_u.data()[ebNE_kb],
4841  isDiffusiveFluxBoundary_u.data()[ebNE_kb],
4842  eb_adjoint_sigma,
4843  u_ext,
4844  bc_u_ext,
4845  normal,
4846  sdInfo_u_u_rowptr.data(),
4847  sdInfo_u_u_colind.data(),
4848  mom_uu_diff_ten_ext,
4849  &vel_grad_test_dS[i*nSpace])+
4850  ck.ExteriorElementBoundaryDiffusionAdjoint(isDOFBoundary_v.data()[ebNE_kb],
4851  isDiffusiveFluxBoundary_u.data()[ebNE_kb],
4852  eb_adjoint_sigma,
4853  v_ext,
4854  bc_v_ext,
4855  normal,
4856  sdInfo_u_v_rowptr.data(),
4857  sdInfo_u_v_colind.data(),
4858  mom_uv_diff_ten_ext,
4859  &vel_grad_test_dS[i*nSpace])+
4860  ck.ExteriorElementBoundaryDiffusionAdjoint(isDOFBoundary_w.data()[ebNE_kb],
4861  isDiffusiveFluxBoundary_u.data()[ebNE_kb],
4862  eb_adjoint_sigma,
4863  w_ext,
4864  bc_w_ext,
4865  normal,
4866  sdInfo_u_w_rowptr.data(),
4867  sdInfo_u_w_colind.data(),
4868  mom_uw_diff_ten_ext,
4869  &vel_grad_test_dS[i*nSpace]));
4870  elementResidual_v[i] += H_s*(ck.ExteriorElementBoundaryFlux(flux_mom_v_adv_ext,vel_test_dS[i]) +
4871  ck.ExteriorElementBoundaryFlux(flux_mom_vu_diff_ext,vel_test_dS[i])+
4872  ck.ExteriorElementBoundaryFlux(flux_mom_vv_diff_ext,vel_test_dS[i])+
4873  ck.ExteriorElementBoundaryFlux(flux_mom_vw_diff_ext,vel_test_dS[i])+
4874  ck.ExteriorElementBoundaryDiffusionAdjoint(isDOFBoundary_u.data()[ebNE_kb],
4875  isDiffusiveFluxBoundary_v.data()[ebNE_kb],
4876  eb_adjoint_sigma,
4877  u_ext,
4878  bc_u_ext,
4879  normal,
4880  sdInfo_v_u_rowptr.data(),
4881  sdInfo_v_u_colind.data(),
4882  mom_vu_diff_ten_ext,
4883  &vel_grad_test_dS[i*nSpace])+
4884  ck.ExteriorElementBoundaryDiffusionAdjoint(isDOFBoundary_v.data()[ebNE_kb],
4885  isDiffusiveFluxBoundary_v.data()[ebNE_kb],
4886  eb_adjoint_sigma,
4887  v_ext,
4888  bc_v_ext,
4889  normal,
4890  sdInfo_v_v_rowptr.data(),
4891  sdInfo_v_v_colind.data(),
4892  mom_vv_diff_ten_ext,
4893  &vel_grad_test_dS[i*nSpace])+
4894  ck.ExteriorElementBoundaryDiffusionAdjoint(isDOFBoundary_w.data()[ebNE_kb],
4895  isDiffusiveFluxBoundary_v.data()[ebNE_kb],
4896  eb_adjoint_sigma,
4897  w_ext,
4898  bc_w_ext,
4899  normal,
4900  sdInfo_v_w_rowptr.data(),
4901  sdInfo_v_w_colind.data(),
4902  mom_vw_diff_ten_ext,
4903  &vel_grad_test_dS[i*nSpace]));
4904 
4905  elementResidual_w[i] += H_s*(ck.ExteriorElementBoundaryFlux(flux_mom_w_adv_ext,vel_test_dS[i]) +
4906  ck.ExteriorElementBoundaryFlux(flux_mom_wu_diff_ext,vel_test_dS[i])+
4907  ck.ExteriorElementBoundaryFlux(flux_mom_wv_diff_ext,vel_test_dS[i])+
4908  ck.ExteriorElementBoundaryFlux(flux_mom_ww_diff_ext,vel_test_dS[i])+
4909  ck.ExteriorElementBoundaryDiffusionAdjoint(isDOFBoundary_u.data()[ebNE_kb],
4910  isDiffusiveFluxBoundary_w.data()[ebNE_kb],
4911  eb_adjoint_sigma,
4912  u_ext,
4913  bc_u_ext,
4914  normal,
4915  sdInfo_w_u_rowptr.data(),
4916  sdInfo_w_u_colind.data(),
4917  mom_wu_diff_ten_ext,
4918  &vel_grad_test_dS[i*nSpace])+
4919  ck.ExteriorElementBoundaryDiffusionAdjoint(isDOFBoundary_v.data()[ebNE_kb],
4920  isDiffusiveFluxBoundary_w.data()[ebNE_kb],
4921  eb_adjoint_sigma,
4922  v_ext,
4923  bc_v_ext,
4924  normal,
4925  sdInfo_w_v_rowptr.data(),
4926  sdInfo_w_v_colind.data(),
4927  mom_wv_diff_ten_ext,
4928  &vel_grad_test_dS[i*nSpace])+
4929  ck.ExteriorElementBoundaryDiffusionAdjoint(isDOFBoundary_w.data()[ebNE_kb],
4930  isDiffusiveFluxBoundary_w.data()[ebNE_kb],
4931  eb_adjoint_sigma,
4932  w_ext,
4933  bc_w_ext,
4934  normal,
4935  sdInfo_w_w_rowptr.data(),
4936  sdInfo_w_w_colind.data(),
4937  mom_ww_diff_ten_ext,
4938  &vel_grad_test_dS[i*nSpace]));
4939  }//i
4940  }//if boundary flag positive
4941  }//kb
4942  //
4943  //update the element and global residual storage
4944  //
4945  for (int i=0;i<nDOF_test_element;i++)
4946  {
4947  int eN_i = eN*nDOF_test_element+i;
4948 
4949  elementResidual_p_save.data()[eN_i] += elementResidual_p[i];
4950  mesh_volume_conservation_weak += elementResidual_mesh[i];
4951  globalResidual.data()[offset_p+stride_p*rp_l2g.data()[eN_i]]+=elementResidual_p[i];
4952  }
4953  for (int i=0;i<nDOF_v_test_element;i++)
4954  {
4955  int eN_i = eN*nDOF_v_test_element+i;
4956  globalResidual.data()[offset_u+stride_u*rvel_l2g.data()[eN_i]]+=elementResidual_u[i];
4957  globalResidual.data()[offset_v+stride_v*rvel_l2g.data()[eN_i]]+=elementResidual_v[i];
4958  globalResidual.data()[offset_w+stride_w*rvel_l2g.data()[eN_i]]+=elementResidual_w[i];
4959  }//i
4960  }//ebNE
4961  if (normalize_pressure)
4962  {
4963  double send[4]={pa_dv,p_dv,total_volume, total_surface_area}, recv[4]={0.,0.,0.,0.};
4964  MPI_Allreduce(send, recv,4,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD);
4965  pa_dv = recv[0];
4966  p_dv = recv[1];
4967  total_volume = recv[2];
4968  total_surface_area = recv[3];
4969  //std::cout<<"Domain Volume: "<<total_volume<<std::endl;
4970  //std::cout<<"Domain Surface Area: "<<total_surface_area<<std::endl;
4971  //cek hack
4972  // 1. This forces the pressure average to match the average of the analytical solution (or zero of no analytical solution is given)
4973  // 2. I'm manually figuring out how many pressure dof there are
4974  /* std::cout<<"mesh volume conservation = "<<mesh_volume_conservation<<std::endl; */
4975  /* std::cout<<"mesh volume conservation weak = "<<mesh_volume_conservation_weak<<std::endl; */
4976  /* std::cout<<"mesh volume conservation err max= "<<mesh_volume_conservation_err_max<<std::endl; */
4977  /* std::cout<<"mesh volume conservation err max weak = "<<mesh_volume_conservation_err_max_weak<<std::endl; */
4978  /* std::cout<<"Pressure Integral "<<p_dv<<std::endl */
4979  /* <<"Analytical Pressure Integral "<<pa_dv<<std::endl */
4980  /* <<"Total Boundary Flux "<<total_flux<<std::endl; */
4981  int nDOF_pressure=0;
4982  for(int eN=0;eN<nElements_global;eN++)
4983  {
4984  for (int i=0;i<nDOF_test_element;i++)
4985  {
4986  int eN_i = eN*nDOF_test_element+i;
4987  if (p_l2g.data()[eN_i] > nDOF_pressure)
4988  nDOF_pressure=p_l2g.data()[eN_i];
4989  }
4990  }
4991  nDOF_pressure +=1;
4992  assert(p_dof.shape(0) == nDOF_pressure);
4993  //std::cout<<"nDOF_pressure "<<nDOF_pressure<<std::endl;
4994  for (int I=0;I<nDOF_pressure;I++)
4995  p_dof.data()[I] += (pa_dv - p_dv)/total_volume;
4996  double p_dv_new=0.0, pa_dv_new=0.0;
4997  p_L1=0.0;
4998  p_L2=0.0;
4999  p_LI=0.0;
5000  for (int eN=0 ; eN < nElements_owned ; ++eN)
5001  {
5002  double element_phi[nDOF_mesh_trial_element], element_phi_s[nDOF_mesh_trial_element];
5003  for (int j=0;j<nDOF_mesh_trial_element;j++)
5004  {
5005  register int eN_j = eN*nDOF_mesh_trial_element+j;
5006  element_phi[j] = phi_nodes.data()[p_l2g.data()[eN_j]];
5007  element_phi_s[j] = phi_solid_nodes.data()[p_l2g.data()[eN_j]];
5008  }
5009  double element_nodes[nDOF_mesh_trial_element*3];
5010  for (int i=0;i<nDOF_mesh_trial_element;i++)
5011  {
5012  register int eN_i=eN*nDOF_mesh_trial_element+i;
5013  for(int I=0;I<3;I++)
5014  element_nodes[i*3 + I] = mesh_dof[mesh_l2g[eN_i]*3 + I];
5015  }//i
5016  int icase_s = gf_s.calculate(element_phi_s, element_nodes, x_ref.data(), false);
5017  for (int k=0 ; k < nQuadraturePoints_element ; ++k)
5018  {
5019  int eN_k = eN*nQuadraturePoints_element + k;
5020  int eN_nDOF_trial_element = eN*nDOF_trial_element;
5021 
5022  double jac[nSpace*nSpace];
5023  double jacInv[nSpace*nSpace];
5024  double p=0.0,pe=0.0;
5025  double jacDet, x, y, z, dV, h_phi;
5026  gf_s.set_quad(k);
5027  double H_s = gf_s.H(0.,0.);
5028  ck.calculateMapping_element(eN,
5029  k,
5030  mesh_dof.data(),
5031  mesh_l2g.data(),
5032  mesh_trial_ref.data(),
5033  mesh_grad_trial_ref.data(),
5034  jac,
5035  jacDet,
5036  jacInv,
5037  x,y,z);
5038  dV = fabs(jacDet)*dV_ref.data()[k];
5039  ck.valFromDOF(p_dof.data(),&p_l2g.data()[eN_nDOF_trial_element],&p_trial_ref.data()[k*nDOF_trial_element],p);
5040  if (isActiveElement[eN])
5041  {
5042  p_dv_new += p*H_s*dV;
5043  pa_dv_new += q_u_0.data()[eN_k]*H_s*dV;
5044  pe = p-q_u_0.data()[eN_k];
5045  p_L1 += fabs(pe)*H_s*dV;
5046  p_L2 += pe*pe*H_s*dV;
5047  if (fabs(pe) > p_LI)
5048  p_LI = fabs(pe);
5049  }
5050  }
5051  }
5052  }
5053  assert(errors.shape(0)*errors.shape(1) == 15);
5054  MPI_Allreduce(MPI_IN_PLACE, errors.data(),(errors.shape(0)-1)*errors.shape(1),MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD);
5055  MPI_Allreduce(MPI_IN_PLACE, errors.data()+(errors.shape(0)-1)*errors.shape(1),1*errors.shape(1),MPI_DOUBLE,MPI_MAX,MPI_COMM_WORLD);
5056  assert(p_L2 >= 0.0);
5057  assert(u_L2 >= 0.0);
5058  assert(v_L2 >= 0.0);
5059  assert(w_L2 >= 0.0);
5060  assert(velocity_L2 >= 0.0);
5061  p_L2 = sqrt(p_L2);
5062  u_L2 = sqrt(u_L2);
5063  v_L2 = sqrt(v_L2);
5064  w_L2 = sqrt(w_L2);
5065  velocity_L2 = sqrt(velocity_L2);
5066  }
5067 
5069  {
5070  double NONCONSERVATIVE_FORM = args.scalar<double>("NONCONSERVATIVE_FORM");
5071  double MOMENTUM_SGE = args.scalar<double>("MOMENTUM_SGE");
5072  double PRESSURE_SGE = args.scalar<double>("PRESSURE_SGE");
5073  double VELOCITY_SGE = args.scalar<double>("VELOCITY_SGE");
5074  double PRESSURE_PROJECTION_STABILIZATION = args.scalar<double>("PRESSURE_PROJECTION_STABILIZATION");
5075  xt::pyarray<double>& mesh_trial_ref = args.array<double>("mesh_trial_ref");
5076  xt::pyarray<double>& mesh_grad_trial_ref = args.array<double>("mesh_grad_trial_ref");
5077  xt::pyarray<double>& mesh_dof = args.array<double>("mesh_dof");
5078  xt::pyarray<double>& mesh_velocity_dof = args.array<double>("mesh_velocity_dof");
5079  double MOVING_DOMAIN = args.scalar<double>("MOVING_DOMAIN");
5080  xt::pyarray<int>& mesh_l2g = args.array<int>("mesh_l2g");
5081  xt::pyarray<double>& x_ref = args.array<double>("x_ref");
5082  xt::pyarray<double>& dV_ref = args.array<double>("dV_ref");
5083  xt::pyarray<double>& p_trial_ref = args.array<double>("p_trial_ref");
5084  xt::pyarray<double>& p_grad_trial_ref = args.array<double>("p_grad_trial_ref");
5085  xt::pyarray<double>& p_test_ref = args.array<double>("p_test_ref");
5086  xt::pyarray<double>& p_grad_test_ref = args.array<double>("p_grad_test_ref");
5087  xt::pyarray<double>& vel_trial_ref = args.array<double>("vel_trial_ref");
5088  xt::pyarray<double>& vel_grad_trial_ref = args.array<double>("vel_grad_trial_ref");
5089  xt::pyarray<double>& vel_test_ref = args.array<double>("vel_test_ref");
5090  xt::pyarray<double>& vel_grad_test_ref = args.array<double>("vel_grad_test_ref");
5091  xt::pyarray<double>& mesh_trial_trace_ref = args.array<double>("mesh_trial_trace_ref");
5092  xt::pyarray<double>& mesh_grad_trial_trace_ref = args.array<double>("mesh_grad_trial_trace_ref");
5093  xt::pyarray<double>& xb_ref = args.array<double>("xb_ref");
5094  xt::pyarray<double>& dS_ref = args.array<double>("dS_ref");
5095  xt::pyarray<double>& p_trial_trace_ref = args.array<double>("p_trial_trace_ref");
5096  xt::pyarray<double>& p_grad_trial_trace_ref = args.array<double>("p_grad_trial_trace_ref");
5097  xt::pyarray<double>& p_test_trace_ref = args.array<double>("p_test_trace_ref");
5098  xt::pyarray<double>& p_grad_test_trace_ref = args.array<double>("p_grad_test_trace_ref");
5099  xt::pyarray<double>& vel_trial_trace_ref = args.array<double>("vel_trial_trace_ref");
5100  xt::pyarray<double>& vel_grad_trial_trace_ref = args.array<double>("vel_grad_trial_trace_ref");
5101  xt::pyarray<double>& vel_test_trace_ref = args.array<double>("vel_test_trace_ref");
5102  xt::pyarray<double>& vel_grad_test_trace_ref = args.array<double>("vel_grad_test_trace_ref");
5103  xt::pyarray<double>& normal_ref = args.array<double>("normal_ref");
5104  xt::pyarray<double>& boundaryJac_ref = args.array<double>("boundaryJac_ref");
5105  double eb_adjoint_sigma = args.scalar<double>("eb_adjoint_sigma");
5106  xt::pyarray<double>& elementDiameter = args.array<double>("elementDiameter");
5107  xt::pyarray<double>& elementBoundaryDiameter = args.array<double>("elementBoundaryDiameter");
5108  xt::pyarray<double>& nodeDiametersArray = args.array<double>("nodeDiametersArray");
5109  double hFactor = args.scalar<double>("hFactor");
5110  int nElements_global = args.scalar<int>("nElements_global");
5111  double useRBLES = args.scalar<double>("useRBLES");
5112  double useMetrics = args.scalar<double>("useMetrics");
5113  double alphaBDF = args.scalar<double>("alphaBDF");
5114  double epsFact_rho = args.scalar<double>("epsFact_rho");
5115  double epsFact_mu = args.scalar<double>("epsFact_mu");
5116  double sigma = args.scalar<double>("sigma");
5117  double rho_0 = args.scalar<double>("rho_0");
5118  double nu_0 = args.scalar<double>("nu_0");
5119  double rho_1 = args.scalar<double>("rho_1");
5120  double nu_1 = args.scalar<double>("nu_1");
5121  double smagorinskyConstant = args.scalar<double>("smagorinskyConstant");
5122  int turbulenceClosureModel = args.scalar<int>("turbulenceClosureModel");
5123  double Ct_sge = args.scalar<double>("Ct_sge");
5124  double Cd_sge = args.scalar<double>("Cd_sge");
5125  double C_dg = args.scalar<double>("C_dg");
5126  double C_b = args.scalar<double>("C_b");
5127  const xt::pyarray<double>& eps_solid = args.array<double>("eps_solid");
5128  const xt::pyarray<double>& phi_solid = args.array<double>("phi_solid");
5129  const xt::pyarray<double>& eps_porous = args.array<double>("eps_porous");
5130  const xt::pyarray<double>& phi_porous = args.array<double>("phi_porous");
5131  const xt::pyarray<double>& q_velocity_porous = args.array<double>("q_velocity_porous");
5132  const xt::pyarray<double>& q_porosity = args.array<double>("q_porosity");
5133  const xt::pyarray<double>& q_dragAlpha = args.array<double>("q_dragAlpha");
5134  const xt::pyarray<double>& q_dragBeta = args.array<double>("q_dragBeta");
5135  const xt::pyarray<double>& q_mass_source = args.array<double>("q_mass_source");
5136  const xt::pyarray<double>& q_turb_var_0 = args.array<double>("q_turb_var_0");
5137  const xt::pyarray<double>& q_turb_var_1 = args.array<double>("q_turb_var_1");
5138  const xt::pyarray<double>& q_turb_var_grad_0 = args.array<double>("q_turb_var_grad_0");
5139  const double LAG_LES = args.scalar<double>("LAG_LES");
5140  xt::pyarray<double> & q_eddy_viscosity_last = args.array<double>("q_eddy_viscosity_last");
5141  xt::pyarray<double> & ebqe_eddy_viscosity_last = args.array<double>("ebqe_eddy_viscosity_last");
5142  xt::pyarray<int>& p_l2g = args.array<int>("p_l2g");
5143  xt::pyarray<int>& vel_l2g = args.array<int>("vel_l2g");
5144  xt::pyarray<double>& p_dof = args.array<double>("p_dof");
5145  xt::pyarray<double>& u_dof = args.array<double>("u_dof");
5146  xt::pyarray<double>& v_dof = args.array<double>("v_dof");
5147  xt::pyarray<double>& w_dof = args.array<double>("w_dof");
5148  xt::pyarray<double>& p_old_dof = args.array<double>("p_old_dof");
5149  xt::pyarray<double>& u_old_dof = args.array<double>("u_old_dof");
5150  xt::pyarray<double>& v_old_dof = args.array<double>("v_old_dof");
5151  xt::pyarray<double>& w_old_dof = args.array<double>("w_old_dof");
5152  xt::pyarray<double>& g = args.array<double>("g");
5153  const double useVF = args.scalar<double>("useVF");
5154  xt::pyarray<double>& vf = args.array<double>("vf");
5155  xt::pyarray<double>& phi = args.array<double>("phi");
5156  xt::pyarray<double>& phi_nodes = args.array<double>("phi_nodes");
5157  xt::pyarray<double>& normal_phi = args.array<double>("normal_phi");
5158  xt::pyarray<double>& kappa_phi = args.array<double>("kappa_phi");
5159  xt::pyarray<double>& q_mom_u_acc_beta_bdf = args.array<double>("q_mom_u_acc_beta_bdf");
5160  xt::pyarray<double>& q_mom_v_acc_beta_bdf = args.array<double>("q_mom_v_acc_beta_bdf");
5161  xt::pyarray<double>& q_mom_w_acc_beta_bdf = args.array<double>("q_mom_w_acc_beta_bdf");
5162  xt::pyarray<double>& q_dV = args.array<double>("q_dV");
5163  xt::pyarray<double>& q_dV_last = args.array<double>("q_dV_last");
5164  xt::pyarray<double>& q_velocity_sge = args.array<double>("q_velocity_sge");
5165  xt::pyarray<double>& q_cfl = args.array<double>("q_cfl");
5166  xt::pyarray<double>& q_numDiff_u_last = args.array<double>("q_numDiff_u_last");
5167  xt::pyarray<double>& q_numDiff_v_last = args.array<double>("q_numDiff_v_last");
5168  xt::pyarray<double>& q_numDiff_w_last = args.array<double>("q_numDiff_w_last");
5169  xt::pyarray<int>& sdInfo_u_u_rowptr = args.array<int>("sdInfo_u_u_rowptr");
5170  xt::pyarray<int>& sdInfo_u_u_colind = args.array<int>("sdInfo_u_u_colind");
5171  xt::pyarray<int>& sdInfo_u_v_rowptr = args.array<int>("sdInfo_u_v_rowptr");
5172  xt::pyarray<int>& sdInfo_u_v_colind = args.array<int>("sdInfo_u_v_colind");
5173  xt::pyarray<int>& sdInfo_u_w_rowptr = args.array<int>("sdInfo_u_w_rowptr");
5174  xt::pyarray<int>& sdInfo_u_w_colind = args.array<int>("sdInfo_u_w_colind");
5175  xt::pyarray<int>& sdInfo_v_v_rowptr = args.array<int>("sdInfo_v_v_rowptr");
5176  xt::pyarray<int>& sdInfo_v_v_colind = args.array<int>("sdInfo_v_v_colind");
5177  xt::pyarray<int>& sdInfo_v_u_rowptr = args.array<int>("sdInfo_v_u_rowptr");
5178  xt::pyarray<int>& sdInfo_v_u_colind = args.array<int>("sdInfo_v_u_colind");
5179  xt::pyarray<int>& sdInfo_v_w_rowptr = args.array<int>("sdInfo_v_w_rowptr");
5180  xt::pyarray<int>& sdInfo_v_w_colind = args.array<int>("sdInfo_v_w_colind");
5181  xt::pyarray<int>& sdInfo_w_w_rowptr = args.array<int>("sdInfo_w_w_rowptr");
5182  xt::pyarray<int>& sdInfo_w_w_colind = args.array<int>("sdInfo_w_w_colind");
5183  xt::pyarray<int>& sdInfo_w_u_rowptr = args.array<int>("sdInfo_w_u_rowptr");
5184  xt::pyarray<int>& sdInfo_w_u_colind = args.array<int>("sdInfo_w_u_colind");
5185  xt::pyarray<int>& sdInfo_w_v_rowptr = args.array<int>("sdInfo_w_v_rowptr");
5186  xt::pyarray<int>& sdInfo_w_v_colind = args.array<int>("sdInfo_w_v_colind");
5187  xt::pyarray<int>& csrRowIndeces_p_p = args.array<int>("csrRowIndeces_p_p");
5188  xt::pyarray<int>& csrColumnOffsets_p_p = args.array<int>("csrColumnOffsets_p_p");
5189  xt::pyarray<int>& csrRowIndeces_p_u = args.array<int>("csrRowIndeces_p_u");
5190  xt::pyarray<int>& csrColumnOffsets_p_u = args.array<int>("csrColumnOffsets_p_u");
5191  xt::pyarray<int>& csrRowIndeces_p_v = args.array<int>("csrRowIndeces_p_v");
5192  xt::pyarray<int>& csrColumnOffsets_p_v = args.array<int>("csrColumnOffsets_p_v");
5193  xt::pyarray<int>& csrRowIndeces_p_w = args.array<int>("csrRowIndeces_p_w");
5194  xt::pyarray<int>& csrColumnOffsets_p_w = args.array<int>("csrColumnOffsets_p_w");
5195  xt::pyarray<int>& csrRowIndeces_u_p = args.array<int>("csrRowIndeces_u_p");
5196  xt::pyarray<int>& csrColumnOffsets_u_p = args.array<int>("csrColumnOffsets_u_p");
5197  xt::pyarray<int>& csrRowIndeces_u_u = args.array<int>("csrRowIndeces_u_u");
5198  xt::pyarray<int>& csrColumnOffsets_u_u = args.array<int>("csrColumnOffsets_u_u");
5199  xt::pyarray<int>& csrRowIndeces_u_v = args.array<int>("csrRowIndeces_u_v");
5200  xt::pyarray<int>& csrColumnOffsets_u_v = args.array<int>("csrColumnOffsets_u_v");
5201  xt::pyarray<int>& csrRowIndeces_u_w = args.array<int>("csrRowIndeces_u_w");
5202  xt::pyarray<int>& csrColumnOffsets_u_w = args.array<int>("csrColumnOffsets_u_w");
5203  xt::pyarray<int>& csrRowIndeces_v_p = args.array<int>("csrRowIndeces_v_p");
5204  xt::pyarray<int>& csrColumnOffsets_v_p = args.array<int>("csrColumnOffsets_v_p");
5205  xt::pyarray<int>& csrRowIndeces_v_u = args.array<int>("csrRowIndeces_v_u");
5206  xt::pyarray<int>& csrColumnOffsets_v_u = args.array<int>("csrColumnOffsets_v_u");
5207  xt::pyarray<int>& csrRowIndeces_v_v = args.array<int>("csrRowIndeces_v_v");
5208  xt::pyarray<int>& csrColumnOffsets_v_v = args.array<int>("csrColumnOffsets_v_v");
5209  xt::pyarray<int>& csrRowIndeces_v_w = args.array<int>("csrRowIndeces_v_w");
5210  xt::pyarray<int>& csrColumnOffsets_v_w = args.array<int>("csrColumnOffsets_v_w");
5211  xt::pyarray<int>& csrRowIndeces_w_p = args.array<int>("csrRowIndeces_w_p");
5212  xt::pyarray<int>& csrColumnOffsets_w_p = args.array<int>("csrColumnOffsets_w_p");
5213  xt::pyarray<int>& csrRowIndeces_w_u = args.array<int>("csrRowIndeces_w_u");
5214  xt::pyarray<int>& csrColumnOffsets_w_u = args.array<int>("csrColumnOffsets_w_u");
5215  xt::pyarray<int>& csrRowIndeces_w_v = args.array<int>("csrRowIndeces_w_v");
5216  xt::pyarray<int>& csrColumnOffsets_w_v = args.array<int>("csrColumnOffsets_w_v");
5217  xt::pyarray<int>& csrRowIndeces_w_w = args.array<int>("csrRowIndeces_w_w");
5218  xt::pyarray<int>& csrColumnOffsets_w_w = args.array<int>("csrColumnOffsets_w_w");
5219  xt::pyarray<double>& globalJacobian = args.array<double>("globalJacobian");
5220  int nExteriorElementBoundaries_global = args.scalar<int>("nExteriorElementBoundaries_global");
5221  xt::pyarray<int>& exteriorElementBoundariesArray = args.array<int>("exteriorElementBoundariesArray");
5222  xt::pyarray<int>& elementBoundaryElementsArray = args.array<int>("elementBoundaryElementsArray");
5223  xt::pyarray<int>& elementBoundaryLocalElementBoundariesArray = args.array<int>("elementBoundaryLocalElementBoundariesArray");
5224  xt::pyarray<double>& ebqe_vf_ext = args.array<double>("ebqe_vf_ext");
5225  xt::pyarray<double>& bc_ebqe_vf_ext = args.array<double>("bc_ebqe_vf_ext");
5226  xt::pyarray<double>& ebqe_phi_ext = args.array<double>("ebqe_phi_ext");
5227  xt::pyarray<double>& bc_ebqe_phi_ext = args.array<double>("bc_ebqe_phi_ext");
5228  xt::pyarray<double>& ebqe_normal_phi_ext = args.array<double>("ebqe_normal_phi_ext");
5229  xt::pyarray<double>& ebqe_kappa_phi_ext = args.array<double>("ebqe_kappa_phi_ext");
5230  const xt::pyarray<double>& ebqe_porosity_ext = args.array<double>("ebqe_porosity_ext");
5231  const xt::pyarray<double>& ebqe_turb_var_0 = args.array<double>("ebqe_turb_var_0");
5232  const xt::pyarray<double>& ebqe_turb_var_1 = args.array<double>("ebqe_turb_var_1");
5233  xt::pyarray<int>& isDOFBoundary_p = args.array<int>("isDOFBoundary_p");
5234  xt::pyarray<int>& isDOFBoundary_u = args.array<int>("isDOFBoundary_u");
5235  xt::pyarray<int>& isDOFBoundary_v = args.array<int>("isDOFBoundary_v");
5236  xt::pyarray<int>& isDOFBoundary_w = args.array<int>("isDOFBoundary_w");
5237  xt::pyarray<int>& isAdvectiveFluxBoundary_p = args.array<int>("isAdvectiveFluxBoundary_p");
5238  xt::pyarray<int>& isAdvectiveFluxBoundary_u = args.array<int>("isAdvectiveFluxBoundary_u");
5239  xt::pyarray<int>& isAdvectiveFluxBoundary_v = args.array<int>("isAdvectiveFluxBoundary_v");
5240  xt::pyarray<int>& isAdvectiveFluxBoundary_w = args.array<int>("isAdvectiveFluxBoundary_w");
5241  xt::pyarray<int>& isDiffusiveFluxBoundary_u = args.array<int>("isDiffusiveFluxBoundary_u");
5242  xt::pyarray<int>& isDiffusiveFluxBoundary_v = args.array<int>("isDiffusiveFluxBoundary_v");
5243  xt::pyarray<int>& isDiffusiveFluxBoundary_w = args.array<int>("isDiffusiveFluxBoundary_w");
5244  xt::pyarray<double>& ebqe_bc_p_ext = args.array<double>("ebqe_bc_p_ext");
5245  xt::pyarray<double>& ebqe_bc_flux_mass_ext = args.array<double>("ebqe_bc_flux_mass_ext");
5246  xt::pyarray<double>& ebqe_bc_flux_mom_u_adv_ext = args.array<double>("ebqe_bc_flux_mom_u_adv_ext");
5247  xt::pyarray<double>& ebqe_bc_flux_mom_v_adv_ext = args.array<double>("ebqe_bc_flux_mom_v_adv_ext");
5248  xt::pyarray<double>& ebqe_bc_flux_mom_w_adv_ext = args.array<double>("ebqe_bc_flux_mom_w_adv_ext");
5249  xt::pyarray<double>& ebqe_bc_u_ext = args.array<double>("ebqe_bc_u_ext");
5250  xt::pyarray<double>& ebqe_bc_flux_u_diff_ext = args.array<double>("ebqe_bc_flux_u_diff_ext");
5251  xt::pyarray<double>& ebqe_penalty_ext = args.array<double>("ebqe_penalty_ext");
5252  xt::pyarray<double>& ebqe_bc_v_ext = args.array<double>("ebqe_bc_v_ext");
5253  xt::pyarray<double>& ebqe_bc_flux_v_diff_ext = args.array<double>("ebqe_bc_flux_v_diff_ext");
5254  xt::pyarray<double>& ebqe_bc_w_ext = args.array<double>("ebqe_bc_w_ext");
5255  xt::pyarray<double>& ebqe_bc_flux_w_diff_ext = args.array<double>("ebqe_bc_flux_w_diff_ext");
5256  xt::pyarray<int>& csrColumnOffsets_eb_p_p = args.array<int>("csrColumnOffsets_eb_p_p");
5257  xt::pyarray<int>& csrColumnOffsets_eb_p_u = args.array<int>("csrColumnOffsets_eb_p_u");
5258  xt::pyarray<int>& csrColumnOffsets_eb_p_v = args.array<int>("csrColumnOffsets_eb_p_v");
5259  xt::pyarray<int>& csrColumnOffsets_eb_p_w = args.array<int>("csrColumnOffsets_eb_p_w");
5260  xt::pyarray<int>& csrColumnOffsets_eb_u_p = args.array<int>("csrColumnOffsets_eb_u_p");
5261  xt::pyarray<int>& csrColumnOffsets_eb_u_u = args.array<int>("csrColumnOffsets_eb_u_u");
5262  xt::pyarray<int>& csrColumnOffsets_eb_u_v = args.array<int>("csrColumnOffsets_eb_u_v");
5263  xt::pyarray<int>& csrColumnOffsets_eb_u_w = args.array<int>("csrColumnOffsets_eb_u_w");
5264  xt::pyarray<int>& csrColumnOffsets_eb_v_p = args.array<int>("csrColumnOffsets_eb_v_p");
5265  xt::pyarray<int>& csrColumnOffsets_eb_v_u = args.array<int>("csrColumnOffsets_eb_v_u");
5266  xt::pyarray<int>& csrColumnOffsets_eb_v_v = args.array<int>("csrColumnOffsets_eb_v_v");
5267  xt::pyarray<int>& csrColumnOffsets_eb_v_w = args.array<int>("csrColumnOffsets_eb_v_w");
5268  xt::pyarray<int>& csrColumnOffsets_eb_w_p = args.array<int>("csrColumnOffsets_eb_w_p");
5269  xt::pyarray<int>& csrColumnOffsets_eb_w_u = args.array<int>("csrColumnOffsets_eb_w_u");
5270  xt::pyarray<int>& csrColumnOffsets_eb_w_v = args.array<int>("csrColumnOffsets_eb_w_v");
5271  xt::pyarray<int>& csrColumnOffsets_eb_w_w = args.array<int>("csrColumnOffsets_eb_w_w");
5272  xt::pyarray<int>& elementFlags = args.array<int>("elementFlags");
5273  xt::pyarray<int>& boundaryFlags = args.array<int>("boundaryFlags");
5274  int use_ball_as_particle = args.scalar<int>("use_ball_as_particle");
5275  xt::pyarray<double>& ball_center = args.array<double>("ball_center");
5276  xt::pyarray<double>& ball_radius = args.array<double>("ball_radius");
5277  xt::pyarray<double>& ball_velocity = args.array<double>("ball_velocity");
5278  xt::pyarray<double>& ball_angular_velocity = args.array<double>("ball_angular_velocity");
5279  xt::pyarray<double>& ball_density = args.array<double>("ball_density");
5280  xt::pyarray<double>& particle_signed_distances = args.array<double>("particle_signed_distances");
5281  xt::pyarray<double>& particle_signed_distance_normals = args.array<double>("particle_signed_distance_normals");
5282  xt::pyarray<double>& particle_velocities = args.array<double>("particle_velocities");
5283  xt::pyarray<double>& particle_centroids = args.array<double>("particle_centroids");
5284  xt::pyarray<double>& ebqe_phi_s = args.array<double>("ebqe_phi_s");
5285  xt::pyarray<double>& ebq_global_grad_phi_s = args.array<double>("ebq_global_grad_phi_s");
5286  xt::pyarray<double>& ebq_particle_velocity_s = args.array<double>("ebq_particle_velocity_s");
5287  xt::pyarray<double>& phi_solid_nodes = args.array<double>("phi_solid_nodes");
5288  xt::pyarray<double>& distance_to_solids = args.array<double>("distance_to_solids");
5289  xt::pyarray<int>& isActiveElement = args.array<int>("isActiveElement");
5290  xt::pyarray<int>& isActiveElement_last = args.array<int>("isActiveElement_last");
5291  int nParticles = args.scalar<int>("nParticles");
5292  int nElements_owned = args.scalar<int>("nElements_owned");
5293  double particle_nitsche = args.scalar<double>("particle_nitsche");
5294  double particle_epsFact = args.scalar<double>("particle_epsFact");
5295  double particle_alpha = args.scalar<double>("particle_alpha");
5296  double particle_beta = args.scalar<double>("particle_beta");
5297  double particle_penalty_constant = args.scalar<double>("particle_penalty_constant");
5298  double ghost_penalty_constant = args.scalar<double>("ghost_penalty_constant");
5299  const bool useExact = args.scalar<int>("useExact");
5300  const int nQuadraturePoints_global(nElements_global*nQuadraturePoints_element);
5301  std::valarray<double> particle_surfaceArea_tmp(nParticles), particle_netForces_tmp(nParticles*3*3), particle_netMoments_tmp(nParticles*3);
5302  gf.useExact = false;//useExact;
5303  gf_p.useExact = false;//useExact;
5304  gf_s.useExact = useExact;
5305  //
5306  //loop over elements to compute volume integrals and load them into the element Jacobians and global Jacobian
5307  //
5308  for(int eN=0;eN<nElements_global;eN++)
5309  {
5310  register int particle_index=0;
5311  register double eps_rho,eps_mu;
5312 
5313  register double elementJacobian_p_p[nDOF_test_element][nDOF_trial_element],
5314  elementJacobian_p_u[nDOF_test_element][nDOF_v_trial_element],
5315  elementJacobian_p_v[nDOF_test_element][nDOF_v_trial_element],
5316  elementJacobian_p_w[nDOF_test_element][nDOF_v_trial_element],
5317  elementJacobian_u_p[nDOF_v_test_element][nDOF_trial_element],
5318  elementJacobian_u_u[nDOF_v_test_element][nDOF_v_trial_element],
5319  elementJacobian_u_v[nDOF_v_test_element][nDOF_v_trial_element],
5320  elementJacobian_u_w[nDOF_v_test_element][nDOF_v_trial_element],
5321  elementJacobian_v_p[nDOF_v_test_element][nDOF_trial_element],
5322  elementJacobian_v_u[nDOF_v_test_element][nDOF_v_trial_element],
5323  elementJacobian_v_v[nDOF_v_test_element][nDOF_v_trial_element],
5324  elementJacobian_v_w[nDOF_v_test_element][nDOF_v_trial_element],
5325  elementJacobian_w_p[nDOF_v_test_element][nDOF_trial_element],
5326  elementJacobian_w_u[nDOF_v_test_element][nDOF_v_trial_element],
5327  elementJacobian_w_v[nDOF_v_test_element][nDOF_v_trial_element],
5328  elementJacobian_w_w[nDOF_v_test_element][nDOF_v_trial_element];
5329  for (int i=0;i<nDOF_test_element;i++)
5330  for (int j=0;j<nDOF_trial_element;j++)
5331  {
5332  elementJacobian_p_p[i][j]=0.0;
5333  }
5334  for (int i=0;i<nDOF_test_element;i++)
5335  for (int j=0;j<nDOF_v_trial_element;j++)
5336  {
5337  elementJacobian_p_u[i][j]=0.0;
5338  elementJacobian_p_v[i][j]=0.0;
5339  elementJacobian_p_w[i][j]=0.0;
5340  elementJacobian_u_p[j][i]=0.0;
5341  elementJacobian_v_p[j][i]=0.0;
5342  elementJacobian_w_p[j][i]=0.0;
5343  }
5344  for (int i=0;i<nDOF_v_test_element;i++)
5345  for (int j=0;j<nDOF_v_trial_element;j++)
5346  {
5347  elementJacobian_u_u[i][j]=0.0;
5348  elementJacobian_u_v[i][j]=0.0;
5349  elementJacobian_u_w[i][j]=0.0;
5350  elementJacobian_v_u[i][j]=0.0;
5351  elementJacobian_v_v[i][j]=0.0;
5352  elementJacobian_v_w[i][j]=0.0;
5353  elementJacobian_w_u[i][j]=0.0;
5354  elementJacobian_w_v[i][j]=0.0;
5355  elementJacobian_w_w[i][j]=0.0;
5356  }
5357  if(use_ball_as_particle==1 && nParticles > 0)
5358  {
5359  double min_d = 1e10;
5360  particle_index=0;
5361  for (int I=0;I<nDOF_mesh_trial_element;I++)
5362  {
5363  int index = get_distance_to_ball(nParticles, ball_center.data(), ball_radius.data(),
5364  mesh_dof.data()[3*mesh_l2g.data()[eN*nDOF_mesh_trial_element+I]+0],
5365  mesh_dof.data()[3*mesh_l2g.data()[eN*nDOF_mesh_trial_element+I]+1],
5366  mesh_dof.data()[3*mesh_l2g.data()[eN*nDOF_mesh_trial_element+I]+2],
5367  phi_solid_nodes.data()[mesh_l2g.data()[eN*nDOF_mesh_trial_element+I]]);
5368  if (phi_solid_nodes.data()[mesh_l2g.data()[eN*nDOF_mesh_trial_element+I]] < min_d)
5369  {
5370  min_d = phi_solid_nodes.data()[mesh_l2g.data()[eN*nDOF_mesh_trial_element+I]];
5371  particle_index = index;
5372  }
5373  }
5374  }
5375  else
5376  {
5377  //phi_solid_nodes is updated in PreStep
5378  }
5379  double element_phi[nDOF_mesh_trial_element], element_phi_s[nDOF_mesh_trial_element];
5380  for (int j=0;j<nDOF_mesh_trial_element;j++)
5381  {
5382  register int eN_j = eN*nDOF_mesh_trial_element+j;
5383  element_phi[j] = phi_nodes.data()[p_l2g.data()[eN_j]];
5384  element_phi_s[j] = phi_solid_nodes.data()[p_l2g.data()[eN_j]];
5385  }
5386  double element_nodes[nDOF_mesh_trial_element*3];
5387  for (int i=0;i<nDOF_mesh_trial_element;i++)
5388  {
5389  register int eN_i=eN*nDOF_mesh_trial_element+i;
5390  for(int I=0;I<3;I++)
5391  element_nodes[i*3 + I] = mesh_dof.data()[mesh_l2g.data()[eN_i]*3 + I];
5392  }//i
5393  int icase_s = gf_s.calculate(element_phi_s, element_nodes, x_ref.data(), false);
5394 #ifdef IFEM
5395  int icase_p = gf_p.calculate(element_phi, element_nodes, x_ref.data(), -rho_1*g.data()[1], -rho_0*g.data()[1],false,true);
5396  int icase = gf.calculate(element_phi, element_nodes, x_ref.data(), rho_1*nu_1, rho_0*nu_0,false,false);
5397 #else
5398  int icase_p = gf_p.calculate(element_phi, element_nodes, x_ref.data(), 1.,1.,false,false);
5399  int icase = gf.calculate(element_phi, element_nodes, x_ref.data(), 1.,1.,false,false);
5400 #endif
5401  for (int fluid_phase=0;fluid_phase < 2 - abs(icase); fluid_phase++)
5402  {
5403  for (int k=0;k<nQuadraturePoints_element;k++)
5404  {
5405  int eN_k = eN*nQuadraturePoints_element+k, //index to a scalar at a quadrature point
5406  eN_k_nSpace = eN_k*nSpace,
5407  eN_k_3d = eN_k*3,
5408  eN_nDOF_trial_element = eN*nDOF_trial_element, //index to a vector at a quadrature point
5409  eN_nDOF_v_trial_element = eN*nDOF_v_trial_element; //index to a vector at a quadrature point
5410 
5411  //declare local storage
5412  register double p=0.0,u=0.0,v=0.0,w=0.0,
5413  grad_p[nSpace]=ZEROVEC,grad_u[nSpace]=ZEROVEC,grad_v[nSpace]=ZEROVEC,grad_w[nSpace]=ZEROVEC,
5414  p_old=0.0,u_old=0.0,v_old=0.0,w_old=0.0,
5415  grad_p_old[nSpace]=ZEROVEC,grad_u_old[nSpace]=ZEROVEC,grad_v_old[nSpace]=ZEROVEC,grad_w_old[nSpace]=ZEROVEC,
5416  mom_u_acc=0.0,
5417  dmom_u_acc_u=0.0,
5418  mom_v_acc=0.0,
5419  dmom_v_acc_v=0.0,
5420  mom_w_acc=0.0,
5421  dmom_w_acc_w=0.0,
5422  mass_adv[nSpace]=ZEROVEC,
5423  dmass_adv_u[nSpace]=ZEROVEC,
5424  dmass_adv_v[nSpace]=ZEROVEC,
5425  dmass_adv_w[nSpace]=ZEROVEC,
5426  mass_ham=0.0,
5427  dmass_ham_u=0.0,
5428  dmass_ham_v=0.0,
5429  dmass_ham_w=0.0,
5430  mom_u_adv[nSpace]=ZEROVEC,
5431  dmom_u_adv_u[nSpace]=ZEROVEC,
5432  dmom_u_adv_v[nSpace]=ZEROVEC,
5433  dmom_u_adv_w[nSpace]=ZEROVEC,
5434  mom_v_adv[nSpace]=ZEROVEC,
5435  dmom_v_adv_u[nSpace]=ZEROVEC,
5436  dmom_v_adv_v[nSpace]=ZEROVEC,
5437  dmom_v_adv_w[nSpace]=ZEROVEC,
5438  mom_w_adv[nSpace]=ZEROVEC,
5439  dmom_w_adv_u[nSpace]=ZEROVEC,
5440  dmom_w_adv_v[nSpace]=ZEROVEC,
5441  dmom_w_adv_w[nSpace]=ZEROVEC,
5442  mom_uu_diff_ten[nSpace]=ZEROVEC,
5443  mom_vv_diff_ten[nSpace]=ZEROVEC,
5444  mom_ww_diff_ten[nSpace]=ZEROVEC,
5445  mom_uv_diff_ten[1],
5446  mom_uw_diff_ten[1],
5447  mom_vu_diff_ten[1],
5448  mom_vw_diff_ten[1],
5449  mom_wu_diff_ten[1],
5450  mom_wv_diff_ten[1],
5451  mom_u_source=0.0,
5452  mom_v_source=0.0,
5453  mom_w_source=0.0,
5454  mom_u_ham=0.0,
5455  dmom_u_ham_grad_p[nSpace]=ZEROVEC,
5456  dmom_u_ham_grad_u[nSpace]=ZEROVEC,
5457  dmom_u_ham_grad_v[nSpace]=ZEROVEC,
5458  dmom_u_ham_grad_w[nSpace]=ZEROVEC,
5459  dmom_u_ham_u=0.0,
5460  dmom_u_ham_v=0.0,
5461  dmom_u_ham_w=0.0,
5462  mom_v_ham=0.0,
5463  dmom_v_ham_grad_p[nSpace]=ZEROVEC,
5464  dmom_v_ham_grad_u[nSpace]=ZEROVEC,
5465  dmom_v_ham_grad_v[nSpace]=ZEROVEC,
5466  dmom_v_ham_grad_w[nSpace]=ZEROVEC,
5467  dmom_v_ham_u=0.0,
5468  dmom_v_ham_v=0.0,
5469  dmom_v_ham_w=0.0,
5470  mom_w_ham=0.0,
5471  dmom_w_ham_grad_p[nSpace]=ZEROVEC,
5472  dmom_w_ham_grad_u[nSpace]=ZEROVEC,
5473  dmom_w_ham_grad_v[nSpace]=ZEROVEC,
5474  dmom_w_ham_grad_w[nSpace]=ZEROVEC,
5475  dmom_w_ham_u=0.0,
5476  dmom_w_ham_v=0.0,
5477  dmom_w_ham_w=0.0,
5478  mom_u_acc_t=0.0,
5479  dmom_u_acc_u_t=0.0,
5480  mom_v_acc_t=0.0,
5481  dmom_v_acc_v_t=0.0,
5482  mom_w_acc_t=0.0,
5483  dmom_w_acc_w_t=0.0,
5484  pdeResidual_p=0.0,
5485  pdeResidual_u=0.0,
5486  pdeResidual_v=0.0,
5487  pdeResidual_w=0.0,
5488  dpdeResidual_p_u[nDOF_v_trial_element],dpdeResidual_p_v[nDOF_v_trial_element],dpdeResidual_p_w[nDOF_v_trial_element],
5489  dpdeResidual_u_p[nDOF_trial_element],dpdeResidual_u_u[nDOF_v_trial_element],
5490  dpdeResidual_v_p[nDOF_trial_element],dpdeResidual_v_v[nDOF_v_trial_element],
5491  dpdeResidual_w_p[nDOF_trial_element],dpdeResidual_w_w[nDOF_v_trial_element],
5492  Lstar_u_p[nDOF_test_element],
5493  Lstar_v_p[nDOF_test_element],
5494  Lstar_w_p[nDOF_test_element],
5495  Lstar_u_u[nDOF_v_test_element],
5496  Lstar_v_v[nDOF_v_test_element],
5497  Lstar_w_w[nDOF_v_test_element],
5498  Lstar_p_u[nDOF_v_test_element],
5499  Lstar_p_v[nDOF_v_test_element],
5500  Lstar_p_w[nDOF_v_test_element],
5501  subgridError_p=0.0,
5502  subgridError_u=0.0,
5503  subgridError_v=0.0,
5504  subgridError_w=0.0,
5505  dsubgridError_p_u[nDOF_v_trial_element],
5506  dsubgridError_p_v[nDOF_v_trial_element],
5507  dsubgridError_p_w[nDOF_v_trial_element],
5508  dsubgridError_u_p[nDOF_trial_element],
5509  dsubgridError_u_u[nDOF_v_trial_element],
5510  dsubgridError_v_p[nDOF_trial_element],
5511  dsubgridError_v_v[nDOF_v_trial_element],
5512  dsubgridError_w_p[nDOF_trial_element],
5513  dsubgridError_w_w[nDOF_v_trial_element],
5514  tau_p=0.0,tau_p0=0.0,tau_p1=0.0,
5515  tau_v=0.0,tau_v0=0.0,tau_v1=0.0,
5516  jac[nSpace*nSpace],
5517  jacDet,
5518  jacInv[nSpace*nSpace],
5519  p_trial[nDOF_trial_element], vel_trial[nDOF_v_trial_element],
5520  p_grad_trial_ib[nDOF_trial_element*nSpace], vel_grad_trial_ib[nDOF_v_trial_element*nSpace],
5521  p_grad_trial[nDOF_trial_element*nSpace],vel_grad_trial[nDOF_v_trial_element*nSpace],
5522  dV,
5523  p_test_dV[nDOF_test_element],vel_test_dV[nDOF_v_test_element],
5524  p_grad_test_dV[nDOF_test_element*nSpace],vel_grad_test_dV[nDOF_v_test_element*nSpace],
5525  x,y,z,xt,yt,zt,
5526  //VRANS
5527  porosity,
5528  //meanGrainSize,
5529  dmom_u_source[nSpace]=ZEROVEC,
5530  dmom_v_source[nSpace]=ZEROVEC,
5531  dmom_w_source[nSpace]=ZEROVEC,
5532  mass_source,
5533  //
5534  G[nSpace*nSpace],G_dd_G,tr_G,h_phi, dmom_adv_star[nSpace]=ZEROVEC, dmom_adv_sge[nSpace]=ZEROVEC, dmom_ham_grad_sge[nSpace]=ZEROVEC,
5535  //embedded solid terms
5536  mass_source_s=0.0,
5537  mom_u_source_s=0.0,
5538  mom_v_source_s=0.0,
5539  mom_w_source_s=0.0,
5540  dmom_u_source_s[nSpace]=ZEROVEC,
5541  dmom_v_source_s[nSpace]=ZEROVEC,
5542  dmom_w_source_s[nSpace]=ZEROVEC,
5543  mom_u_adv_s[nSpace]=ZEROVEC,
5544  mom_v_adv_s[nSpace]=ZEROVEC,
5545  mom_w_adv_s[nSpace]=ZEROVEC,
5546  dmom_u_adv_u_s[nSpace]=ZEROVEC,
5547  dmom_v_adv_v_s[nSpace]=ZEROVEC,
5548  dmom_w_adv_w_s[nSpace]=ZEROVEC,
5549  mom_u_ham_s=0.0,
5550  dmom_u_ham_grad_u_s[nSpace]=ZEROVEC,
5551  dmom_u_ham_grad_v_s[nSpace]=ZEROVEC,
5552  dmom_u_ham_grad_w_s[nSpace]=ZEROVEC,
5553  dmom_u_ham_u_s=0.0,
5554  dmom_u_ham_v_s=0.0,
5555  dmom_u_ham_w_s=0.0,
5556  mom_v_ham_s=0.0,
5557  dmom_v_ham_grad_u_s[nSpace]=ZEROVEC,
5558  dmom_v_ham_grad_v_s[nSpace]=ZEROVEC,
5559  dmom_v_ham_grad_w_s[nSpace]=ZEROVEC,
5560  dmom_v_ham_u_s=0.0,
5561  dmom_v_ham_v_s=0.0,
5562  dmom_v_ham_w_s=0.0,
5563  mom_w_ham_s=0.0,
5564  dmom_w_ham_grad_u_s[nSpace]=ZEROVEC,
5565  dmom_w_ham_grad_v_s[nSpace]=ZEROVEC,
5566  dmom_w_ham_grad_w_s[nSpace]=ZEROVEC,
5567  dmom_w_ham_u_s=0.0,
5568  dmom_w_ham_v_s=0.0,
5569  dmom_w_ham_w_s=0.0,
5570  mass_ham_s=0.0,
5571  dmass_ham_u_s=0.0,
5572  dmass_ham_v_s=0.0,
5573  dmass_ham_w_s=0.0;
5574  //get jacobian, etc for mapping reference element
5575  gf_s.set_quad(k);
5576  gf.set_quad(k);
5577  gf_p.set_quad(k);
5578  ck.calculateMapping_element(eN,
5579  k,
5580  mesh_dof.data(),
5581  mesh_l2g.data(),
5582  mesh_trial_ref.data(),
5583  mesh_grad_trial_ref.data(),
5584  jac,
5585  jacDet,
5586  jacInv,
5587  x,y,z);
5588  ck.calculateH_element(eN,
5589  k,
5590  nodeDiametersArray.data(),
5591  mesh_l2g.data(),
5592  mesh_trial_ref.data(),
5593  h_phi);
5594  ck.calculateMappingVelocity_element(eN,
5595  k,
5596  mesh_velocity_dof.data(),
5597  mesh_l2g.data(),
5598  mesh_trial_ref.data(),
5599  xt,yt,zt);
5600  //xt=0.0;yt=0.0;zt=0.0;
5601  //std::cout<<"xt "<<xt<<'\t'<<yt<<'\t'<<zt<<std::endl;
5602  //get the physical integration weight
5603  dV = fabs(jacDet)*dV_ref.data()[k];
5604  ck.calculateG(jacInv,G,G_dd_G,tr_G);
5605  //ck.calculateGScale(G,&normal_phi[eN_k_nSpace],h_phi);
5606 
5607  eps_rho = epsFact_rho*(useMetrics*h_phi+(1.0-useMetrics)*elementDiameter.data()[eN]);
5608  eps_mu = epsFact_mu *(useMetrics*h_phi+(1.0-useMetrics)*elementDiameter.data()[eN]);
5609  //get the trial function gradients
5610  ck.gradTrialFromRef(&p_grad_trial_ref.data()[k*nDOF_trial_element*nSpace],jacInv,p_grad_trial);
5611  ck_v.gradTrialFromRef(&vel_grad_trial_ref.data()[k*nDOF_v_trial_element*nSpace],jacInv,vel_grad_trial);
5612  for (int i=0; i < nDOF_trial_element; i++)
5613  {
5614  p_trial[i] = p_trial_ref.data()[k*nDOF_trial_element + i];
5615  p_grad_trial_ib[i*nSpace + 0] = p_grad_trial[i*nSpace+0];
5616  p_grad_trial_ib[i*nSpace + 1] = p_grad_trial[i*nSpace+1];
5617  p_grad_trial_ib[i*nSpace + 2] = p_grad_trial[i*nSpace+2];
5618  }
5619  for (int i=0; i < nDOF_v_trial_element; i++)
5620  {
5621  vel_trial[i] = vel_trial_ref.data()[k*nDOF_v_trial_element + i];
5622  vel_grad_trial_ib[i*nSpace + 0] = vel_grad_trial[i*nSpace+0];
5623  vel_grad_trial_ib[i*nSpace + 1] = vel_grad_trial[i*nSpace+1];
5624  vel_grad_trial_ib[i*nSpace + 2] = vel_grad_trial[i*nSpace+2];
5625  }
5626  if (icase == 0)
5627  {
5628 #ifdef IFEMBASIS
5629  for (int i=0; i < nDOF_trial_element; i++)
5630  {
5631  if (fluid_phase == 0)
5632  {
5633  if (not std::isnan(gf_p.VA(i)))
5634  {
5635  p_trial[i] = gf_p.VA(i);
5636  p_grad_trial_ib[i*nSpace + 0] = gf_p.VA_x(i);
5637  p_grad_trial_ib[i*nSpace + 1] = gf_p.VA_y(i);
5638  p_grad_trial_ib[i*nSpace + 2] = gf_p.VA_z(i);
5639  }
5640  }
5641  else
5642  {
5643  if (not std::isnan(gf_p.VB(i)))
5644  {
5645  p_trial[i] = gf_p.VB(i);
5646  p_grad_trial_ib[i*nSpace + 0] = gf_p.VB_x(i);
5647  p_grad_trial_ib[i*nSpace + 1] = gf_p.VB_y(i);
5648  p_grad_trial_ib[i*nSpace + 2] = gf_p.VB_z(i);
5649  }
5650  }
5651  }
5652  if(nDOF_v_trial_element == nDOF_trial_element)
5653  {
5654  for (int vi=0; vi < nDOF_v_trial_element; vi++)
5655  {
5656  if (fluid_phase == 0)
5657  {
5658  if (not std::isnan(gf.VA(vi)))
5659  {
5660  vel_trial[vi] = gf.VA(vi);
5661  vel_grad_trial_ib[vi*nSpace + 0] = gf.VA_x(vi);
5662  vel_grad_trial_ib[vi*nSpace + 1] = gf.VA_y(vi);
5663  vel_grad_trial_ib[vi*nSpace + 2] = gf.VA_z(vi);
5664  }
5665  }
5666  else
5667  {
5668  if (not std::isnan(gf.VB(vi)))
5669  {
5670  vel_trial[vi] = gf.VB(vi);
5671  vel_grad_trial_ib[vi*nSpace + 0] = gf.VB_x(vi);
5672  vel_grad_trial_ib[vi*nSpace + 1] = gf.VB_y(vi);
5673  vel_grad_trial_ib[vi*nSpace + 2] = gf.VB_z(vi);
5674  }
5675  }
5676  }
5677  }
5678 #endif
5679 #ifndef IFEM
5680  bool prob=false;
5681  for (int vi=0; vi < nDOF_v_trial_element; vi++)
5682  {
5683  //pressure
5684  if (fabs(p_trial_ref.data()[k*nDOF_trial_element + vi] - p_trial[vi]) > 1.0e-8)
5685  {
5686  for (int vj=0; vj < nDOF_trial_element; vj++)
5687  std::cout<<"Trial "<<p_trial_ref.data()[k*nDOF_trial_element + vj]<<'\t'<<gf_p.VA(vj)<<'\t'<<gf_p.VB(vj)<<std::endl;
5688  prob=true;
5689  }
5690  if (fabs(p_grad_trial[vi*nSpace + 0] - p_grad_trial_ib[vi*nSpace+0]) > 1.0e-8)
5691  {
5692  for (int vj=0; vj < nDOF_trial_element; vj++)
5693  std::cout<<"Grad Trial x"<<p_grad_trial[vj*nSpace + 0]<<'\t'<<gf_p.VA_x(vj)<<'\t'<<gf_p.VB_x(vj)<<std::endl;
5694  prob=true;
5695  }
5696  if (fabs(p_grad_trial[vi*nSpace + 1] - p_grad_trial_ib[vi*nSpace+1]) > 1.0e-8)
5697  {
5698  for (int vj=0; vj < nDOF_trial_element; vj++)
5699  std::cout<<"Grad Trial y "<<p_grad_trial[vj*nSpace + 1]<<'\t'<<gf_p.VA_y(vj)<<'\t'<<gf_p.VB_y(vj)<<std::endl;
5700  prob=true;
5701  }
5702  if (fabs(p_grad_trial[vi*nSpace + 2] - p_grad_trial_ib[vi*nSpace+2]) > 1.0e-8)
5703  {
5704  for (int vj=0; vj < nDOF_trial_element; vj++)
5705  std::cout<<"Grad Trial z "<<p_grad_trial[vj*nSpace + 2]<<'\t'<<gf_p.VA_z(vj)<<'\t'<<gf_p.VB_z(vj)<<std::endl;
5706  prob=true;
5707  }
5708  //velocity
5709  if (fabs(vel_trial_ref.data()[k*nDOF_v_trial_element + vi] - vel_trial[vi]) > 1.0e-8)
5710  {
5711  for (int vj=0; vj < nDOF_v_trial_element; vj++)
5712  std::cout<<"Trial "<<vel_trial_ref.data()[k*nDOF_v_trial_element + vj]<<'\t'<<gf.VA(vj)<<'\t'<<gf.VB(vj)<<std::endl;
5713  prob=true;
5714  }
5715  if (fabs(vel_grad_trial[vi*nSpace + 0] - vel_grad_trial_ib[vi*nSpace+0]) > 1.0e-8)
5716  {
5717  for (int vj=0; vj < nDOF_v_trial_element; vj++)
5718  std::cout<<"Grad Trial x"<<vel_grad_trial[vj*nSpace + 0]<<'\t'<<gf.VA_x(vj)<<'\t'<<gf.VB_x(vj)<<std::endl;
5719  prob=true;
5720  }
5721  if (fabs(vel_grad_trial[vi*nSpace + 1] - vel_grad_trial_ib[vi*nSpace+1]) > 1.0e-8)
5722  {
5723  for (int vj=0; vj < nDOF_v_trial_element; vj++)
5724  std::cout<<"Grad Trial y "<<vel_grad_trial[vj*nSpace + 1]<<'\t'<<gf.VA_y(vj)<<'\t'<<gf.VB_y(vj)<<std::endl;
5725  prob=true;
5726  }
5727  if (fabs(vel_grad_trial[vi*nSpace + 2] - vel_grad_trial_ib[vi*nSpace+2]) > 1.0e-8)
5728  {
5729  for (int vj=0; vj < nDOF_v_trial_element; vj++)
5730  std::cout<<"Grad Trial z "<<vel_grad_trial[vj*nSpace + 2]<<'\t'<<gf.VA_z(vj)<<'\t'<<gf.VB_z(vj)<<std::endl;
5731  prob=true;
5732  }
5733  if (prob)
5734  break;
5735  }
5736  assert(!prob);
5737 #endif
5738  }
5739  //get the solution
5740  ck.valFromDOF(p_dof.data(),&p_l2g[eN_nDOF_trial_element],p_trial,p);
5741  ck_v.valFromDOF(u_dof.data(),&vel_l2g[eN_nDOF_v_trial_element],vel_trial,u);
5742  ck_v.valFromDOF(v_dof.data(),&vel_l2g[eN_nDOF_v_trial_element],vel_trial,v);
5743  ck_v.valFromDOF(w_dof.data(),&vel_l2g[eN_nDOF_v_trial_element],vel_trial,w);
5744  ck.valFromDOF(p_old_dof.data(),&p_l2g[eN_nDOF_trial_element],p_trial,p_old);
5745  ck_v.valFromDOF(u_old_dof.data(),&vel_l2g[eN_nDOF_v_trial_element],vel_trial,u_old);
5746  ck_v.valFromDOF(v_old_dof.data(),&vel_l2g[eN_nDOF_v_trial_element],vel_trial,v_old);
5747  ck_v.valFromDOF(w_old_dof.data(),&vel_l2g[eN_nDOF_v_trial_element],vel_trial,w_old);
5748  //get the solution gradients
5749  ck.gradFromDOF(p_dof.data(),&p_l2g[eN_nDOF_trial_element],p_grad_trial_ib,grad_p);
5750  ck_v.gradFromDOF(u_dof.data(),&vel_l2g[eN_nDOF_v_trial_element],vel_grad_trial_ib,grad_u);
5751  ck_v.gradFromDOF(v_dof.data(),&vel_l2g[eN_nDOF_v_trial_element],vel_grad_trial_ib,grad_v);
5752  ck_v.gradFromDOF(w_dof.data(),&vel_l2g[eN_nDOF_v_trial_element],vel_grad_trial_ib,grad_w);
5753  ck.gradFromDOF(p_dof.data(),&p_l2g[eN_nDOF_trial_element],p_grad_trial_ib,grad_p_old);
5754  ck_v.gradFromDOF(u_old_dof.data(),&vel_l2g[eN_nDOF_v_trial_element],vel_grad_trial_ib,grad_u_old);
5755  ck_v.gradFromDOF(v_old_dof.data(),&vel_l2g[eN_nDOF_v_trial_element],vel_grad_trial_ib,grad_v_old);
5756  ck_v.gradFromDOF(w_old_dof.data(),&vel_l2g[eN_nDOF_v_trial_element],vel_grad_trial_ib,grad_w_old);
5757  //precalculate test function products with integration weights
5758 #ifdef IFEMGALERKIN
5759  for (int j=0;j<nDOF_test_element;j++)
5760  {
5761  p_test_dV[j] = p_trial[j]*dV;
5762  for (int I=0;I<nSpace;I++)
5763  {
5764  p_grad_test_dV[j*nSpace+I] = p_grad_trial_ib[j*nSpace+I]*dV;
5765  }
5766  }
5767  for (int j=0;j<nDOF_v_test_element;j++)
5768  {
5769  vel_test_dV[j] = vel_trial[j]*dV;
5770  for (int I=0;I<nSpace;I++)
5771  {
5772  vel_grad_test_dV[j*nSpace+I] = vel_grad_trial_ib[j*nSpace+I]*dV;
5773  }
5774  }
5775 #else
5776  for (int j=0;j<nDOF_test_element;j++)
5777  {
5778  p_test_dV[j] = p_test_ref.data()[k*nDOF_trial_element+j]*dV;
5779  for (int I=0;I<nSpace;I++)
5780  {
5781  p_grad_test_dV[j*nSpace+I] = p_grad_trial[j*nSpace+I]*dV;//assume test_j == trial_j, ok for ifem
5782  }
5783  }
5784  for (int j=0;j<nDOF_v_test_element;j++)
5785  {
5786  vel_test_dV[j] = vel_test_ref.data()[k*nDOF_v_trial_element+j]*dV;
5787  for (int I=0;I<nSpace;I++)
5788  {
5789  vel_grad_test_dV[j*nSpace+I] = vel_grad_trial[j*nSpace+I]*dV;//assume test_j == trial_j, ok for ifem
5790  }
5791  }
5792 #endif
5793  //needs to be fixed for higher-order meshes, assuming mesh trial is same as p trial
5794  double div_mesh_velocity=0.0;
5795  for (int j=0;j<nDOF_trial_element;j++)
5796  {
5797  int eN_j=eN*nDOF_trial_element+j;
5798  div_mesh_velocity +=
5799  mesh_velocity_dof.data()[mesh_l2g.data()[eN_j]*3+0]*p_grad_trial[j*nSpace+0] +
5800  mesh_velocity_dof.data()[mesh_l2g.data()[eN_j]*3+1]*p_grad_trial[j*nSpace+1] +
5801  mesh_velocity_dof.data()[mesh_l2g.data()[eN_j]*3+2]*p_grad_trial[j*nSpace+2];
5802  }
5803  div_mesh_velocity = DM3*div_mesh_velocity + (1.0-DM3)*alphaBDF*(dV-q_dV_last.data()[eN_k])/dV;
5804  //
5805  //VRANS
5806  porosity = q_porosity.data()[eN_k];
5807  //
5808  double ball_n[nSpace];
5809  if (use_ball_as_particle == 1 && nParticles > 0)
5810  {
5811  int ball_index=get_distance_to_ball(nParticles, ball_center.data(), ball_radius.data(),x,y,z,distance_to_solids.data()[eN_k]);
5812  get_normal_to_ith_ball(nParticles, ball_center.data(), ball_radius.data(),ball_index,x,y,z,ball_n[0],ball_n[1],ball_n[2]);
5813  }
5814  else
5815  {
5816  //distance_to_solids is given in Prestep
5817  }
5818  //
5819  //calculate pde coefficients and derivatives at quadrature points
5820  //
5821  double eddy_viscosity(0.);//not really interested in saving eddy_viscosity in jacobian
5822  const double particle_eps = particle_epsFact*(useMetrics*h_phi+(1.0-useMetrics)*elementDiameter.data()[eN]);
5823  const double H_s = gf_s.H(particle_eps, phi_solid.data()[eN_k]);
5824  double rho,nu;
5825  if (gf.useExact)
5826  {
5827  if (icase == 0)
5828  {
5829  if (fluid_phase == 0)
5830  {
5831  rho=rho_0;
5832  nu=nu_0;
5833  }
5834  else
5835  {
5836  rho=rho_1;
5837  nu=nu_1;
5838  }
5839  }
5840  else if (icase == -1)
5841  {
5842  rho=rho_0;
5843  nu=nu_0;
5844  }
5845  else if (icase == 1)
5846  {
5847  rho=rho_1;
5848  nu=nu_1;
5849  }
5850  else
5851  assert(false);
5852  }
5853  else
5854  {
5855  double H = (1.0-useVF)*gf.H(eps_rho,phi[eN_k]) + useVF*fmin(1.0,fmax(0.0,vf[eN_k]));
5856  double ImH = (1.0-useVF)*gf.ImH(eps_rho,phi[eN_k]) + useVF*(1.0-fmin(1.0,fmax(0.0,vf[eN_k])));
5857 
5858  rho = rho_0*ImH + rho_1*H;
5859  nu = nu_0*ImH + nu_1*H;
5860  }
5861  evaluateCoefficients(NONCONSERVATIVE_FORM,
5862  sigma,
5863  rho,
5864  nu,
5865  elementDiameter.data()[eN],
5866  smagorinskyConstant,
5867  turbulenceClosureModel,
5868  g.data(),
5869  useVF,
5870  vf.data()[eN_k],
5871  phi.data()[eN_k],
5872  &normal_phi.data()[eN_k_nSpace],
5873  kappa_phi.data()[eN_k],
5874  //VRANS
5875  porosity,
5876  //
5877  phi_solid.data()[eN_k],//updated in get residual
5878  p_old,
5879  u_old,
5880  v_old,
5881  w_old,
5882  grad_p_old,
5883  grad_u_old,
5884  grad_v_old,
5885  grad_w_old,
5886  p,
5887  grad_p,
5888  grad_u,
5889  grad_v,
5890  grad_w,
5891  u,
5892  v,
5893  w,
5894  LAG_LES,
5895  eddy_viscosity,
5896  q_eddy_viscosity_last.data()[eN_k],
5897  mom_u_acc,
5898  dmom_u_acc_u,
5899  mom_v_acc,
5900  dmom_v_acc_v,
5901  mom_w_acc,
5902  dmom_w_acc_w,
5903  mass_adv,
5904  dmass_adv_u,
5905  dmass_adv_v,
5906  dmass_adv_w,
5907  mom_u_adv,
5908  dmom_u_adv_u,
5909  dmom_u_adv_v,
5910  dmom_u_adv_w,
5911  mom_v_adv,
5912  dmom_v_adv_u,
5913  dmom_v_adv_v,
5914  dmom_v_adv_w,
5915  mom_w_adv,
5916  dmom_w_adv_u,
5917  dmom_w_adv_v,
5918  dmom_w_adv_w,
5919  mom_uu_diff_ten,
5920  mom_vv_diff_ten,
5921  mom_ww_diff_ten,
5922  mom_uv_diff_ten,
5923  mom_uw_diff_ten,
5924  mom_vu_diff_ten,
5925  mom_vw_diff_ten,
5926  mom_wu_diff_ten,
5927  mom_wv_diff_ten,
5928  mom_u_source,
5929  mom_v_source,
5930  mom_w_source,
5931  mom_u_ham,
5932  dmom_u_ham_grad_p,
5933  dmom_u_ham_grad_u,
5934  dmom_u_ham_u,
5935  dmom_u_ham_v,
5936  dmom_u_ham_w,
5937  mom_v_ham,
5938  dmom_v_ham_grad_p,
5939  dmom_v_ham_grad_v,
5940  dmom_v_ham_u,
5941  dmom_v_ham_v,
5942  dmom_v_ham_w,
5943  mom_w_ham,
5944  dmom_w_ham_grad_p,
5945  dmom_w_ham_grad_w,
5946  dmom_w_ham_u,
5947  dmom_w_ham_v,
5948  dmom_w_ham_w,
5949  0.0,
5950  0.0,
5951  0.0);
5952  mass_source = q_mass_source.data()[eN_k];
5953  updateDarcyForchheimerTerms_Ergun(NONCONSERVATIVE_FORM,
5954  /* linearDragFactor, */
5955  /* nonlinearDragFactor, */
5956  /* porosity, */
5957  /* meanGrainSize, */
5958  q_dragAlpha.data()[eN_k],
5959  q_dragBeta.data()[eN_k],
5960  eps_rho,
5961  eps_mu,
5962  rho_0,
5963  nu_0,
5964  rho_1,
5965  nu_1,
5966  useVF,
5967  vf.data()[eN_k],
5968  phi.data()[eN_k],
5969  u,
5970  v,
5971  w,
5972  q_velocity_sge.data()[eN_k_nSpace+0],
5973  q_velocity_sge.data()[eN_k_nSpace+1],
5974  q_velocity_sge.data()[eN_k_nSpace+2],
5975  eps_porous.data()[elementFlags.data()[eN]],
5976  phi_porous.data()[eN_k],
5977  q_velocity_porous.data()[eN_k_nSpace+0],
5978  q_velocity_porous.data()[eN_k_nSpace+1],
5979  q_velocity_porous.data()[eN_k_nSpace+2],
5980  mom_u_source,
5981  mom_v_source,
5982  mom_w_source,
5983  dmom_u_source,
5984  dmom_v_source,
5985  dmom_w_source);
5986 
5987  //Turbulence closure model
5988  if (turbulenceClosureModel >= 3)
5989  {
5990  const double c_mu = 0.09;//mwf hack
5991  updateTurbulenceClosure(NONCONSERVATIVE_FORM,
5992  turbulenceClosureModel,
5993  eps_rho,
5994  eps_mu,
5995  rho_0,
5996  nu_0,
5997  rho_1,
5998  nu_1,
5999  useVF,
6000  vf.data()[eN_k],
6001  phi.data()[eN_k],
6002  porosity,
6003  c_mu, //mwf hack
6004  q_turb_var_0.data()[eN_k],
6005  q_turb_var_1.data()[eN_k],
6006  &q_turb_var_grad_0.data()[eN_k_nSpace],
6007  eddy_viscosity,
6008  mom_uu_diff_ten,
6009  mom_vv_diff_ten,
6010  mom_ww_diff_ten,
6011  mom_uv_diff_ten,
6012  mom_uw_diff_ten,
6013  mom_vu_diff_ten,
6014  mom_vw_diff_ten,
6015  mom_wu_diff_ten,
6016  mom_wv_diff_ten,
6017  mom_u_source,
6018  mom_v_source,
6019  mom_w_source);
6020 
6021  }
6022  //
6023  //
6024  //moving mesh
6025  //
6026  if (NONCONSERVATIVE_FORM > 0.0)
6027  {
6028  mom_u_ham -= MOVING_DOMAIN*dmom_u_acc_u*(grad_u[0]*xt + grad_u[1]*yt + grad_u[2]*zt);
6029  dmom_u_ham_grad_u[0] -= MOVING_DOMAIN*dmom_u_acc_u*xt;
6030  dmom_u_ham_grad_u[1] -= MOVING_DOMAIN*dmom_u_acc_u*yt;
6031  dmom_u_ham_grad_u[2] -= MOVING_DOMAIN*dmom_u_acc_u*zt;
6032  }
6033  else
6034  {
6035  mom_u_adv[0] -= MOVING_DOMAIN*mom_u_acc*xt;
6036  mom_u_adv[1] -= MOVING_DOMAIN*mom_u_acc*yt;
6037  mom_u_adv[2] -= MOVING_DOMAIN*mom_u_acc*zt;
6038  dmom_u_adv_u[0] -= MOVING_DOMAIN*dmom_u_acc_u*xt;
6039  dmom_u_adv_u[1] -= MOVING_DOMAIN*dmom_u_acc_u*yt;
6040  dmom_u_adv_u[2] -= MOVING_DOMAIN*dmom_u_acc_u*zt;
6041  }
6042 
6043  if (NONCONSERVATIVE_FORM > 0.0)
6044  {
6045  mom_v_ham -= MOVING_DOMAIN*dmom_v_acc_v*(grad_v[0]*xt + grad_v[1]*yt + grad_v[2]*zt);
6046  dmom_v_ham_grad_v[0] -= MOVING_DOMAIN*dmom_v_acc_v*xt;
6047  dmom_v_ham_grad_v[1] -= MOVING_DOMAIN*dmom_v_acc_v*yt;
6048  dmom_v_ham_grad_v[2] -= MOVING_DOMAIN*dmom_v_acc_v*zt;
6049  }
6050  else
6051  {
6052  mom_v_adv[0] -= MOVING_DOMAIN*mom_v_acc*xt;
6053  mom_v_adv[1] -= MOVING_DOMAIN*mom_v_acc*yt;
6054  mom_v_adv[2] -= MOVING_DOMAIN*mom_v_acc*zt;
6055  dmom_v_adv_v[0] -= MOVING_DOMAIN*dmom_v_acc_v*xt;
6056  dmom_v_adv_v[1] -= MOVING_DOMAIN*dmom_v_acc_v*yt;
6057  dmom_v_adv_v[2] -= MOVING_DOMAIN*dmom_v_acc_v*zt;
6058  }
6059 
6060  if (NONCONSERVATIVE_FORM > 0.0)
6061  {
6062  mom_w_ham -= MOVING_DOMAIN*dmom_w_acc_w*(grad_w[0]*xt + grad_w[1]*yt + grad_w[2]*zt);
6063  dmom_w_ham_grad_w[0] -= MOVING_DOMAIN*dmom_w_acc_w*xt;
6064  dmom_w_ham_grad_w[1] -= MOVING_DOMAIN*dmom_w_acc_w*yt;
6065  dmom_w_ham_grad_w[2] -= MOVING_DOMAIN*dmom_w_acc_w*zt;
6066  }
6067  else
6068  {
6069  mom_w_adv[0] -= MOVING_DOMAIN*mom_w_acc*xt;
6070  mom_w_adv[1] -= MOVING_DOMAIN*mom_w_acc*yt;
6071  mom_w_adv[2] -= MOVING_DOMAIN*mom_w_acc*zt;
6072  dmom_w_adv_w[0] -= MOVING_DOMAIN*dmom_w_acc_w*xt;
6073  dmom_w_adv_w[1] -= MOVING_DOMAIN*dmom_w_acc_w*yt;
6074  dmom_w_adv_w[2] -= MOVING_DOMAIN*dmom_w_acc_w*zt;
6075  }
6076  //
6077  //calculate time derivatives
6078  //
6079  ck.bdf(alphaBDF,
6080  q_mom_u_acc_beta_bdf.data()[eN_k]*q_dV_last.data()[eN_k]/dV,
6081  mom_u_acc,
6082  dmom_u_acc_u,
6083  mom_u_acc_t,
6084  dmom_u_acc_u_t);
6085  ck.bdf(alphaBDF,
6086  q_mom_v_acc_beta_bdf.data()[eN_k]*q_dV_last.data()[eN_k]/dV,
6087  mom_v_acc,
6088  dmom_v_acc_v,
6089  mom_v_acc_t,
6090  dmom_v_acc_v_t);
6091  ck.bdf(alphaBDF,
6092  q_mom_w_acc_beta_bdf.data()[eN_k]*q_dV_last.data()[eN_k]/dV,
6093  mom_w_acc,
6094  dmom_w_acc_w,
6095  mom_w_acc_t,
6096  dmom_w_acc_w_t);
6097  if (NONCONSERVATIVE_FORM > 0.0)
6098  {
6099  mom_u_acc_t *= dmom_u_acc_u;
6100  mom_v_acc_t *= dmom_v_acc_v;
6101  mom_w_acc_t *= dmom_w_acc_w;
6102  }
6103  //
6104  //calculate subgrid error contribution to the Jacobian (strong residual, adjoint, jacobian of strong residual)
6105  //
6106  if (NONCONSERVATIVE_FORM > 0.0)
6107  {
6108  dmom_adv_sge[0] = 0.0;
6109  dmom_adv_sge[1] = 0.0;
6110  dmom_adv_sge[2] = 0.0;
6111  dmom_ham_grad_sge[0] = inertial_term*dmom_u_acc_u*(q_velocity_sge.data()[eN_k_nSpace+0] - MOVING_DOMAIN*xt);
6112  dmom_ham_grad_sge[1] = inertial_term*dmom_u_acc_u*(q_velocity_sge.data()[eN_k_nSpace+1] - MOVING_DOMAIN*yt);
6113  dmom_ham_grad_sge[2] = inertial_term*dmom_u_acc_u*(q_velocity_sge.data()[eN_k_nSpace+2] - MOVING_DOMAIN*zt);
6114  }
6115  else
6116  {
6117  dmom_adv_sge[0] = inertial_term*dmom_u_acc_u*(q_velocity_sge.data()[eN_k_nSpace+0] - MOVING_DOMAIN*xt);
6118  dmom_adv_sge[1] = inertial_term*dmom_u_acc_u*(q_velocity_sge.data()[eN_k_nSpace+1] - MOVING_DOMAIN*yt);
6119  dmom_adv_sge[2] = inertial_term*dmom_u_acc_u*(q_velocity_sge.data()[eN_k_nSpace+2] - MOVING_DOMAIN*zt);
6120  dmom_ham_grad_sge[0] = 0.0;
6121  dmom_ham_grad_sge[1] = 0.0;
6122  dmom_ham_grad_sge[2] = 0.0;
6123  }
6124  double mv_tau[nSpace]=ZEROVEC;
6125  mv_tau[0] = dmom_adv_sge[0] + dmom_ham_grad_sge[0];
6126  mv_tau[1] = dmom_adv_sge[1] + dmom_ham_grad_sge[1];
6127  mv_tau[2] = dmom_adv_sge[2] + dmom_ham_grad_sge[2];
6128  //
6129  //calculate strong residual
6130  //
6131  pdeResidual_p = ck.Advection_strong(dmass_adv_u,grad_u) +
6132  ck.Advection_strong(dmass_adv_v,grad_v) +
6133  ck.Advection_strong(dmass_adv_w,grad_w) +
6134  DM2*MOVING_DOMAIN*ck.Reaction_strong(alphaBDF*(dV-q_dV_last.data()[eN_k])/dV - div_mesh_velocity) +
6135  ck.Reaction_strong(mass_source);
6136 
6137  pdeResidual_u = ck.Mass_strong(mom_u_acc_t) +
6138  ck.Advection_strong(dmom_adv_sge,grad_u) +
6139  ck.Hamiltonian_strong(dmom_ham_grad_sge,grad_u) +
6140  ck.Hamiltonian_strong(dmom_u_ham_grad_p,grad_p) +
6141  ck.Reaction_strong(mom_u_source) -
6142  ck.Reaction_strong(dmom_u_acc_u*u*div_mesh_velocity);
6143 
6144  pdeResidual_v = ck.Mass_strong(mom_v_acc_t) +
6145  ck.Advection_strong(dmom_adv_sge,grad_v) +
6146  ck.Hamiltonian_strong(dmom_ham_grad_sge,grad_v) +
6147  ck.Hamiltonian_strong(dmom_v_ham_grad_p,grad_p) +
6148  ck.Reaction_strong(mom_v_source) -
6149  ck.Reaction_strong(dmom_v_acc_v*v*div_mesh_velocity);
6150 
6151  pdeResidual_w = ck.Mass_strong(mom_w_acc_t) +
6152  ck.Advection_strong(dmom_adv_sge,grad_w) +
6153  ck.Hamiltonian_strong(dmom_ham_grad_sge,grad_w) +
6154  ck.Hamiltonian_strong(dmom_w_ham_grad_p,grad_p) +
6155  ck.Reaction_strong(mom_w_source) -
6156  ck.Reaction_strong(dmom_w_acc_w*w*div_mesh_velocity);
6157 
6158  //calculate the Jacobian of strong residual
6159  for (int j=0;j<nDOF_v_trial_element;j++)
6160  {
6161  register int j_nSpace = j*nSpace;
6162  dpdeResidual_p_u[j]=ck.AdvectionJacobian_strong(dmass_adv_u,&vel_grad_trial_ib[j_nSpace]);
6163  dpdeResidual_p_v[j]=ck.AdvectionJacobian_strong(dmass_adv_v,&vel_grad_trial_ib[j_nSpace]);
6164  dpdeResidual_p_w[j]=ck.AdvectionJacobian_strong(dmass_adv_w,&vel_grad_trial_ib[j_nSpace]);
6165  dpdeResidual_u_u[j]=ck.MassJacobian_strong(dmom_u_acc_u_t,vel_trial[j]) +
6166  ck.HamiltonianJacobian_strong(dmom_ham_grad_sge,&vel_grad_trial_ib[j_nSpace]) +
6167  ck.AdvectionJacobian_strong(dmom_adv_sge,&vel_grad_trial_ib[j_nSpace]) -
6168  ck.ReactionJacobian_strong(dmom_u_acc_u*div_mesh_velocity,vel_trial[j]);
6169  dpdeResidual_v_v[j]=ck.MassJacobian_strong(dmom_v_acc_v_t,vel_trial[j]) +
6170  ck.HamiltonianJacobian_strong(dmom_ham_grad_sge,&vel_grad_trial_ib[j_nSpace]) +
6171  ck.AdvectionJacobian_strong(dmom_adv_sge,&vel_grad_trial_ib[j_nSpace]) -
6172  ck.ReactionJacobian_strong(dmom_v_acc_v*div_mesh_velocity,vel_trial[j]);
6173  dpdeResidual_w_w[j]=ck.MassJacobian_strong(dmom_w_acc_w_t,vel_trial[j]) +
6174  ck.HamiltonianJacobian_strong(dmom_ham_grad_sge,&vel_grad_trial_ib[j_nSpace]) +
6175  ck.AdvectionJacobian_strong(dmom_adv_sge,&vel_grad_trial_ib[j_nSpace]) -
6176  ck.ReactionJacobian_strong(dmom_w_acc_w*div_mesh_velocity,vel_trial[j]);
6177  //VRANS account for drag terms, diagonal only here ... decide if need off diagonal terms too
6178  dpdeResidual_u_u[j]+= ck.ReactionJacobian_strong(dmom_u_source[0],vel_trial[j]);
6179  dpdeResidual_v_v[j]+= ck.ReactionJacobian_strong(dmom_v_source[1],vel_trial[j]);
6180  dpdeResidual_w_w[j]+= ck.ReactionJacobian_strong(dmom_w_source[2],vel_trial[j]);
6181  }
6182  for (int j=0;j<nDOF_trial_element;j++)
6183  {
6184  register int j_nSpace = j*nSpace;
6185  dpdeResidual_u_p[j]=ck.HamiltonianJacobian_strong(dmom_u_ham_grad_p,&p_grad_trial_ib[j_nSpace]);
6186  dpdeResidual_v_p[j]=ck.HamiltonianJacobian_strong(dmom_v_ham_grad_p,&p_grad_trial_ib[j_nSpace]);
6187  dpdeResidual_w_p[j]=ck.HamiltonianJacobian_strong(dmom_w_ham_grad_p,&p_grad_trial_ib[j_nSpace]);
6188  }
6189  //calculate tau and tau*Res
6190  //add contributions from mass and sourced terms
6191  double tmpR=dmom_u_acc_u_t + dmom_u_source[0];
6192  calculateSubgridError_tau(hFactor,
6193  elementDiameter.data()[eN],
6194  tmpR,//dmom_u_acc_u_t,
6195  dmom_u_acc_u,
6196  mv_tau,//dmom_adv_sge,
6197  mom_uu_diff_ten[1],
6198  dmom_u_ham_grad_p[0],
6199  tau_v0,
6200  tau_p0,
6201  q_cfl.data()[eN_k]);
6202 
6203  calculateSubgridError_tau(Ct_sge,Cd_sge,
6204  G,G_dd_G,tr_G,
6205  tmpR,//dmom_u_acc_u_t,
6206  mv_tau,//dmom_adv_sge,
6207  mom_uu_diff_ten[1],
6208  dmom_u_ham_grad_p[0],
6209  tau_v1,
6210  tau_p1,
6211  q_cfl.data()[eN_k]);
6212 
6213  tau_v = useMetrics*tau_v1+(1.0-useMetrics)*tau_v0;
6214  tau_p = useMetrics*tau_p1+(1.0-useMetrics)*tau_p0;
6215 
6217  tau_v,
6218  pdeResidual_p,
6219  pdeResidual_u,
6220  pdeResidual_v,
6221  pdeResidual_w,
6222  subgridError_p,
6223  subgridError_u,
6224  subgridError_v,
6225  subgridError_w);
6226 
6228  tau_v,
6229  dpdeResidual_p_u,
6230  dpdeResidual_p_v,
6231  dpdeResidual_p_w,
6232  dpdeResidual_u_p,
6233  dpdeResidual_u_u,
6234  dpdeResidual_v_p,
6235  dpdeResidual_v_v,
6236  dpdeResidual_w_p,
6237  dpdeResidual_w_w,
6238  dsubgridError_p_u,
6239  dsubgridError_p_v,
6240  dsubgridError_p_w,
6241  dsubgridError_u_p,
6242  dsubgridError_u_u,
6243  dsubgridError_v_p,
6244  dsubgridError_v_v,
6245  dsubgridError_w_p,
6246  dsubgridError_w_w);
6247  // velocity used in adjoint (VMS or RBLES, with or without lagging the grid scale velocity)
6248  dmom_adv_star[0] = inertial_term*dmom_u_acc_u*(q_velocity_sge.data()[eN_k_nSpace+0] - MOVING_DOMAIN*xt + useRBLES*subgridError_u);
6249  dmom_adv_star[1] = inertial_term*dmom_u_acc_u*(q_velocity_sge.data()[eN_k_nSpace+1] - MOVING_DOMAIN*yt + useRBLES*subgridError_v);
6250  dmom_adv_star[2] = inertial_term*dmom_u_acc_u*(q_velocity_sge.data()[eN_k_nSpace+2] - MOVING_DOMAIN*zt + useRBLES*subgridError_w);
6251 
6252  //calculate the adjoint times the test functions
6253  for (int i=0;i<nDOF_test_element;i++)
6254  {
6255  register int i_nSpace = i*nSpace;
6256  Lstar_u_p[i]=ck.Advection_adjoint(dmass_adv_u,&p_grad_test_dV[i_nSpace]);
6257  Lstar_v_p[i]=ck.Advection_adjoint(dmass_adv_v,&p_grad_test_dV[i_nSpace]);
6258  Lstar_w_p[i]=ck.Advection_adjoint(dmass_adv_w,&p_grad_test_dV[i_nSpace]);
6259  }
6260  //calculate the adjoint times the test functions
6261  for (int i=0;i<nDOF_v_test_element;i++)
6262  {
6263  register int i_nSpace = i*nSpace;
6264  Lstar_u_u[i]=ck.Advection_adjoint(dmom_adv_star,&vel_grad_test_dV[i_nSpace]);
6265  Lstar_v_v[i]=ck.Advection_adjoint(dmom_adv_star,&vel_grad_test_dV[i_nSpace]);
6266  Lstar_w_w[i]=ck.Advection_adjoint(dmom_adv_star,&vel_grad_test_dV[i_nSpace]);
6267  Lstar_p_u[i]=ck.Hamiltonian_adjoint(dmom_u_ham_grad_p,&vel_grad_test_dV[i_nSpace]);
6268  Lstar_p_v[i]=ck.Hamiltonian_adjoint(dmom_v_ham_grad_p,&vel_grad_test_dV[i_nSpace]);
6269  Lstar_p_w[i]=ck.Hamiltonian_adjoint(dmom_w_ham_grad_p,&vel_grad_test_dV[i_nSpace]);
6270  //VRANS account for drag terms, diagonal only here ... decide if need off diagonal terms too
6271  Lstar_u_u[i]+=ck.Reaction_adjoint(dmom_u_source[0],vel_test_dV[i]);
6272  Lstar_v_v[i]+=ck.Reaction_adjoint(dmom_v_source[1],vel_test_dV[i]);
6273  Lstar_w_w[i]+=ck.Reaction_adjoint(dmom_w_source[2],vel_test_dV[i]);
6274  }
6275 
6276  // Assumes non-lagged subgrid velocity
6277  dmom_u_adv_u[0] += inertial_term*dmom_u_acc_u*(useRBLES*subgridError_u);
6278  dmom_u_adv_u[1] += inertial_term*dmom_u_acc_u*(useRBLES*subgridError_v);
6279  dmom_u_adv_u[2] += inertial_term*dmom_u_acc_u*(useRBLES*subgridError_w);
6280 
6281  dmom_v_adv_v[0] += inertial_term*dmom_u_acc_u*(useRBLES*subgridError_u);
6282  dmom_v_adv_v[1] += inertial_term*dmom_u_acc_u*(useRBLES*subgridError_v);
6283  dmom_v_adv_v[2] += inertial_term*dmom_u_acc_u*(useRBLES*subgridError_w);
6284 
6285  dmom_w_adv_w[0] += inertial_term*dmom_u_acc_u*(useRBLES*subgridError_u);
6286  dmom_w_adv_w[1] += inertial_term*dmom_u_acc_u*(useRBLES*subgridError_v);
6287  dmom_w_adv_w[2] += inertial_term*dmom_u_acc_u*(useRBLES*subgridError_w);
6288 
6289  if(nParticles > 0)
6290  {
6291  //cek todo, this needs to be fixed for not exact
6292  double level_set_normal[nSpace];
6293  double sign=0.0;
6294  if (gf_s.useExact)
6295  {
6296  double norm_exact=0.0,norm_cut=0.0;
6297  if (use_ball_as_particle)
6298  {
6299  for (int I=0;I<nSpace;I++)
6300  {
6301  sign += ball_n[I]*gf_s.get_normal()[I];
6302  level_set_normal[I] = gf_s.get_normal()[I];
6303  norm_cut += level_set_normal[I]*level_set_normal[I];
6304  norm_exact += ball_n[I]*ball_n[I];
6305  }
6306  }
6307  else
6308  {
6309  for (int I=0;I<nSpace;I++)
6310  {
6311  sign += particle_signed_distance_normals.data()[eN_k_3d+I]*gf_s.get_normal()[I];
6312  level_set_normal[I] = gf_s.get_normal()[I];
6313  norm_cut += level_set_normal[I]*level_set_normal[I];
6314  norm_exact += particle_signed_distance_normals.data()[eN_k_3d+I]*particle_signed_distance_normals.data()[eN_k_3d+I];
6315  }
6316  }
6317  assert(std::fabs(1.0-norm_cut) < 1.0e-8);
6318  assert(std::fabs(1.0-norm_exact) < 1.0e-8);
6319  if (sign < 0.0)
6320  for (int I=0;I<nSpace;I++)
6321  level_set_normal[I]*=-1.0;
6322  /* if(icase_s==0)// && (1.0-sign*sign) > 1.0e-3) */
6323  /* { */
6324  /* std::cout<<"phi normal and cut normal divergent "<<eN<<'\t'<<k<<std::endl; */
6325  /* for (int I=0;I<nSpace;I++) */
6326  /* std::cout<<level_set_normal[I]<<'\t'<<particle_signed_distance_normals[eN_k_3d+I]<<std::endl; */
6327  /* } */
6328  }
6329  else
6330  {
6331  if (use_ball_as_particle)
6332  for (int I=0;I<nSpace;I++)
6333  level_set_normal[I] = ball_n[I];
6334  else
6335  for (int I=0;I<nSpace;I++)
6336  level_set_normal[I] = particle_signed_distance_normals.data()[eN_k_3d+I];
6337  }
6338  updateSolidParticleTerms(particle_index,
6339  NONCONSERVATIVE_FORM,
6340  eN < nElements_owned,
6341  particle_nitsche,
6342  dV,
6343  nParticles,
6344  nQuadraturePoints_global,
6345  &particle_signed_distances.data()[eN_k],
6346  level_set_normal,
6347  &particle_velocities.data()[eN_k_3d],
6348  particle_centroids.data(),
6349  use_ball_as_particle,
6350  ball_center.data(),
6351  ball_radius.data(),
6352  ball_velocity.data(),
6353  ball_angular_velocity.data(),
6354  ball_density.data(),
6355  porosity,
6356  particle_penalty_constant/h_phi,//penalty,
6357  particle_alpha,
6358  particle_beta,
6359  eps_rho,
6360  eps_mu,
6361  rho_0,
6362  nu_0,
6363  rho_1,
6364  nu_1,
6365  useVF,
6366  vf.data()[eN_k],
6367  phi.data()[eN_k],
6368  x,
6369  y,
6370  z,
6371  p,
6372  u,
6373  v,
6374  w,
6375  q_velocity_sge.data()[eN_k_nSpace+0],
6376  q_velocity_sge.data()[eN_k_nSpace+1],
6377  q_velocity_sge.data()[eN_k_nSpace+2],
6378  particle_eps,
6379  grad_u,
6380  grad_v,
6381  grad_w,
6382  mass_source_s,
6383  mom_u_source_s,
6384  mom_v_source_s,
6385  mom_w_source_s,
6386  dmom_u_source_s,
6387  dmom_v_source_s,
6388  dmom_w_source_s,
6389  mom_u_adv_s,
6390  mom_v_adv_s,
6391  mom_w_adv_s,
6392  dmom_u_adv_u_s,
6393  dmom_v_adv_v_s,
6394  dmom_w_adv_w_s,
6395  mom_u_ham_s,
6396  dmom_u_ham_grad_u_s,
6397  dmom_u_ham_grad_v_s,
6398  dmom_u_ham_grad_w_s,
6399  dmom_u_ham_u_s,
6400  dmom_u_ham_v_s,
6401  dmom_u_ham_w_s,
6402  mom_v_ham_s,
6403  dmom_v_ham_grad_u_s,
6404  dmom_v_ham_grad_v_s,
6405  dmom_v_ham_grad_w_s,
6406  dmom_v_ham_u_s,
6407  dmom_v_ham_v_s,
6408  dmom_v_ham_w_s,
6409  mom_w_ham_s,
6410  dmom_w_ham_grad_u_s,
6411  dmom_w_ham_grad_v_s,
6412  dmom_w_ham_grad_w_s,
6413  dmom_w_ham_u_s,
6414  dmom_w_ham_v_s,
6415  dmom_w_ham_w_s,
6416  mass_ham_s,
6417  dmass_ham_u_s,
6418  dmass_ham_v_s,
6419  dmass_ham_w_s,
6420  &particle_netForces_tmp[0],
6421  &particle_netMoments_tmp[0],
6422  &particle_surfaceArea_tmp[0]);
6423  }
6424  //cek todo add RBLES terms consistent to residual modifications or ignore the partials w.r.t the additional RBLES terms
6425  double H_f=1.0;
6426  if (gf.useExact && icase == 0)
6427  {
6428  if (fluid_phase == 0)
6429  H_f = gf.ImH(0.,0.);
6430  else
6431  H_f = gf.H(0.,0.);
6432  }
6433  else
6434  {
6435  assert(fluid_phase == 0);
6436  H_f = 1.0;
6437  }
6438  for(int i=0;i<nDOF_test_element;i++)
6439  {
6440  register int i_nSpace = i*nSpace;
6441  for(int j=0;j<nDOF_trial_element;j++)
6442  {
6443  register int j_nSpace = j*nSpace;
6444  if (nDOF_test_element == nDOF_v_trial_element)
6445  {
6446  elementJacobian_p_p[i][j] += H_s*H_f*((1-PRESSURE_PROJECTION_STABILIZATION)*ck.SubgridErrorJacobian(dsubgridError_u_p[j],Lstar_u_p[i]) +
6447  (1-PRESSURE_PROJECTION_STABILIZATION)*ck.SubgridErrorJacobian(dsubgridError_v_p[j],Lstar_v_p[i]) +
6448  (1-PRESSURE_PROJECTION_STABILIZATION)*ck.SubgridErrorJacobian(dsubgridError_w_p[j],Lstar_w_p[i]) +
6449  PRESSURE_PROJECTION_STABILIZATION*ck.pressureProjection_weak(mom_uu_diff_ten[1], p_trial[j], 1./3., p_test_ref.data()[k*nDOF_test_element +i],dV));
6450  }
6451  }
6452  }
6453  for(int i=0;i<nDOF_test_element;i++)
6454  {
6455  register int i_nSpace = i*nSpace;
6456  for(int j=0;j<nDOF_v_trial_element;j++)
6457  {
6458  register int j_nSpace = j*nSpace;
6459  elementJacobian_p_u[i][j] += H_s*H_f*(ck.AdvectionJacobian_weak(dmass_adv_u,vel_trial[j],&p_grad_test_dV[i_nSpace]) +
6460  ck.MassJacobian_weak(dmass_ham_u,vel_trial[j],p_test_dV[i]));
6461  elementJacobian_p_v[i][j] += H_s*H_f*(ck.AdvectionJacobian_weak(dmass_adv_v,vel_trial[j],&p_grad_test_dV[i_nSpace]) +
6462  ck.MassJacobian_weak(dmass_ham_v,vel_trial[j],p_test_dV[i]));
6463  elementJacobian_p_w[i][j] += H_s*H_f*(ck.AdvectionJacobian_weak(dmass_adv_w,vel_trial[j],&p_grad_test_dV[i_nSpace]) +
6464  ck.MassJacobian_weak(dmass_ham_w,vel_trial[j],p_test_dV[i]));
6465  if (nDOF_test_element == nDOF_v_trial_element)
6466  {
6467  elementJacobian_p_u[i][j] += H_s*H_f*(1-PRESSURE_PROJECTION_STABILIZATION)*ck.SubgridErrorJacobian(dsubgridError_u_u[j],Lstar_u_p[i]);
6468  elementJacobian_p_v[i][j] += H_s*H_f*(1-PRESSURE_PROJECTION_STABILIZATION)*ck.SubgridErrorJacobian(dsubgridError_v_v[j],Lstar_v_p[i]);
6469  elementJacobian_p_w[i][j] += H_s*H_f*(1-PRESSURE_PROJECTION_STABILIZATION)*ck.SubgridErrorJacobian(dsubgridError_w_w[j],Lstar_w_p[i]);
6470  }
6471  }
6472  }
6473  for(int i=0;i<nDOF_v_test_element;i++)
6474  {
6475  register int i_nSpace = i*nSpace;
6476  for(int j=0;j<nDOF_trial_element;j++)
6477  {
6478  register int j_nSpace = j*nSpace;
6479  elementJacobian_u_p[i][j] += H_s*H_f*(ck.HamiltonianJacobian_weak(dmom_u_ham_grad_p,&p_grad_trial_ib[j_nSpace],vel_test_dV[i])+
6480  MOMENTUM_SGE*VELOCITY_SGE*ck.SubgridErrorJacobian(dsubgridError_u_p[j],Lstar_u_u[i]));
6481  elementJacobian_v_p[i][j] += H_s*H_f*(ck.HamiltonianJacobian_weak(dmom_v_ham_grad_p,&p_grad_trial_ib[j_nSpace],vel_test_dV[i])+
6482  MOMENTUM_SGE*VELOCITY_SGE*ck.SubgridErrorJacobian(dsubgridError_v_p[j],Lstar_v_v[i]));
6483  elementJacobian_w_p[i][j] += H_s*H_f*(ck.HamiltonianJacobian_weak(dmom_w_ham_grad_p,&p_grad_trial_ib[j_nSpace],vel_test_dV[i])+
6484  MOMENTUM_SGE*VELOCITY_SGE*ck.SubgridErrorJacobian(dsubgridError_w_p[j],Lstar_w_w[i]));
6485  }
6486  }
6487  for(int i=0;i<nDOF_v_test_element;i++)
6488  {
6489  register int i_nSpace = i*nSpace;
6490  for(int j=0;j<nDOF_v_trial_element;j++)
6491  {
6492  register int j_nSpace = j*nSpace;
6493  elementJacobian_u_u[i][j] += H_s*H_f*(ck.MassJacobian_weak(dmom_u_acc_u_t,vel_trial[j],vel_test_dV[i]) +
6494  ck.MassJacobian_weak(dmom_u_ham_u,vel_trial[j],vel_test_dV[i]) + //cek hack for nonlinear hamiltonian
6495  ck.HamiltonianJacobian_weak(dmom_u_ham_grad_u,&vel_grad_trial_ib[j_nSpace],vel_test_dV[i]) +
6496  ck.AdvectionJacobian_weak(dmom_u_adv_u,vel_trial[j],&vel_grad_test_dV[i_nSpace]) +
6497  ck.SimpleDiffusionJacobian_weak(sdInfo_u_u_rowptr.data(),sdInfo_u_u_colind.data(),mom_uu_diff_ten,&vel_grad_trial_ib[j_nSpace],&vel_grad_test_dV[i_nSpace]) +
6498  ck.ReactionJacobian_weak(dmom_u_source[0]+NONCONSERVATIVE_FORM*dmom_u_acc_u*div_mesh_velocity,vel_trial[j],vel_test_dV[i]) +
6499  MOMENTUM_SGE*PRESSURE_SGE*ck.SubgridErrorJacobian(dsubgridError_p_u[j],Lstar_p_u[i]) +
6500  MOMENTUM_SGE*VELOCITY_SGE*ck.SubgridErrorJacobian(dsubgridError_u_u[j],Lstar_u_u[i]) +
6501  ck.NumericalDiffusionJacobian(q_numDiff_u_last.data()[eN_k],&vel_grad_trial_ib[j_nSpace],&vel_grad_test_dV[i_nSpace]));
6502  elementJacobian_u_v[i][j] += H_s*H_f*(ck.HamiltonianJacobian_weak(dmom_u_ham_grad_v,&vel_grad_trial_ib[j_nSpace],vel_test_dV[i]) +
6503  ck.AdvectionJacobian_weak(dmom_u_adv_v,vel_trial[j],&vel_grad_test_dV[i_nSpace]) +
6504  ck.MassJacobian_weak(dmom_u_ham_v,vel_trial[j],vel_test_dV[i]) + //cek hack for nonlinear hamiltonian
6505  ck.SimpleDiffusionJacobian_weak(sdInfo_u_v_rowptr.data(),sdInfo_u_v_colind.data(),mom_uv_diff_ten,&vel_grad_trial_ib[j_nSpace],&vel_grad_test_dV[i_nSpace]) +
6506  ck.ReactionJacobian_weak(dmom_u_source[1],vel_trial[j],vel_test_dV[i]) +
6507  MOMENTUM_SGE*PRESSURE_SGE*ck.SubgridErrorJacobian(dsubgridError_p_v[j],Lstar_p_u[i]));
6508  elementJacobian_u_w[i][j] += H_s*H_f*(ck.HamiltonianJacobian_weak(dmom_u_ham_grad_w,&vel_grad_trial_ib[j_nSpace],vel_test_dV[i]) +
6509  ck.AdvectionJacobian_weak(dmom_u_adv_w,vel_trial[j],&vel_grad_test_dV[i_nSpace]) +
6510  ck.MassJacobian_weak(dmom_u_ham_w,vel_trial[j],vel_test_dV[i]) + //cek hack for nonlinear hamiltonian
6511  ck.SimpleDiffusionJacobian_weak(sdInfo_u_w_rowptr.data(),sdInfo_u_w_colind.data(),mom_uw_diff_ten,&vel_grad_trial_ib[j_nSpace],&vel_grad_test_dV[i_nSpace]) +
6512  ck.ReactionJacobian_weak(dmom_u_source[2],vel_trial[j],vel_test_dV[i]) +
6513  MOMENTUM_SGE*PRESSURE_SGE*ck.SubgridErrorJacobian(dsubgridError_p_w[j],Lstar_p_u[i]));
6514  elementJacobian_v_u[i][j] += H_s*H_f*(ck.HamiltonianJacobian_weak(dmom_v_ham_grad_u,&vel_grad_trial_ib[j_nSpace],vel_test_dV[i]) +
6515  ck.AdvectionJacobian_weak(dmom_v_adv_u,vel_trial[j],&vel_grad_test_dV[i_nSpace]) +
6516  ck.MassJacobian_weak(dmom_v_ham_u,vel_trial[j],vel_test_dV[i]) + //cek hack for nonlinear hamiltonian
6517  ck.SimpleDiffusionJacobian_weak(sdInfo_v_u_rowptr.data(),sdInfo_v_u_colind.data(),mom_vu_diff_ten,&vel_grad_trial_ib[j_nSpace],&vel_grad_test_dV[i_nSpace]) +
6518  ck.ReactionJacobian_weak(dmom_v_source[0],vel_trial[j],vel_test_dV[i]) +
6519  MOMENTUM_SGE*PRESSURE_SGE*ck.SubgridErrorJacobian(dsubgridError_p_u[j],Lstar_p_v[i]));
6520  elementJacobian_v_v[i][j] += H_s*H_f*(ck.MassJacobian_weak(dmom_v_acc_v_t,vel_trial[j],vel_test_dV[i]) +
6521  ck.MassJacobian_weak(dmom_v_ham_v,vel_trial[j],vel_test_dV[i]) + //cek hack for nonlinear hamiltonian
6522  ck.HamiltonianJacobian_weak(dmom_v_ham_grad_v,&vel_grad_trial_ib[j_nSpace],vel_test_dV[i]) +
6523  ck.AdvectionJacobian_weak(dmom_v_adv_v,vel_trial[j],&vel_grad_test_dV[i_nSpace]) +
6524  ck.SimpleDiffusionJacobian_weak(sdInfo_v_v_rowptr.data(),sdInfo_v_v_colind.data(),mom_vv_diff_ten,&vel_grad_trial_ib[j_nSpace],&vel_grad_test_dV[i_nSpace]) +
6525  ck.ReactionJacobian_weak(dmom_v_source[1]+NONCONSERVATIVE_FORM*dmom_v_acc_v*div_mesh_velocity,vel_trial[j],vel_test_dV[i]) +
6526  MOMENTUM_SGE*PRESSURE_SGE*ck.SubgridErrorJacobian(dsubgridError_p_v[j],Lstar_p_v[i]) +
6527  MOMENTUM_SGE*VELOCITY_SGE*ck.SubgridErrorJacobian(dsubgridError_v_v[j],Lstar_v_v[i]) +
6528  ck.NumericalDiffusionJacobian(q_numDiff_v_last.data()[eN_k],&vel_grad_trial_ib[j_nSpace],&vel_grad_test_dV[i_nSpace]));
6529  elementJacobian_v_w[i][j] += H_s*H_f*(ck.HamiltonianJacobian_weak(dmom_v_ham_grad_w,&vel_grad_trial_ib[j_nSpace],vel_test_dV[i]) +
6530  ck.AdvectionJacobian_weak(dmom_v_adv_w,vel_trial[j],&vel_grad_test_dV[i_nSpace]) +
6531  ck.MassJacobian_weak(dmom_v_ham_w,vel_trial[j],vel_test_dV[i]) + //cek hack for nonlinear hamiltonian
6532  ck.SimpleDiffusionJacobian_weak(sdInfo_v_w_rowptr.data(),sdInfo_v_w_colind.data(),mom_vw_diff_ten,&vel_grad_trial_ib[j_nSpace],&vel_grad_test_dV[i_nSpace]) +
6533  ck.ReactionJacobian_weak(dmom_v_source[2],vel_trial[j],vel_test_dV[i]) +
6534  MOMENTUM_SGE*PRESSURE_SGE*ck.SubgridErrorJacobian(dsubgridError_p_w[j],Lstar_p_v[i]));
6535  elementJacobian_w_u[i][j] += H_s*H_f*(ck.HamiltonianJacobian_weak(dmom_w_ham_grad_u,&vel_grad_trial_ib[j_nSpace],vel_test_dV[i]) +
6536  ck.AdvectionJacobian_weak(dmom_w_adv_u,vel_trial[j],&vel_grad_test_dV[i_nSpace]) +
6537  ck.MassJacobian_weak(dmom_w_ham_u,vel_trial[j],vel_test_dV[i]) + //cek hack for nonlinear hamiltonian
6538  ck.SimpleDiffusionJacobian_weak(sdInfo_w_u_rowptr.data(),sdInfo_w_u_colind.data(),mom_wu_diff_ten,&vel_grad_trial_ib[j_nSpace],&vel_grad_test_dV[i_nSpace]) +
6539  ck.ReactionJacobian_weak(dmom_w_source[0],vel_trial[j],vel_test_dV[i]) +
6540  MOMENTUM_SGE*PRESSURE_SGE*ck.SubgridErrorJacobian(dsubgridError_p_u[j],Lstar_p_w[i]));
6541  elementJacobian_w_v[i][j] += H_s*H_f*(ck.HamiltonianJacobian_weak(dmom_w_ham_grad_v,&vel_grad_trial_ib[j_nSpace],vel_test_dV[i]) +
6542  ck.AdvectionJacobian_weak(dmom_w_adv_v,vel_trial[j],&vel_grad_test_dV[i_nSpace]) +
6543  ck.MassJacobian_weak(dmom_w_ham_v,vel_trial[j],vel_test_dV[i]) + //cek hack for nonlinear hamiltonian
6544  ck.SimpleDiffusionJacobian_weak(sdInfo_w_v_rowptr.data(),sdInfo_w_v_colind.data(),mom_wv_diff_ten,&vel_grad_trial_ib[j_nSpace],&vel_grad_test_dV[i_nSpace]) +
6545  ck.ReactionJacobian_weak(dmom_w_source[1],vel_trial[j],vel_test_dV[i]) +
6546  MOMENTUM_SGE*PRESSURE_SGE*ck.SubgridErrorJacobian(dsubgridError_p_v[j],Lstar_p_w[i]));
6547  elementJacobian_w_w[i][j] += H_s*H_f*(ck.MassJacobian_weak(dmom_w_acc_w_t,vel_trial[j],vel_test_dV[i]) +
6548  ck.MassJacobian_weak(dmom_w_ham_w,vel_trial[j],vel_test_dV[i]) + //cek hack for nonlinear hamiltonian
6549  ck.HamiltonianJacobian_weak(dmom_w_ham_grad_w,&vel_grad_trial_ib[j_nSpace],vel_test_dV[i]) +
6550  ck.AdvectionJacobian_weak(dmom_w_adv_w,vel_trial[j],&vel_grad_test_dV[i_nSpace]) +
6551  ck.SimpleDiffusionJacobian_weak(sdInfo_w_w_rowptr.data(),sdInfo_w_w_colind.data(),mom_ww_diff_ten,&vel_grad_trial_ib[j_nSpace],&vel_grad_test_dV[i_nSpace]) +
6552  ck.ReactionJacobian_weak(dmom_w_source[2]+NONCONSERVATIVE_FORM*dmom_w_acc_w*div_mesh_velocity,vel_trial[j],vel_test_dV[i]) +
6553  MOMENTUM_SGE*PRESSURE_SGE*ck.SubgridErrorJacobian(dsubgridError_p_w[j],Lstar_p_w[i]) +
6554  MOMENTUM_SGE*VELOCITY_SGE*ck.SubgridErrorJacobian(dsubgridError_w_w[j],Lstar_w_w[i]) +
6555  ck.NumericalDiffusionJacobian(q_numDiff_w_last.data()[eN_k],&vel_grad_trial_ib[j_nSpace],&vel_grad_test_dV[i_nSpace]));
6556  }//j
6557  }//i
6558  if (nParticles > 0)
6559  {
6560  for(int i=0;i<nDOF_v_test_element;i++)
6561  {
6562  register int i_nSpace = i*nSpace;
6563  for(int j=0;j<nDOF_v_trial_element;j++)
6564  {
6565  register int j_nSpace = j*nSpace;
6566  elementJacobian_u_u[i][j] += H_f*(ck.MassJacobian_weak(dmom_u_ham_u_s,vel_trial[j],vel_test_dV[i]) +
6567  ck.HamiltonianJacobian_weak(dmom_u_ham_grad_u_s,&vel_grad_trial_ib[j_nSpace],vel_test_dV[i]) +
6568  ck.AdvectionJacobian_weak(dmom_u_adv_u_s,vel_trial[j],&vel_grad_test_dV[i_nSpace]) +
6569  ck.ReactionJacobian_weak(dmom_u_source_s[0],vel_trial[j],vel_test_dV[i]));
6570 
6571  elementJacobian_u_v[i][j] += H_f*(ck.HamiltonianJacobian_weak(dmom_u_ham_grad_v_s,&vel_grad_trial_ib[j_nSpace],vel_test_dV[i]) +
6572  ck.ReactionJacobian_weak(dmom_u_source_s[1],vel_trial[j],vel_test_dV[i]));
6573 
6574  elementJacobian_u_w[i][j] += H_f*(ck.HamiltonianJacobian_weak(dmom_u_ham_grad_w_s,&vel_grad_trial_ib[j_nSpace],vel_test_dV[i]) +
6575  ck.ReactionJacobian_weak(dmom_u_source_s[2],vel_trial[j],vel_test_dV[i]));
6576 
6577  elementJacobian_v_u[i][j] += H_f*(ck.HamiltonianJacobian_weak(dmom_v_ham_grad_u_s,&vel_grad_trial_ib[j_nSpace],vel_test_dV[i]) +
6578  ck.ReactionJacobian_weak(dmom_v_source_s[0],vel_trial[j],vel_test_dV[i]));
6579 
6580  elementJacobian_v_v[i][j] += H_f*(ck.MassJacobian_weak(dmom_v_ham_v_s,vel_trial[j],vel_test_dV[i]) +
6581  ck.HamiltonianJacobian_weak(dmom_v_ham_grad_v_s,&vel_grad_trial_ib[j_nSpace],vel_test_dV[i]) +
6582  ck.AdvectionJacobian_weak(dmom_v_adv_v_s,vel_trial[j],&vel_grad_test_dV[i_nSpace]) +
6583  ck.ReactionJacobian_weak(dmom_v_source_s[1],vel_trial[j],vel_test_dV[i]));
6584 
6585  elementJacobian_v_w[i][j] += H_f*(ck.HamiltonianJacobian_weak(dmom_v_ham_grad_w_s,&vel_grad_trial_ib[j_nSpace],vel_test_dV[i]) +
6586  ck.ReactionJacobian_weak(dmom_v_source_s[2],vel_trial[j],vel_test_dV[i]));
6587 
6588  elementJacobian_w_u[i][j] += H_f*(ck.HamiltonianJacobian_weak(dmom_w_ham_grad_u_s,&vel_grad_trial_ib[j_nSpace],vel_test_dV[i]) +
6589  ck.ReactionJacobian_weak(dmom_w_source_s[0],vel_trial[j],vel_test_dV[i]));
6590 
6591  elementJacobian_w_v[i][j] += H_f*(ck.HamiltonianJacobian_weak(dmom_w_ham_grad_v_s,&vel_grad_trial_ib[j_nSpace],vel_test_dV[i]) +
6592  ck.ReactionJacobian_weak(dmom_w_source_s[1],vel_trial[j],vel_test_dV[i]));
6593 
6594  elementJacobian_w_w[i][j] += H_f*(ck.MassJacobian_weak(dmom_w_ham_w_s,vel_trial[j],vel_test_dV[i]) +
6595  ck.HamiltonianJacobian_weak(dmom_w_ham_grad_w_s,&vel_grad_trial_ib[j_nSpace],vel_test_dV[i]) +
6596  ck.AdvectionJacobian_weak(dmom_w_adv_w_s,vel_trial[j],&vel_grad_test_dV[i_nSpace]) +
6597  ck.ReactionJacobian_weak(dmom_w_source_s[2],vel_trial[j],vel_test_dV[i]));
6598  }//j
6599  }//i
6600  }
6601  }//k
6602  }//fluid_phase
6603  //
6604  //load into element Jacobian into global Jacobian
6605  //
6606  for (int i=0;i<nDOF_test_element;i++)
6607  {
6608  register int eN_i = eN*nDOF_test_element+i;
6609  for (int j=0;j<nDOF_trial_element;j++)
6610  {
6611  register int eN_i_j = eN_i*nDOF_trial_element+j;
6612  globalJacobian.data()[csrRowIndeces_p_p.data()[eN_i] + csrColumnOffsets_p_p.data()[eN_i_j]] += elementJacobian_p_p[i][j];
6613  }
6614  }
6615  for (int i=0;i<nDOF_test_element;i++)
6616  {
6617  register int eN_i = eN*nDOF_test_element+i;
6618  for (int j=0;j<nDOF_v_trial_element;j++)
6619  {
6620  register int eN_i_j = eN_i*nDOF_v_trial_element+j;
6621  globalJacobian.data()[csrRowIndeces_p_u.data()[eN_i] + csrColumnOffsets_p_u.data()[eN_i_j]] += elementJacobian_p_u[i][j];
6622  globalJacobian.data()[csrRowIndeces_p_v.data()[eN_i] + csrColumnOffsets_p_v.data()[eN_i_j]] += elementJacobian_p_v[i][j];
6623  globalJacobian.data()[csrRowIndeces_p_w.data()[eN_i] + csrColumnOffsets_p_w.data()[eN_i_j]] += elementJacobian_p_w[i][j];
6624  }
6625  }
6626  for (int i=0;i<nDOF_v_test_element;i++)
6627  {
6628  register int eN_i = eN*nDOF_v_test_element+i;
6629  for (int j=0;j<nDOF_trial_element;j++)
6630  {
6631  register int eN_i_j = eN_i*nDOF_trial_element+j;
6632  globalJacobian.data()[csrRowIndeces_u_p.data()[eN_i] + csrColumnOffsets_u_p.data()[eN_i_j]] += elementJacobian_u_p[i][j];
6633  globalJacobian.data()[csrRowIndeces_v_p.data()[eN_i] + csrColumnOffsets_v_p.data()[eN_i_j]] += elementJacobian_v_p[i][j];
6634  globalJacobian.data()[csrRowIndeces_w_p.data()[eN_i] + csrColumnOffsets_w_p.data()[eN_i_j]] += elementJacobian_w_p[i][j];
6635  }
6636  }
6637  for (int i=0;i<nDOF_v_test_element;i++)
6638  {
6639  register int eN_i = eN*nDOF_v_test_element+i;
6640  for (int j=0;j<nDOF_v_trial_element;j++)
6641  {
6642  register int eN_i_j = eN_i*nDOF_v_trial_element+j;
6643  globalJacobian.data()[csrRowIndeces_u_u.data()[eN_i] + csrColumnOffsets_u_u.data()[eN_i_j]] += elementJacobian_u_u[i][j];
6644  globalJacobian.data()[csrRowIndeces_u_v.data()[eN_i] + csrColumnOffsets_u_v.data()[eN_i_j]] += elementJacobian_u_v[i][j];
6645  globalJacobian.data()[csrRowIndeces_u_w.data()[eN_i] + csrColumnOffsets_u_w.data()[eN_i_j]] += elementJacobian_u_w[i][j];
6646 
6647  globalJacobian.data()[csrRowIndeces_v_u.data()[eN_i] + csrColumnOffsets_v_u.data()[eN_i_j]] += elementJacobian_v_u[i][j];
6648  globalJacobian.data()[csrRowIndeces_v_v.data()[eN_i] + csrColumnOffsets_v_v.data()[eN_i_j]] += elementJacobian_v_v[i][j];
6649  globalJacobian.data()[csrRowIndeces_v_w.data()[eN_i] + csrColumnOffsets_v_w.data()[eN_i_j]] += elementJacobian_v_w[i][j];
6650 
6651  globalJacobian.data()[csrRowIndeces_w_u.data()[eN_i] + csrColumnOffsets_w_u.data()[eN_i_j]] += elementJacobian_w_u[i][j];
6652  globalJacobian.data()[csrRowIndeces_w_v.data()[eN_i] + csrColumnOffsets_w_v.data()[eN_i_j]] += elementJacobian_w_v[i][j];
6653  globalJacobian.data()[csrRowIndeces_w_w.data()[eN_i] + csrColumnOffsets_w_w.data()[eN_i_j]] += elementJacobian_w_w[i][j];
6654  }//j
6655  }//i
6656  }//elements
6657  std::set<int>::iterator it=cutfem_boundaries.begin();
6658  while(it!=cutfem_boundaries.end())
6659  {
6660  std::map<int,double> DWp_Dn_jump,DW_Dn_jump;
6661  std::map<std::pair<int, int>, int> p_p_nz, u_u_nz, v_v_nz, w_w_nz;
6662  register double gamma_cutfem=ghost_penalty_constant,gamma_cutfem_p=ghost_penalty_constant,h_cutfem=elementBoundaryDiameter.data()[*it];
6663  int eN_nDOF_v_trial_element = elementBoundaryElementsArray.data()[(*it)*2+0]*nDOF_v_trial_element;
6664  //See Massing Schott Wall 2018
6665  //cek todo modify for two-fluids: rho_0 != rho_1
6666  double norm_v=0.0;
6667  for (int i_offset=1;i_offset<nDOF_v_trial_element;i_offset++)//MSW18 is just on face
6668  {
6669  int i = (cutfem_local_boundaries[*it] + i_offset)%nDOF_v_trial_element;//cek hack only works for P1
6670  double u=u_old_dof.data()[vel_l2g.data()[eN_nDOF_v_trial_element+i]],
6671  v=v_old_dof.data()[vel_l2g.data()[eN_nDOF_v_trial_element+i]],
6672  w=w_old_dof.data()[vel_l2g.data()[eN_nDOF_v_trial_element+i]];
6673  norm_v=fmax(norm_v,sqrt(u*u+v*v+w*w));
6674  }
6675  double gamma_v_dim = rho_0*(nu_0 + norm_v*h_cutfem + alphaBDF*h_cutfem*h_cutfem);
6676  gamma_cutfem_p *= h_cutfem*h_cutfem/gamma_v_dim;
6677  if (NONCONSERVATIVE_FORM)
6678  gamma_cutfem*=gamma_v_dim;
6679  else
6680  gamma_cutfem*=(gamma_v_dim/rho_0);
6681  for (int kb=0;kb<nQuadraturePoints_elementBoundary;kb++)
6682  {
6683  register double Dp_Dn_jump=0.0, Du_Dn_jump=0.0, Dv_Dn_jump=0.0, Dw_Dn_jump=0.0,dS;
6684  for (int eN_side=0;eN_side < 2; eN_side++)
6685  {
6686  register int ebN = *it,
6687  eN = elementBoundaryElementsArray.data()[ebN*2+eN_side];
6688  for (int i=0;i<nDOF_test_element;i++)
6689  DWp_Dn_jump[p_l2g.data()[eN*nDOF_test_element+i]] = 0.0;
6690  for (int i=0;i<nDOF_v_test_element;i++)
6691  DW_Dn_jump[vel_l2g.data()[eN*nDOF_v_test_element+i]] = 0.0;
6692  }
6693  for (int eN_side=0;eN_side < 2; eN_side++)
6694  {
6695  register int ebN = *it,
6696  eN = elementBoundaryElementsArray.data()[ebN*2+eN_side],
6697  ebN_local = elementBoundaryLocalElementBoundariesArray.data()[ebN*2+eN_side],
6698  eN_nDOF_trial_element = eN*nDOF_trial_element,
6699  eN_nDOF_v_trial_element = eN*nDOF_v_trial_element,
6700  ebN_local_kb = ebN_local*nQuadraturePoints_elementBoundary+kb,
6701  ebN_local_kb_nSpace = ebN_local_kb*nSpace;
6702  register double p_int=0.0,
6703  u_int=0.0,
6704  v_int=0.0,
6705  w_int=0.0,
6706  grad_p_int[nSpace]=ZEROVEC,
6707  grad_u_int[nSpace]=ZEROVEC,
6708  grad_v_int[nSpace]=ZEROVEC,
6709  grad_w_int[nSpace]=ZEROVEC,
6710  jac_int[nSpace*nSpace],
6711  jacDet_int,
6712  jacInv_int[nSpace*nSpace],
6713  boundaryJac[nSpace*(nSpace-1)],
6714  metricTensor[(nSpace-1)*(nSpace-1)],
6715  metricTensorDetSqrt,
6716  p_test_dS[nDOF_test_element],vel_test_dS[nDOF_v_test_element],
6717  p_grad_trial_trace[nDOF_trial_element*nSpace],vel_grad_trial_trace[nDOF_v_trial_element*nSpace],
6718  p_grad_test_dS[nDOF_trial_element*nSpace],vel_grad_test_dS[nDOF_v_trial_element*nSpace],
6719  normal[nSpace],x_int,y_int,z_int,xt_int,yt_int,zt_int,integralScaling,
6720  G[nSpace*nSpace],G_dd_G,tr_G,h_phi,h_penalty,penalty,
6721  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;
6722  //compute information about mapping from reference element to physical element
6723  ck.calculateMapping_elementBoundary(eN,
6724  ebN_local,
6725  kb,
6726  ebN_local_kb,
6727  mesh_dof.data(),
6728  mesh_l2g.data(),
6729  mesh_trial_trace_ref.data(),
6730  mesh_grad_trial_trace_ref.data(),
6731  boundaryJac_ref.data(),
6732  jac_int,
6733  jacDet_int,
6734  jacInv_int,
6735  boundaryJac,
6736  metricTensor,
6737  metricTensorDetSqrt,
6738  normal_ref.data(),
6739  normal,
6740  x_int,y_int,z_int);
6741  //todo: check that physical coordinates match
6742  ck.calculateMappingVelocity_elementBoundary(eN,
6743  ebN_local,
6744  kb,
6745  ebN_local_kb,
6746  mesh_velocity_dof.data(),
6747  mesh_l2g.data(),
6748  mesh_trial_trace_ref.data(),
6749  xt_int,yt_int,zt_int,
6750  normal,
6751  boundaryJac,
6752  metricTensor,
6753  integralScaling);
6754  dS = metricTensorDetSqrt*dS_ref.data()[kb];
6755  //compute shape and solution information
6756  //shape
6757  ck.gradTrialFromRef(&p_grad_trial_trace_ref.data()[ebN_local_kb_nSpace*nDOF_trial_element],jacInv_int,p_grad_trial_trace);
6758  ck_v.gradTrialFromRef(&vel_grad_trial_trace_ref.data()[ebN_local_kb_nSpace*nDOF_v_trial_element],jacInv_int,vel_grad_trial_trace);
6759  for (int i=0;i<nDOF_test_element;i++)
6760  {
6761  int eN_i = eN*nDOF_test_element + i;
6762  for (int I=0;I<nSpace;I++)
6763  DWp_Dn_jump[p_l2g.data()[eN_i]] += p_grad_trial_trace[i*nSpace+I]*normal[I];
6764  }
6765  for (int i=0;i<nDOF_v_test_element;i++)
6766  {
6767  int eN_i = eN*nDOF_v_test_element + i;
6768  for (int I=0;I<nSpace;I++)
6769  DW_Dn_jump[vel_l2g.data()[eN_i]] += vel_grad_trial_trace[i*nSpace+I]*normal[I];
6770  }
6771  }//eN_side
6772  for (int eN_side=0;eN_side < 2; eN_side++)
6773  {
6774  register int ebN = *it,
6775  eN = elementBoundaryElementsArray.data()[ebN*2+eN_side];
6776  for (int i=0;i<nDOF_test_element;i++)
6777  {
6778  register int eN_i = eN*nDOF_test_element+i;
6779  for (int eN_side2=0;eN_side2 < 2; eN_side2++)
6780  {
6781  register int eN2 = elementBoundaryElementsArray.data()[ebN*2+eN_side2];
6782  for (int j=0;j<nDOF_test_element;j++)
6783  {
6784  int eN_i_j = eN_i*nDOF_test_element + j;
6785  int eN2_j = eN2*nDOF_test_element + j;
6786  register int ebN_i_j = ebN*4*nDOF_test_X_trial_element +
6787  eN_side*2*nDOF_test_X_trial_element +
6788  eN_side2*nDOF_test_X_trial_element +
6789  i*nDOF_trial_element +
6790  j;
6791  std::pair<int,int> ij = std::make_pair(p_l2g.data()[eN_i], p_l2g.data()[eN2_j]);
6792  if (p_p_nz.count(ij))
6793  {
6794  assert(p_p_nz[ij] == csrRowIndeces_p_p.data()[eN_i] + csrColumnOffsets_eb_p_p.data()[ebN_i_j]);
6795  }
6796  else
6797  p_p_nz[ij] = csrRowIndeces_p_p.data()[eN_i] + csrColumnOffsets_eb_p_p.data()[ebN_i_j];
6798  }
6799  }
6800  }
6801  for (int i=0;i<nDOF_v_test_element;i++)
6802  {
6803  register int eN_i = eN*nDOF_v_test_element+i;
6804  for (int eN_side2=0;eN_side2 < 2; eN_side2++)
6805  {
6806  register int eN2 = elementBoundaryElementsArray.data()[ebN*2+eN_side2];
6807  for (int j=0;j<nDOF_v_test_element;j++)
6808  {
6809  int eN_i_j = eN_i*nDOF_v_test_element + j;
6810  int eN2_j = eN2*nDOF_v_test_element + j;
6811  register int ebN_i_j = ebN*4*nDOF_v_test_X_v_trial_element +
6812  eN_side*2*nDOF_v_test_X_v_trial_element +
6814  i*nDOF_v_trial_element +
6815  j;
6816  std::pair<int,int> ij = std::make_pair(vel_l2g.data()[eN_i], vel_l2g.data()[eN2_j]);
6817  if (u_u_nz.count(ij))
6818  {
6819  assert(u_u_nz[ij] == csrRowIndeces_u_u.data()[eN_i] + csrColumnOffsets_eb_u_u.data()[ebN_i_j]);
6820  }
6821  else
6822  u_u_nz[ij] = csrRowIndeces_u_u.data()[eN_i] + csrColumnOffsets_eb_u_u.data()[ebN_i_j];
6823  if (v_v_nz.count(ij))
6824  {
6825  assert(v_v_nz[ij] == csrRowIndeces_v_v.data()[eN_i] + csrColumnOffsets_eb_v_v.data()[ebN_i_j]);
6826  }
6827  else
6828  v_v_nz[ij] = csrRowIndeces_v_v.data()[eN_i] + csrColumnOffsets_eb_v_v.data()[ebN_i_j];
6829  if (w_w_nz.count(ij))
6830  {
6831  assert(w_w_nz[ij] == csrRowIndeces_w_w.data()[eN_i] + csrColumnOffsets_eb_w_w.data()[ebN_i_j]);
6832  }
6833  else
6834  w_w_nz[ij] = csrRowIndeces_w_w.data()[eN_i] + csrColumnOffsets_eb_w_w.data()[ebN_i_j];
6835  }
6836  }
6837  }
6838  }
6839  for (std::map<int,double>::iterator Wi_it=DWp_Dn_jump.begin(); Wi_it!=DWp_Dn_jump.end(); ++Wi_it)
6840  for (std::map<int,double>::iterator Wj_it=DWp_Dn_jump.begin(); Wj_it!=DWp_Dn_jump.end(); ++Wj_it)
6841  {
6842  int i_global = Wi_it->first,
6843  j_global = Wj_it->first;
6844  double DWp_Dn_jump_i = Wi_it->second,
6845  DWp_Dn_jump_j = Wj_it->second;
6846  std::pair<int,int> ij = std::make_pair(i_global, j_global);
6847  globalJacobian.data()[p_p_nz.at(ij)] += gamma_cutfem_p*h_cutfem*DWp_Dn_jump_j*DWp_Dn_jump_i*dS;
6848  }//i,j
6849  for (std::map<int,double>::iterator Wi_it=DW_Dn_jump.begin(); Wi_it!=DW_Dn_jump.end(); ++Wi_it)
6850  for (std::map<int,double>::iterator Wj_it=DW_Dn_jump.begin(); Wj_it!=DW_Dn_jump.end(); ++Wj_it)
6851  {
6852  int i_global = Wi_it->first,
6853  j_global = Wj_it->first;
6854  double DW_Dn_jump_i = Wi_it->second,
6855  DW_Dn_jump_j = Wj_it->second;
6856  std::pair<int,int> ij = std::make_pair(i_global, j_global);
6857  globalJacobian.data()[u_u_nz.at(ij)] += gamma_cutfem*h_cutfem*DW_Dn_jump_j*DW_Dn_jump_i*dS;
6858  globalJacobian.data()[v_v_nz.at(ij)] += gamma_cutfem*h_cutfem*DW_Dn_jump_j*DW_Dn_jump_i*dS;
6859  globalJacobian.data()[w_w_nz.at(ij)] += gamma_cutfem*h_cutfem*DW_Dn_jump_j*DW_Dn_jump_i*dS;
6860  }//i,j
6861  }//kb
6862  it++;
6863  }//cutfem element boundaries
6864  //
6865  //loop over exterior element boundaries to compute the surface integrals and load them into the global Jacobian
6866  //
6867  for (int ebNE = 0; ebNE < nExteriorElementBoundaries_global; ebNE++)
6868  {
6869  register int ebN = exteriorElementBoundariesArray.data()[ebNE],
6870  eN = elementBoundaryElementsArray.data()[ebN*2+0],
6871  eN_nDOF_trial_element = eN*nDOF_trial_element,
6872  eN_nDOF_v_trial_element = eN*nDOF_v_trial_element,
6873  ebN_local = elementBoundaryLocalElementBoundariesArray.data()[ebN*2+0];
6874  if (boundaryFlags[ebN] < 1)
6875  continue;
6876  register double eps_rho,eps_mu;
6877  double element_phi[nDOF_mesh_trial_element], element_phi_s[nDOF_mesh_trial_element];
6878  for (int j=0;j<nDOF_mesh_trial_element;j++)
6879  {
6880  register int eN_j = eN*nDOF_mesh_trial_element+j;
6881  element_phi[j] = phi_nodes.data()[p_l2g.data()[eN_j]];
6882  element_phi_s[j] = phi_solid_nodes.data()[p_l2g.data()[eN_j]];
6883  }
6884  double element_nodes[nDOF_mesh_trial_element*3];
6885  for (int i=0;i<nDOF_mesh_trial_element;i++)
6886  {
6887  register int eN_i=eN*nDOF_mesh_trial_element+i;
6888  for(int I=0;I<3;I++)
6889  element_nodes[i*3 + I] = mesh_dof[mesh_l2g.data()[eN_i]*3 + I];
6890  }//i
6891  double mesh_dof_ref[nDOF_mesh_trial_element*3]={0.,0.,0.,1.,0.,0.,0.,1.,0.,0.,0.,1.};
6892  double xb_ref_calc[nQuadraturePoints_elementBoundary*3];
6893  for (int kb=0;kb<nQuadraturePoints_elementBoundary;kb++)
6894  {
6895  double x=0.0,y=0.0,z=0.0;
6896  for (int j=0;j<nDOF_mesh_trial_element;j++)
6897  {
6898  int ebN_local_kb = ebN_local*nQuadraturePoints_elementBoundary+kb;
6899  int ebN_local_kb_j = ebN_local_kb*nDOF_mesh_trial_element+j;
6900  x += mesh_dof_ref[j*3+0]*mesh_trial_trace_ref.data()[ebN_local_kb_j];
6901  y += mesh_dof_ref[j*3+1]*mesh_trial_trace_ref.data()[ebN_local_kb_j];
6902  z += mesh_dof_ref[j*3+2]*mesh_trial_trace_ref.data()[ebN_local_kb_j];
6903  }
6904  xb_ref_calc[3*kb+0] = x;
6905  xb_ref_calc[3*kb+1] = y;
6906  xb_ref_calc[3*kb+2] = z;
6907  }
6908  int icase_s = gf_s.calculate(element_phi_s, element_nodes, xb_ref_calc,true);
6909 #ifdef IFEM
6910  int icase = gf.calculate(element_phi, element_nodes, xb_ref.data(), rho_1*nu_1, rho_0*nu_0,true,false);
6911 #else
6912  int icase = gf.calculate(element_phi, element_nodes, xb_ref.data(), 1.0,1.0,true, false);
6913 #endif
6914  for (int kb=0;kb<nQuadraturePoints_elementBoundary;kb++)
6915  {
6916  register int ebNE_kb = ebNE*nQuadraturePoints_elementBoundary+kb,
6917  ebNE_kb_nSpace = ebNE_kb*nSpace,
6918  ebN_local_kb = ebN_local*nQuadraturePoints_elementBoundary+kb,
6919  ebN_local_kb_nSpace = ebN_local_kb*nSpace;
6920 
6921  register double phi_s_ext=0.0,
6922  p_ext=0.0,
6923  u_ext=0.0,
6924  v_ext=0.0,
6925  w_ext=0.0,
6926  grad_p_ext[nSpace]=ZEROVEC,
6927  grad_u_ext[nSpace]=ZEROVEC,
6928  grad_v_ext[nSpace]=ZEROVEC,
6929  grad_w_ext[nSpace]=ZEROVEC,
6930  p_old=0.0,u_old=0.0,v_old=0.0,w_old=0.0,
6931  grad_p_old[nSpace]=ZEROVEC,grad_u_old[nSpace]=ZEROVEC,grad_v_old[nSpace]=ZEROVEC,grad_w_old[nSpace]=ZEROVEC,
6932  mom_u_acc_ext=0.0,
6933  dmom_u_acc_u_ext=0.0,
6934  mom_v_acc_ext=0.0,
6935  dmom_v_acc_v_ext=0.0,
6936  mom_w_acc_ext=0.0,
6937  dmom_w_acc_w_ext=0.0,
6938  mass_adv_ext[nSpace]=ZEROVEC,
6939  dmass_adv_u_ext[nSpace]=ZEROVEC,
6940  dmass_adv_v_ext[nSpace]=ZEROVEC,
6941  dmass_adv_w_ext[nSpace]=ZEROVEC,
6942  mom_u_adv_ext[nSpace]=ZEROVEC,
6943  dmom_u_adv_u_ext[nSpace]=ZEROVEC,
6944  dmom_u_adv_v_ext[nSpace]=ZEROVEC,
6945  dmom_u_adv_w_ext[nSpace]=ZEROVEC,
6946  mom_v_adv_ext[nSpace]=ZEROVEC,
6947  dmom_v_adv_u_ext[nSpace]=ZEROVEC,
6948  dmom_v_adv_v_ext[nSpace]=ZEROVEC,
6949  dmom_v_adv_w_ext[nSpace]=ZEROVEC,
6950  mom_w_adv_ext[nSpace]=ZEROVEC,
6951  dmom_w_adv_u_ext[nSpace]=ZEROVEC,
6952  dmom_w_adv_v_ext[nSpace]=ZEROVEC,
6953  dmom_w_adv_w_ext[nSpace]=ZEROVEC,
6954  mom_uu_diff_ten_ext[nSpace]=ZEROVEC,
6955  mom_vv_diff_ten_ext[nSpace]=ZEROVEC,
6956  mom_ww_diff_ten_ext[nSpace]=ZEROVEC,
6957  mom_uv_diff_ten_ext[1],
6958  mom_uw_diff_ten_ext[1],
6959  mom_vu_diff_ten_ext[1],
6960  mom_vw_diff_ten_ext[1],
6961  mom_wu_diff_ten_ext[1],
6962  mom_wv_diff_ten_ext[1],
6963  mom_u_source_ext=0.0,
6964  mom_v_source_ext=0.0,
6965  mom_w_source_ext=0.0,
6966  mom_u_ham_ext=0.0,
6967  dmom_u_ham_grad_p_ext[nSpace]=ZEROVEC,
6968  dmom_u_ham_grad_u_ext[nSpace]=ZEROVEC,
6969  dmom_u_ham_u_ext=0.0,
6970  dmom_u_ham_v_ext=0.0,
6971  dmom_u_ham_w_ext=0.0,
6972  mom_v_ham_ext=0.0,
6973  dmom_v_ham_grad_p_ext[nSpace]=ZEROVEC,
6974  dmom_v_ham_grad_v_ext[nSpace]=ZEROVEC,
6975  dmom_v_ham_u_ext=0.0,
6976  dmom_v_ham_v_ext=0.0,
6977  dmom_v_ham_w_ext=0.0,
6978  mom_w_ham_ext=0.0,
6979  dmom_w_ham_grad_p_ext[nSpace]=ZEROVEC,
6980  dmom_w_ham_grad_w_ext[nSpace]=ZEROVEC,
6981  dmom_w_ham_u_ext=0.0,
6982  dmom_w_ham_v_ext=0.0,
6983  dmom_w_ham_w_ext=0.0,
6984  dmom_u_adv_p_ext[nSpace]=ZEROVEC,
6985  dmom_v_adv_p_ext[nSpace]=ZEROVEC,
6986  dmom_w_adv_p_ext[nSpace]=ZEROVEC,
6987  dflux_mass_u_ext=0.0,
6988  dflux_mass_v_ext=0.0,
6989  dflux_mass_w_ext=0.0,
6990  dflux_mom_u_adv_p_ext=0.0,
6991  dflux_mom_u_adv_u_ext=0.0,
6992  dflux_mom_u_adv_v_ext=0.0,
6993  dflux_mom_u_adv_w_ext=0.0,
6994  dflux_mom_v_adv_p_ext=0.0,
6995  dflux_mom_v_adv_u_ext=0.0,
6996  dflux_mom_v_adv_v_ext=0.0,
6997  dflux_mom_v_adv_w_ext=0.0,
6998  dflux_mom_w_adv_p_ext=0.0,
6999  dflux_mom_w_adv_u_ext=0.0,
7000  dflux_mom_w_adv_v_ext=0.0,
7001  dflux_mom_w_adv_w_ext=0.0,
7002  bc_p_ext=0.0,
7003  bc_u_ext=0.0,
7004  bc_v_ext=0.0,
7005  bc_w_ext=0.0,
7006  bc_mom_u_acc_ext=0.0,
7007  bc_dmom_u_acc_u_ext=0.0,
7008  bc_mom_v_acc_ext=0.0,
7009  bc_dmom_v_acc_v_ext=0.0,
7010  bc_mom_w_acc_ext=0.0,
7011  bc_dmom_w_acc_w_ext=0.0,
7012  bc_mass_adv_ext[nSpace]=ZEROVEC,
7013  bc_dmass_adv_u_ext[nSpace]=ZEROVEC,
7014  bc_dmass_adv_v_ext[nSpace]=ZEROVEC,
7015  bc_dmass_adv_w_ext[nSpace]=ZEROVEC,
7016  bc_mom_u_adv_ext[nSpace]=ZEROVEC,
7017  bc_dmom_u_adv_u_ext[nSpace]=ZEROVEC,
7018  bc_dmom_u_adv_v_ext[nSpace]=ZEROVEC,
7019  bc_dmom_u_adv_w_ext[nSpace]=ZEROVEC,
7020  bc_mom_v_adv_ext[nSpace]=ZEROVEC,
7021  bc_dmom_v_adv_u_ext[nSpace]=ZEROVEC,
7022  bc_dmom_v_adv_v_ext[nSpace]=ZEROVEC,
7023  bc_dmom_v_adv_w_ext[nSpace]=ZEROVEC,
7024  bc_mom_w_adv_ext[nSpace]=ZEROVEC,
7025  bc_dmom_w_adv_u_ext[nSpace]=ZEROVEC,
7026  bc_dmom_w_adv_v_ext[nSpace]=ZEROVEC,
7027  bc_dmom_w_adv_w_ext[nSpace]=ZEROVEC,
7028  bc_mom_uu_diff_ten_ext[nSpace]=ZEROVEC,
7029  bc_mom_vv_diff_ten_ext[nSpace]=ZEROVEC,
7030  bc_mom_ww_diff_ten_ext[nSpace]=ZEROVEC,
7031  bc_mom_uv_diff_ten_ext[1],
7032  bc_mom_uw_diff_ten_ext[1],
7033  bc_mom_vu_diff_ten_ext[1],
7034  bc_mom_vw_diff_ten_ext[1],
7035  bc_mom_wu_diff_ten_ext[1],
7036  bc_mom_wv_diff_ten_ext[1],
7037  bc_mom_u_source_ext=0.0,
7038  bc_mom_v_source_ext=0.0,
7039  bc_mom_w_source_ext=0.0,
7040  bc_mom_u_ham_ext=0.0,
7041  bc_dmom_u_ham_grad_p_ext[nSpace]=ZEROVEC,
7042  bc_dmom_u_ham_grad_u_ext[nSpace]=ZEROVEC,
7043  bc_dmom_u_ham_u_ext=0.0,
7044  bc_dmom_u_ham_v_ext=0.0,
7045  bc_dmom_u_ham_w_ext=0.0,
7046  bc_mom_v_ham_ext=0.0,
7047  bc_dmom_v_ham_grad_p_ext[nSpace]=ZEROVEC,
7048  bc_dmom_v_ham_grad_v_ext[nSpace]=ZEROVEC,
7049  bc_dmom_v_ham_u_ext=0.0,
7050  bc_dmom_v_ham_v_ext=0.0,
7051  bc_dmom_v_ham_w_ext=0.0,
7052  bc_mom_w_ham_ext=0.0,
7053  bc_dmom_w_ham_grad_p_ext[nSpace]=ZEROVEC,
7054  bc_dmom_w_ham_grad_w_ext[nSpace]=ZEROVEC,
7055  bc_dmom_w_ham_u_ext=0.0,
7056  bc_dmom_w_ham_v_ext=0.0,
7057  bc_dmom_w_ham_w_ext=0.0,
7058  fluxJacobian_p_p[nDOF_trial_element],
7059  fluxJacobian_p_u[nDOF_v_trial_element],
7060  fluxJacobian_p_v[nDOF_v_trial_element],
7061  fluxJacobian_p_w[nDOF_v_trial_element],
7062  fluxJacobian_u_p[nDOF_trial_element],
7063  fluxJacobian_u_u[nDOF_v_trial_element],
7064  fluxJacobian_u_v[nDOF_v_trial_element],
7065  fluxJacobian_u_w[nDOF_v_trial_element],
7066  fluxJacobian_v_p[nDOF_trial_element],
7067  fluxJacobian_v_u[nDOF_v_trial_element],
7068  fluxJacobian_v_v[nDOF_v_trial_element],
7069  fluxJacobian_v_w[nDOF_v_trial_element],
7070  fluxJacobian_w_p[nDOF_trial_element],
7071  fluxJacobian_w_u[nDOF_v_trial_element],
7072  fluxJacobian_w_v[nDOF_v_trial_element],
7073  fluxJacobian_w_w[nDOF_v_trial_element],
7074  jac_ext[nSpace*nSpace],
7075  jacDet_ext,
7076  jacInv_ext[nSpace*nSpace],
7077  boundaryJac[nSpace*(nSpace-1)],
7078  metricTensor[(nSpace-1)*(nSpace-1)],
7079  metricTensorDetSqrt,
7080  p_grad_trial_trace[nDOF_trial_element*nSpace],
7081  vel_grad_trial_trace[nDOF_v_trial_element*nSpace],
7082  dS,
7083  p_test_dS[nDOF_test_element],
7084  vel_test_dS[nDOF_v_test_element],
7085  normal[nSpace],
7086  x_ext,y_ext,z_ext,xt_ext,yt_ext,zt_ext,integralScaling,
7087  vel_grad_test_dS[nDOF_v_trial_element*nSpace],
7088  //VRANS
7089  porosity_ext,
7090  //
7091  G[nSpace*nSpace],G_dd_G,tr_G,h_phi,h_penalty,penalty;
7092  gf_s.set_boundary_quad(kb);
7093  gf.set_boundary_quad(kb);
7094  ck.calculateMapping_elementBoundary(eN,
7095  ebN_local,
7096  kb,
7097  ebN_local_kb,
7098  mesh_dof.data(),
7099  mesh_l2g.data(),
7100  mesh_trial_trace_ref.data(),
7101  mesh_grad_trial_trace_ref.data(),
7102  boundaryJac_ref.data(),
7103  jac_ext,
7104  jacDet_ext,
7105  jacInv_ext,
7106  boundaryJac,
7107  metricTensor,
7108  metricTensorDetSqrt,
7109  normal_ref.data(),
7110  normal,
7111  x_ext,y_ext,z_ext);
7112  ck.calculateMappingVelocity_elementBoundary(eN,
7113  ebN_local,
7114  kb,
7115  ebN_local_kb,
7116  mesh_velocity_dof.data(),
7117  mesh_l2g.data(),
7118  mesh_trial_trace_ref.data(),
7119  xt_ext,yt_ext,zt_ext,
7120  normal,
7121  boundaryJac,
7122  metricTensor,
7123  integralScaling);
7124  //dS = ((1.0-MOVING_DOMAIN)*metricTensorDetSqrt + MOVING_DOMAIN*integralScaling)*dS_ref.data()[kb];
7125  dS = metricTensorDetSqrt*dS_ref.data()[kb];
7126  ck.calculateG(jacInv_ext,G,G_dd_G,tr_G);
7127  ck.calculateGScale(G,&ebqe_normal_phi_ext.data()[ebNE_kb_nSpace],h_phi);
7128 
7129  eps_rho = epsFact_rho*(useMetrics*h_phi+(1.0-useMetrics)*elementDiameter.data()[eN]);
7130  eps_mu = epsFact_mu *(useMetrics*h_phi+(1.0-useMetrics)*elementDiameter.data()[eN]);
7131 
7132  //compute shape and solution information
7133  //shape
7134  ck.gradTrialFromRef(&p_grad_trial_trace_ref.data()[ebN_local_kb_nSpace*nDOF_trial_element],jacInv_ext,p_grad_trial_trace);
7135  ck_v.gradTrialFromRef(&vel_grad_trial_trace_ref.data()[ebN_local_kb_nSpace*nDOF_v_trial_element],jacInv_ext,vel_grad_trial_trace);
7136  //solution and gradients
7137  ck.valFromDOF(p_dof.data(),&p_l2g.data()[eN_nDOF_trial_element],&p_trial_trace_ref.data()[ebN_local_kb*nDOF_test_element],p_ext);
7138  ck_v.valFromDOF(u_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],&vel_trial_trace_ref.data()[ebN_local_kb*nDOF_v_test_element],u_ext);
7139  ck_v.valFromDOF(v_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],&vel_trial_trace_ref.data()[ebN_local_kb*nDOF_v_test_element],v_ext);
7140  ck_v.valFromDOF(w_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],&vel_trial_trace_ref.data()[ebN_local_kb*nDOF_v_test_element],w_ext);
7141  ck.valFromDOF(p_old_dof.data(),&p_l2g.data()[eN_nDOF_trial_element],&p_trial_trace_ref.data()[ebN_local_kb*nDOF_test_element],p_old);
7142  ck_v.valFromDOF(u_old_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],&vel_trial_trace_ref.data()[ebN_local_kb*nDOF_v_test_element],u_old);
7143  ck_v.valFromDOF(v_old_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],&vel_trial_trace_ref.data()[ebN_local_kb*nDOF_v_test_element],v_old);
7144  ck_v.valFromDOF(w_old_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],&vel_trial_trace_ref.data()[ebN_local_kb*nDOF_v_test_element],w_old);
7145  ck.gradFromDOF(p_dof.data(),&p_l2g.data()[eN_nDOF_trial_element],p_grad_trial_trace,grad_p_ext);
7146  ck_v.gradFromDOF(u_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],vel_grad_trial_trace,grad_u_ext);
7147  ck_v.gradFromDOF(v_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],vel_grad_trial_trace,grad_v_ext);
7148  ck_v.gradFromDOF(w_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],vel_grad_trial_trace,grad_w_ext);
7149  ck.gradFromDOF(p_old_dof.data(),&p_l2g.data()[eN_nDOF_trial_element],p_grad_trial_trace,grad_p_old);
7150  ck_v.gradFromDOF(u_old_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],vel_grad_trial_trace,grad_u_old);
7151  ck_v.gradFromDOF(v_old_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],vel_grad_trial_trace,grad_v_old);
7152  ck_v.gradFromDOF(w_old_dof.data(),&vel_l2g.data()[eN_nDOF_v_trial_element],vel_grad_trial_trace,grad_w_old);
7153  ck.valFromDOF(phi_solid_nodes.data(),&p_l2g.data()[eN_nDOF_trial_element],&p_trial_trace_ref.data()[ebN_local_kb*nDOF_test_element],phi_s_ext);
7154  //precalculate test function products with integration weights
7155  for (int j=0;j<nDOF_test_element;j++)
7156  {
7157  p_test_dS[j] = p_test_trace_ref.data()[ebN_local_kb*nDOF_test_element+j]*dS;
7158  }
7159  //precalculate test function products with integration weights
7160  for (int j=0;j<nDOF_v_test_element;j++)
7161  {
7162  vel_test_dS[j] = vel_test_trace_ref.data()[ebN_local_kb*nDOF_v_test_element+j]*dS;
7163  for (int I=0;I<nSpace;I++)
7164  vel_grad_test_dS[j*nSpace+I] = vel_grad_trial_trace[j*nSpace+I]*dS;//assume test_j == trial_j
7165  }
7166  //
7167  //load the boundary values
7168  //
7169  bc_p_ext = isDOFBoundary_p.data()[ebNE_kb]*ebqe_bc_p_ext.data()[ebNE_kb]+(1-isDOFBoundary_p.data()[ebNE_kb])*p_ext;
7170  //bc values at moving boundaries are specified relative to boundary motion so we need to add it here
7171  bc_u_ext = isDOFBoundary_u.data()[ebNE_kb]*(ebqe_bc_u_ext.data()[ebNE_kb] + MOVING_DOMAIN*xt_ext) + (1-isDOFBoundary_u.data()[ebNE_kb])*u_ext;
7172  bc_v_ext = isDOFBoundary_v.data()[ebNE_kb]*(ebqe_bc_v_ext.data()[ebNE_kb] + MOVING_DOMAIN*yt_ext) + (1-isDOFBoundary_v.data()[ebNE_kb])*v_ext;
7173  bc_w_ext = isDOFBoundary_w.data()[ebNE_kb]*(ebqe_bc_w_ext.data()[ebNE_kb] + MOVING_DOMAIN*zt_ext) + (1-isDOFBoundary_w.data()[ebNE_kb])*w_ext;
7174  //VRANS
7175  porosity_ext = ebqe_porosity_ext.data()[ebNE_kb];
7176  //
7177  //calculate the internal and external trace of the pde coefficients
7178  //
7179  double eddy_viscosity_ext(0.),bc_eddy_viscosity_ext(0.);//not interested in saving boundary eddy viscosity for now
7180  if (use_ball_as_particle == 1 && nParticles > 0)
7181  {
7182  get_distance_to_ball(nParticles, ball_center.data(), ball_radius.data(),x_ext,y_ext,z_ext,ebqe_phi_s.data()[ebNE_kb]);
7183  }
7184  //else distance_to_solids is updated in PreStep
7185  const double particle_eps = particle_epsFact*(useMetrics*h_phi+(1.0-useMetrics)*elementDiameter.data()[eN]);
7186  //cek needs to be fixed for two-phase ifem
7187  double H = (1.0-useVF)*gf.H(eps_rho,ebqe_phi_ext.data()[ebNE_kb]) + useVF*fmin(1.0,fmax(0.0,ebqe_vf_ext.data()[ebNE_kb]));
7188  double ImH = (1.0-useVF)*gf.ImH(eps_rho,ebqe_phi_ext.data()[ebNE_kb]) + useVF*(1.0-fmin(1.0,fmax(0.0,ebqe_vf_ext.data()[ebNE_kb])));
7189  double rho = rho_0*ImH + rho_1*H;
7190  double nu = nu_0*ImH + nu_1*H;
7191  //
7192  evaluateCoefficients(NONCONSERVATIVE_FORM,
7193  sigma,
7194  rho,
7195  nu,
7196  elementDiameter.data()[eN],
7197  smagorinskyConstant,
7198  turbulenceClosureModel,
7199  g.data(),
7200  useVF,
7201  ebqe_vf_ext.data()[ebNE_kb],
7202  ebqe_phi_ext.data()[ebNE_kb],
7203  &ebqe_normal_phi_ext.data()[ebNE_kb_nSpace],
7204  ebqe_kappa_phi_ext.data()[ebNE_kb],
7205  //VRANS
7206  porosity_ext,
7207  //
7208  ebqe_phi_s.data()[ebNE_kb],
7209  p_old,
7210  u_old,
7211  v_old,
7212  w_old,
7213  grad_p_old,
7214  grad_u_old,
7215  grad_v_old,
7216  grad_w_old,
7217  p_ext,
7218  grad_p_ext,
7219  grad_u_ext,
7220  grad_v_ext,
7221  grad_w_ext,
7222  u_ext,
7223  v_ext,
7224  w_ext,
7225  LAG_LES,
7226  eddy_viscosity_ext,
7227  ebqe_eddy_viscosity_last.data()[ebNE_kb],
7228  mom_u_acc_ext,
7229  dmom_u_acc_u_ext,
7230  mom_v_acc_ext,
7231  dmom_v_acc_v_ext,
7232  mom_w_acc_ext,
7233  dmom_w_acc_w_ext,
7234  mass_adv_ext,
7235  dmass_adv_u_ext,
7236  dmass_adv_v_ext,
7237  dmass_adv_w_ext,
7238  mom_u_adv_ext,
7239  dmom_u_adv_u_ext,
7240  dmom_u_adv_v_ext,
7241  dmom_u_adv_w_ext,
7242  mom_v_adv_ext,
7243  dmom_v_adv_u_ext,
7244  dmom_v_adv_v_ext,
7245  dmom_v_adv_w_ext,
7246  mom_w_adv_ext,
7247  dmom_w_adv_u_ext,
7248  dmom_w_adv_v_ext,
7249  dmom_w_adv_w_ext,
7250  mom_uu_diff_ten_ext,
7251  mom_vv_diff_ten_ext,
7252  mom_ww_diff_ten_ext,
7253  mom_uv_diff_ten_ext,
7254  mom_uw_diff_ten_ext,
7255  mom_vu_diff_ten_ext,
7256  mom_vw_diff_ten_ext,
7257  mom_wu_diff_ten_ext,
7258  mom_wv_diff_ten_ext,
7259  mom_u_source_ext,
7260  mom_v_source_ext,
7261  mom_w_source_ext,
7262  mom_u_ham_ext,
7263  dmom_u_ham_grad_p_ext,
7264  dmom_u_ham_grad_u_ext,
7265  dmom_u_ham_u_ext,
7266  dmom_u_ham_v_ext,
7267  dmom_u_ham_w_ext,
7268  mom_v_ham_ext,
7269  dmom_v_ham_grad_p_ext,
7270  dmom_v_ham_grad_v_ext,
7271  dmom_v_ham_u_ext,
7272  dmom_v_ham_v_ext,
7273  dmom_v_ham_w_ext,
7274  mom_w_ham_ext,
7275  dmom_w_ham_grad_p_ext,
7276  dmom_w_ham_grad_w_ext,
7277  dmom_w_ham_u_ext,
7278  dmom_w_ham_v_ext,
7279  dmom_w_ham_w_ext,
7280  0.0,
7281  0.0,
7282  0.0);
7283  //cek needs to be fixed for two-phase ifem
7284  H = (1.0-useVF)*gf.H(eps_rho,bc_ebqe_phi_ext.data()[ebNE_kb]) + useVF*fmin(1.0,fmax(0.0,bc_ebqe_vf_ext.data()[ebNE_kb]));
7285  ImH = (1.0-useVF)*gf.ImH(eps_rho,bc_ebqe_phi_ext.data()[ebNE_kb]) + useVF*(1.0-fmin(1.0,fmax(0.0,bc_ebqe_vf_ext.data()[ebNE_kb])));
7286  rho = rho_0*ImH + rho_1*H;
7287  nu = nu_0*ImH + nu_1*H;
7288  //
7289  evaluateCoefficients(NONCONSERVATIVE_FORM,
7290  sigma,
7291  rho,
7292  nu,
7293  elementDiameter.data()[eN],
7294  smagorinskyConstant,
7295  turbulenceClosureModel,
7296  g.data(),
7297  useVF,
7298  bc_ebqe_vf_ext.data()[ebNE_kb],
7299  bc_ebqe_phi_ext.data()[ebNE_kb],
7300  &ebqe_normal_phi_ext.data()[ebNE_kb_nSpace],
7301  ebqe_kappa_phi_ext.data()[ebNE_kb],
7302  //VRANS
7303  porosity_ext,
7304  //
7305  ebqe_phi_s.data()[ebNE_kb],
7306  p_old,
7307  u_old,
7308  v_old,
7309  w_old,
7310  grad_p_old,
7311  grad_u_old,
7312  grad_v_old,
7313  grad_w_old,
7314  bc_p_ext,
7315  grad_p_ext,
7316  grad_u_ext,
7317  grad_v_ext,
7318  grad_w_ext,
7319  bc_u_ext,
7320  bc_v_ext,
7321  bc_w_ext,
7322  LAG_LES,
7323  bc_eddy_viscosity_ext,
7324  ebqe_eddy_viscosity_last.data()[ebNE_kb],
7325  bc_mom_u_acc_ext,
7326  bc_dmom_u_acc_u_ext,
7327  bc_mom_v_acc_ext,
7328  bc_dmom_v_acc_v_ext,
7329  bc_mom_w_acc_ext,
7330  bc_dmom_w_acc_w_ext,
7331  bc_mass_adv_ext,
7332  bc_dmass_adv_u_ext,
7333  bc_dmass_adv_v_ext,
7334  bc_dmass_adv_w_ext,
7335  bc_mom_u_adv_ext,
7336  bc_dmom_u_adv_u_ext,
7337  bc_dmom_u_adv_v_ext,
7338  bc_dmom_u_adv_w_ext,
7339  bc_mom_v_adv_ext,
7340  bc_dmom_v_adv_u_ext,
7341  bc_dmom_v_adv_v_ext,
7342  bc_dmom_v_adv_w_ext,
7343  bc_mom_w_adv_ext,
7344  bc_dmom_w_adv_u_ext,
7345  bc_dmom_w_adv_v_ext,
7346  bc_dmom_w_adv_w_ext,
7347  bc_mom_uu_diff_ten_ext,
7348  bc_mom_vv_diff_ten_ext,
7349  bc_mom_ww_diff_ten_ext,
7350  bc_mom_uv_diff_ten_ext,
7351  bc_mom_uw_diff_ten_ext,
7352  bc_mom_vu_diff_ten_ext,
7353  bc_mom_vw_diff_ten_ext,
7354  bc_mom_wu_diff_ten_ext,
7355  bc_mom_wv_diff_ten_ext,
7356  bc_mom_u_source_ext,
7357  bc_mom_v_source_ext,
7358  bc_mom_w_source_ext,
7359  bc_mom_u_ham_ext,
7360  bc_dmom_u_ham_grad_p_ext,
7361  bc_dmom_u_ham_grad_u_ext,
7362  bc_dmom_u_ham_u_ext,
7363  bc_dmom_u_ham_v_ext,
7364  bc_dmom_u_ham_w_ext,
7365  bc_mom_v_ham_ext,
7366  bc_dmom_v_ham_grad_p_ext,
7367  bc_dmom_v_ham_grad_v_ext,
7368  bc_dmom_v_ham_u_ext,
7369  bc_dmom_v_ham_v_ext,
7370  bc_dmom_v_ham_w_ext,
7371  bc_mom_w_ham_ext,
7372  bc_dmom_w_ham_grad_p_ext,
7373  bc_dmom_w_ham_grad_w_ext,
7374  bc_dmom_w_ham_u_ext,
7375  bc_dmom_w_ham_v_ext,
7376  bc_dmom_w_ham_w_ext,
7377  0.0,
7378  0.0,
7379  0.0);
7380  //Turbulence closure model
7381  if (turbulenceClosureModel >= 3)
7382  {
7383  const double turb_var_grad_0_dummy[nSpace] = ZEROVEC;
7384  const double c_mu = 0.09;//mwf hack
7385  updateTurbulenceClosure(NONCONSERVATIVE_FORM,
7386  turbulenceClosureModel,
7387  eps_rho,
7388  eps_mu,
7389  rho_0,
7390  nu_0,
7391  rho_1,
7392  nu_1,
7393  useVF,
7394  ebqe_vf_ext.data()[ebNE_kb],
7395  ebqe_phi_ext.data()[ebNE_kb],
7396  porosity_ext,
7397  c_mu, //mwf hack
7398  ebqe_turb_var_0.data()[ebNE_kb],
7399  ebqe_turb_var_1.data()[ebNE_kb],
7400  turb_var_grad_0_dummy, //not needed
7401  eddy_viscosity_ext,
7402  mom_uu_diff_ten_ext,
7403  mom_vv_diff_ten_ext,
7404  mom_ww_diff_ten_ext,
7405  mom_uv_diff_ten_ext,
7406  mom_uw_diff_ten_ext,
7407  mom_vu_diff_ten_ext,
7408  mom_vw_diff_ten_ext,
7409  mom_wu_diff_ten_ext,
7410  mom_wv_diff_ten_ext,
7411  mom_u_source_ext,
7412  mom_v_source_ext,
7413  mom_w_source_ext);
7414 
7415  updateTurbulenceClosure(NONCONSERVATIVE_FORM,
7416  turbulenceClosureModel,
7417  eps_rho,
7418  eps_mu,
7419  rho_0,
7420  nu_0,
7421  rho_1,
7422  nu_1,
7423  useVF,
7424  ebqe_vf_ext.data()[ebNE_kb],
7425  ebqe_phi_ext.data()[ebNE_kb],
7426  porosity_ext,
7427  c_mu, //mwf hack
7428  ebqe_turb_var_0.data()[ebNE_kb],
7429  ebqe_turb_var_1.data()[ebNE_kb],
7430  turb_var_grad_0_dummy, //not needed
7431  bc_eddy_viscosity_ext,
7432  bc_mom_uu_diff_ten_ext,
7433  bc_mom_vv_diff_ten_ext,
7434  bc_mom_ww_diff_ten_ext,
7435  bc_mom_uv_diff_ten_ext,
7436  bc_mom_uw_diff_ten_ext,
7437  bc_mom_vu_diff_ten_ext,
7438  bc_mom_vw_diff_ten_ext,
7439  bc_mom_wu_diff_ten_ext,
7440  bc_mom_wv_diff_ten_ext,
7441  bc_mom_u_source_ext,
7442  bc_mom_v_source_ext,
7443  bc_mom_w_source_ext);
7444  }
7445  //
7446  //moving domain
7447  //
7448  if (NONCONSERVATIVE_FORM > 0.0)
7449  {
7450  mom_u_ham_ext -= MOVING_DOMAIN*dmom_u_acc_u_ext*(grad_u_ext[0]*xt_ext +
7451  grad_u_ext[1]*yt_ext +
7452  grad_u_ext[2]*zt_ext);
7453  dmom_u_ham_grad_u_ext[0] -= MOVING_DOMAIN*dmom_u_acc_u_ext*xt_ext;
7454  dmom_u_ham_grad_u_ext[1] -= MOVING_DOMAIN*dmom_u_acc_u_ext*yt_ext;
7455  dmom_u_ham_grad_u_ext[2] -= MOVING_DOMAIN*dmom_u_acc_u_ext*zt_ext;
7456  }
7457  else
7458  {
7459  mom_u_adv_ext[0] -= MOVING_DOMAIN*mom_u_acc_ext*xt_ext;
7460  mom_u_adv_ext[1] -= MOVING_DOMAIN*mom_u_acc_ext*yt_ext;
7461  mom_u_adv_ext[2] -= MOVING_DOMAIN*mom_u_acc_ext*zt_ext;
7462  dmom_u_adv_u_ext[0] -= MOVING_DOMAIN*dmom_u_acc_u_ext*xt_ext;
7463  dmom_u_adv_u_ext[1] -= MOVING_DOMAIN*dmom_u_acc_u_ext*yt_ext;
7464  dmom_u_adv_u_ext[2] -= MOVING_DOMAIN*dmom_u_acc_u_ext*zt_ext;
7465  }
7466 
7467  if (NONCONSERVATIVE_FORM > 0.0)
7468  {
7469  mom_v_ham_ext -= MOVING_DOMAIN*dmom_v_acc_v_ext*(grad_v_ext[0]*xt_ext +
7470  grad_v_ext[1]*yt_ext +
7471  grad_v_ext[2]*zt_ext);
7472  dmom_v_ham_grad_v_ext[0] -= MOVING_DOMAIN*dmom_v_acc_v_ext*xt_ext;
7473  dmom_v_ham_grad_v_ext[1] -= MOVING_DOMAIN*dmom_v_acc_v_ext*yt_ext;
7474  dmom_v_ham_grad_v_ext[2] -= MOVING_DOMAIN*dmom_v_acc_v_ext*zt_ext;
7475  }
7476  else
7477  {
7478  mom_v_adv_ext[0] -= MOVING_DOMAIN*mom_v_acc_ext*xt_ext;
7479  mom_v_adv_ext[1] -= MOVING_DOMAIN*mom_v_acc_ext*yt_ext;
7480  mom_v_adv_ext[2] -= MOVING_DOMAIN*mom_v_acc_ext*zt_ext;
7481  dmom_v_adv_v_ext[0] -= MOVING_DOMAIN*dmom_v_acc_v_ext*xt_ext;
7482  dmom_v_adv_v_ext[1] -= MOVING_DOMAIN*dmom_v_acc_v_ext*yt_ext;
7483  dmom_v_adv_v_ext[2] -= MOVING_DOMAIN*dmom_v_acc_v_ext*zt_ext;
7484  }
7485 
7486  if (NONCONSERVATIVE_FORM > 0.0)
7487  {
7488  mom_w_ham_ext -= MOVING_DOMAIN*dmom_w_acc_w_ext*(grad_w_ext[0]*xt_ext +
7489  grad_w_ext[1]*yt_ext +
7490  grad_w_ext[2]*zt_ext);
7491  dmom_w_ham_grad_w_ext[0] -= MOVING_DOMAIN*dmom_w_acc_w_ext*xt_ext;
7492  dmom_w_ham_grad_w_ext[1] -= MOVING_DOMAIN*dmom_w_acc_w_ext*yt_ext;
7493  dmom_w_ham_grad_w_ext[2] -= MOVING_DOMAIN*dmom_w_acc_w_ext*zt_ext;
7494  }
7495  else
7496  {
7497  mom_w_adv_ext[0] -= MOVING_DOMAIN*mom_w_acc_ext*xt_ext;
7498  mom_w_adv_ext[1] -= MOVING_DOMAIN*mom_w_acc_ext*yt_ext;
7499  mom_w_adv_ext[2] -= MOVING_DOMAIN*mom_w_acc_ext*zt_ext;
7500  dmom_w_adv_w_ext[0] -= MOVING_DOMAIN*dmom_w_acc_w_ext*xt_ext;
7501  dmom_w_adv_w_ext[1] -= MOVING_DOMAIN*dmom_w_acc_w_ext*yt_ext;
7502  dmom_w_adv_w_ext[2] -= MOVING_DOMAIN*dmom_w_acc_w_ext*zt_ext;
7503  }
7504 
7505  //moving domain bc's
7506  if (NONCONSERVATIVE_FORM < 1.0)
7507  {
7508  bc_mom_u_adv_ext[0] -= MOVING_DOMAIN*bc_mom_u_acc_ext*xt_ext;
7509  bc_mom_u_adv_ext[1] -= MOVING_DOMAIN*bc_mom_u_acc_ext*yt_ext;
7510  bc_mom_u_adv_ext[2] -= MOVING_DOMAIN*bc_mom_u_acc_ext*zt_ext;
7511 
7512  bc_mom_v_adv_ext[0] -= MOVING_DOMAIN*bc_mom_v_acc_ext*xt_ext;
7513  bc_mom_v_adv_ext[1] -= MOVING_DOMAIN*bc_mom_v_acc_ext*yt_ext;
7514  bc_mom_v_adv_ext[2] -= MOVING_DOMAIN*bc_mom_v_acc_ext*zt_ext;
7515 
7516  bc_mom_w_adv_ext[0] -= MOVING_DOMAIN*bc_mom_w_acc_ext*xt_ext;
7517  bc_mom_w_adv_ext[1] -= MOVING_DOMAIN*bc_mom_w_acc_ext*yt_ext;
7518  bc_mom_w_adv_ext[2] -= MOVING_DOMAIN*bc_mom_w_acc_ext*zt_ext;
7519  }
7520  //
7521  //calculate the numerical fluxes
7522  //
7523  exteriorNumericalAdvectiveFluxDerivatives(NONCONSERVATIVE_FORM,
7524  isDOFBoundary_p.data()[ebNE_kb],
7525  isDOFBoundary_u.data()[ebNE_kb],
7526  isDOFBoundary_v.data()[ebNE_kb],
7527  isDOFBoundary_w.data()[ebNE_kb],
7528  isAdvectiveFluxBoundary_p.data()[ebNE_kb],
7529  isAdvectiveFluxBoundary_u.data()[ebNE_kb],
7530  isAdvectiveFluxBoundary_v.data()[ebNE_kb],
7531  isAdvectiveFluxBoundary_w.data()[ebNE_kb],
7532  dmom_u_ham_grad_p_ext[0],//=1/rho
7533  normal,
7534  bc_p_ext,
7535  bc_u_ext,
7536  bc_v_ext,
7537  bc_w_ext,
7538  bc_mass_adv_ext,
7539  bc_mom_u_adv_ext,
7540  bc_mom_v_adv_ext,
7541  bc_mom_w_adv_ext,
7542  ebqe_bc_flux_mass_ext.data()[ebNE_kb]+MOVING_DOMAIN*(xt_ext*normal[0]+yt_ext*normal[1]+zt_ext*normal[2]),//bc is relative mass flux
7543  ebqe_bc_flux_mom_u_adv_ext.data()[ebNE_kb],
7544  ebqe_bc_flux_mom_v_adv_ext.data()[ebNE_kb],
7545  ebqe_bc_flux_mom_w_adv_ext.data()[ebNE_kb],
7546  p_ext,
7547  u_ext,
7548  v_ext,
7549  w_ext,
7550  dmom_u_acc_u_ext,
7551  mass_adv_ext,
7552  mom_u_adv_ext,
7553  mom_v_adv_ext,
7554  mom_w_adv_ext,
7555  dmass_adv_u_ext,
7556  dmass_adv_v_ext,
7557  dmass_adv_w_ext,
7558  dmom_u_adv_p_ext,
7559  dmom_u_ham_grad_u_ext,
7560  dmom_u_adv_u_ext,
7561  dmom_u_adv_v_ext,
7562  dmom_u_adv_w_ext,
7563  dmom_v_adv_p_ext,
7564  dmom_v_adv_u_ext,
7565  dmom_v_adv_v_ext,
7566  dmom_v_adv_w_ext,
7567  dmom_w_adv_p_ext,
7568  dmom_w_adv_u_ext,
7569  dmom_w_adv_v_ext,
7570  dmom_w_adv_w_ext,
7571  dflux_mass_u_ext,
7572  dflux_mass_v_ext,
7573  dflux_mass_w_ext,
7574  dflux_mom_u_adv_p_ext,
7575  dflux_mom_u_adv_u_ext,
7576  dflux_mom_u_adv_v_ext,
7577  dflux_mom_u_adv_w_ext,
7578  dflux_mom_v_adv_p_ext,
7579  dflux_mom_v_adv_u_ext,
7580  dflux_mom_v_adv_v_ext,
7581  dflux_mom_v_adv_w_ext,
7582  dflux_mom_w_adv_p_ext,
7583  dflux_mom_w_adv_u_ext,
7584  dflux_mom_w_adv_v_ext,
7585  dflux_mom_w_adv_w_ext);
7586  //
7587  //calculate the flux jacobian
7588  //
7589  ck.calculateGScale(G,normal,h_penalty);
7590  penalty = useMetrics*C_b/h_penalty + (1.0-useMetrics)*ebqe_penalty_ext.data()[ebNE_kb];
7591  if (isActiveElement[eN])
7592  // if(true)//boundaryFlags[ebN] > 0)
7593  { //if boundary flag positive, then include flux contributions on interpart boundaries
7594  for (int j=0;j<nDOF_trial_element;j++)
7595  {
7596  register int j_nSpace = j*nSpace,ebN_local_kb_j=ebN_local_kb*nDOF_trial_element+j;
7597  fluxJacobian_p_p[j]=0.0;
7598  fluxJacobian_u_p[j]=ck.ExteriorNumericalAdvectiveFluxJacobian(dflux_mom_u_adv_p_ext,p_trial_trace_ref.data()[ebN_local_kb_j]);
7599  fluxJacobian_v_p[j]=ck.ExteriorNumericalAdvectiveFluxJacobian(dflux_mom_v_adv_p_ext,p_trial_trace_ref.data()[ebN_local_kb_j]);
7600  fluxJacobian_w_p[j]=ck.ExteriorNumericalAdvectiveFluxJacobian(dflux_mom_w_adv_p_ext,p_trial_trace_ref.data()[ebN_local_kb_j]);
7601  }
7602  for (int j=0;j<nDOF_v_trial_element;j++)
7603  {
7604  register int j_nSpace = j*nSpace,ebN_local_kb_j=ebN_local_kb*nDOF_v_trial_element+j;
7605  fluxJacobian_p_u[j]=ck.ExteriorNumericalAdvectiveFluxJacobian(dflux_mass_u_ext,vel_trial_trace_ref.data()[ebN_local_kb_j]);
7606  fluxJacobian_p_v[j]=ck.ExteriorNumericalAdvectiveFluxJacobian(dflux_mass_v_ext,vel_trial_trace_ref.data()[ebN_local_kb_j]);
7607  fluxJacobian_p_w[j]=ck.ExteriorNumericalAdvectiveFluxJacobian(dflux_mass_w_ext,vel_trial_trace_ref.data()[ebN_local_kb_j]);
7608  fluxJacobian_u_u[j]=ck.ExteriorNumericalAdvectiveFluxJacobian(dflux_mom_u_adv_u_ext,vel_trial_trace_ref.data()[ebN_local_kb_j]) +
7610  ebqe_phi_ext.data()[ebNE_kb],
7611  sdInfo_u_u_rowptr.data(),
7612  sdInfo_u_u_colind.data(),
7613  isDOFBoundary_u.data()[ebNE_kb],
7614  isDiffusiveFluxBoundary_u.data()[ebNE_kb],
7615  normal,
7616  mom_uu_diff_ten_ext,
7617  vel_trial_trace_ref.data()[ebN_local_kb_j],
7618  &vel_grad_trial_trace[j_nSpace],
7619  penalty);//ebqe_penalty_ext.data()[ebNE_kb]);
7620  fluxJacobian_u_v[j]=ck.ExteriorNumericalAdvectiveFluxJacobian(dflux_mom_u_adv_v_ext,vel_trial_trace_ref.data()[ebN_local_kb_j]) +
7622  ebqe_phi_ext.data()[ebNE_kb],
7623  sdInfo_u_v_rowptr.data(),
7624  sdInfo_u_v_colind.data(),
7625  isDOFBoundary_v.data()[ebNE_kb],
7626  isDiffusiveFluxBoundary_v.data()[ebNE_kb],
7627  normal,
7628  mom_uv_diff_ten_ext,
7629  vel_trial_trace_ref.data()[ebN_local_kb_j],
7630  &vel_grad_trial_trace[j_nSpace],
7631  penalty);//ebqe_penalty_ext.data()[ebNE_kb]);
7632  fluxJacobian_u_w[j]=ck.ExteriorNumericalAdvectiveFluxJacobian(dflux_mom_u_adv_w_ext,vel_trial_trace_ref.data()[ebN_local_kb_j]) +
7634  ebqe_phi_ext.data()[ebNE_kb],
7635  sdInfo_u_w_rowptr.data(),
7636  sdInfo_u_w_colind.data(),
7637  isDOFBoundary_w.data()[ebNE_kb],
7638  isDiffusiveFluxBoundary_w.data()[ebNE_kb],
7639  normal,
7640  mom_uw_diff_ten_ext,
7641  vel_trial_trace_ref.data()[ebN_local_kb_j],
7642  &vel_grad_trial_trace[j_nSpace],
7643  penalty);//ebqe_penalty_ext.data()[ebNE_kb]);
7644 
7645  fluxJacobian_v_u[j]=ck.ExteriorNumericalAdvectiveFluxJacobian(dflux_mom_v_adv_u_ext,vel_trial_trace_ref.data()[ebN_local_kb_j]) +
7647  ebqe_phi_ext.data()[ebNE_kb],
7648  sdInfo_v_u_rowptr.data(),
7649  sdInfo_v_u_colind.data(),
7650  isDOFBoundary_u.data()[ebNE_kb],
7651  isDiffusiveFluxBoundary_u.data()[ebNE_kb],
7652  normal,
7653  mom_vu_diff_ten_ext,
7654  vel_trial_trace_ref.data()[ebN_local_kb_j],
7655  &vel_grad_trial_trace[j_nSpace],
7656  penalty);//ebqe_penalty_ext.data()[ebNE_kb]);
7657  fluxJacobian_v_v[j]=ck.ExteriorNumericalAdvectiveFluxJacobian(dflux_mom_v_adv_v_ext,vel_trial_trace_ref.data()[ebN_local_kb_j]) +
7659  ebqe_phi_ext.data()[ebNE_kb],
7660  sdInfo_v_v_rowptr.data(),
7661  sdInfo_v_v_colind.data(),
7662  isDOFBoundary_v.data()[ebNE_kb],
7663  isDiffusiveFluxBoundary_v.data()[ebNE_kb],
7664  normal,
7665  mom_vv_diff_ten_ext,
7666  vel_trial_trace_ref.data()[ebN_local_kb_j],
7667  &vel_grad_trial_trace[j_nSpace],
7668  penalty);//ebqe_penalty_ext.data()[ebNE_kb]);
7669  fluxJacobian_v_w[j]=ck.ExteriorNumericalAdvectiveFluxJacobian(dflux_mom_v_adv_w_ext,vel_trial_trace_ref.data()[ebN_local_kb_j]) +
7671  ebqe_phi_ext.data()[ebNE_kb],
7672  sdInfo_v_w_rowptr.data(),
7673  sdInfo_v_w_colind.data(),
7674  isDOFBoundary_w.data()[ebNE_kb],
7675  isDiffusiveFluxBoundary_w.data()[ebNE_kb],
7676  normal,
7677  mom_vw_diff_ten_ext,
7678  vel_trial_trace_ref.data()[ebN_local_kb_j],
7679  &vel_grad_trial_trace[j_nSpace],
7680  penalty);//ebqe_penalty_ext.data()[ebNE_kb]);
7681 
7682  fluxJacobian_w_u[j]=ck.ExteriorNumericalAdvectiveFluxJacobian(dflux_mom_w_adv_u_ext,vel_trial_trace_ref.data()[ebN_local_kb_j]) +
7684  ebqe_phi_ext.data()[ebNE_kb],
7685  sdInfo_w_u_rowptr.data(),
7686  sdInfo_w_u_colind.data(),
7687  isDOFBoundary_u.data()[ebNE_kb],
7688  isDiffusiveFluxBoundary_u.data()[ebNE_kb],
7689  normal,
7690  mom_wu_diff_ten_ext,
7691  vel_trial_trace_ref.data()[ebN_local_kb_j],
7692  &vel_grad_trial_trace[j_nSpace],
7693  penalty);//ebqe_penalty_ext.data()[ebNE_kb]);
7694  fluxJacobian_w_v[j]=ck.ExteriorNumericalAdvectiveFluxJacobian(dflux_mom_w_adv_v_ext,vel_trial_trace_ref.data()[ebN_local_kb_j]) +
7696  ebqe_phi_ext.data()[ebNE_kb],
7697  sdInfo_w_v_rowptr.data(),
7698  sdInfo_w_v_colind.data(),
7699  isDOFBoundary_v.data()[ebNE_kb],
7700  isDiffusiveFluxBoundary_v.data()[ebNE_kb],
7701  normal,
7702  mom_wv_diff_ten_ext,
7703  vel_trial_trace_ref.data()[ebN_local_kb_j],
7704  &vel_grad_trial_trace[j_nSpace],
7705  penalty);//ebqe_penalty_ext.data()[ebNE_kb]);
7706  fluxJacobian_w_w[j]=ck.ExteriorNumericalAdvectiveFluxJacobian(dflux_mom_w_adv_w_ext,vel_trial_trace_ref.data()[ebN_local_kb_j]) +
7708  ebqe_phi_ext.data()[ebNE_kb],
7709  sdInfo_w_w_rowptr.data(),
7710  sdInfo_w_w_colind.data(),
7711  isDOFBoundary_w.data()[ebNE_kb],
7712  isDiffusiveFluxBoundary_w.data()[ebNE_kb],
7713  normal,
7714  mom_ww_diff_ten_ext,
7715  vel_trial_trace_ref.data()[ebN_local_kb_j],
7716  &vel_grad_trial_trace[j_nSpace],
7717  penalty);//ebqe_penalty_ext.data()[ebNE_kb]);
7718  }//j
7719  }
7720  //
7721  //update the global Jacobian from the flux Jacobian
7722  //
7723  const double H_s = gf_s.H(particle_eps, ebqe_phi_s[ebNE_kb]);
7724  if (isActiveElement[eN])
7725  {
7726  for (int i=0;i<nDOF_test_element;i++)
7727  {
7728  register int eN_i = eN*nDOF_test_element+i;
7729  for (int j=0;j<nDOF_trial_element;j++)
7730  {
7731  register int eN_j = eN*nDOF_trial_element+j;
7732  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;
7733 
7734  globalJacobian.data()[csrRowIndeces_p_p[eN_i] + csrColumnOffsets_eb_p_p.data()[ebN_i_j]] += H_s*fluxJacobian_p_p[j]*p_test_dS[i];
7735  }
7736  }
7737  for (int i=0;i<nDOF_test_element;i++)
7738  {
7739  register int eN_i = eN*nDOF_test_element+i;
7740  for (int j=0;j<nDOF_v_trial_element;j++)
7741  {
7742  register int eN_j = eN*nDOF_v_trial_element+j;
7743  register int ebN_i_j = ebN*4*nDOF_test_X_v_trial_element + i*nDOF_v_trial_element + j,ebN_local_kb_j=ebN_local_kb*nDOF_v_trial_element+j;
7744  globalJacobian.data()[csrRowIndeces_p_u.data()[eN_i] + csrColumnOffsets_eb_p_u.data()[ebN_i_j]] += H_s*fluxJacobian_p_u[j]*p_test_dS[i];
7745  globalJacobian.data()[csrRowIndeces_p_v.data()[eN_i] + csrColumnOffsets_eb_p_v.data()[ebN_i_j]] += H_s*fluxJacobian_p_v[j]*p_test_dS[i];
7746  globalJacobian.data()[csrRowIndeces_p_w.data()[eN_i] + csrColumnOffsets_eb_p_w.data()[ebN_i_j]] += H_s*fluxJacobian_p_w[j]*p_test_dS[i];
7747  }
7748  }
7749  for (int i=0;i<nDOF_v_test_element;i++)
7750  {
7751  register int eN_i = eN*nDOF_v_test_element+i;
7752  for (int j=0;j<nDOF_trial_element;j++)
7753  {
7754  register int ebN_i_j = ebN*4*nDOF_v_test_X_trial_element + i*nDOF_trial_element + j,ebN_local_kb_j=ebN_local_kb*nDOF_trial_element+j;
7755  globalJacobian.data()[csrRowIndeces_u_p.data()[eN_i] + csrColumnOffsets_eb_u_p.data()[ebN_i_j]] += H_s*fluxJacobian_u_p[j]*vel_test_dS[i];
7756  globalJacobian.data()[csrRowIndeces_v_p.data()[eN_i] + csrColumnOffsets_eb_v_p.data()[ebN_i_j]] += H_s*fluxJacobian_v_p[j]*vel_test_dS[i];
7757  globalJacobian.data()[csrRowIndeces_w_p.data()[eN_i] + csrColumnOffsets_eb_w_p.data()[ebN_i_j]] += H_s*fluxJacobian_w_p[j]*vel_test_dS[i];
7758  }
7759  }
7760  for (int i=0;i<nDOF_v_test_element;i++)
7761  {
7762  register int eN_i = eN*nDOF_v_test_element+i;
7763  for (int j=0;j<nDOF_v_trial_element;j++)
7764  {
7765  register int eN_j = eN*nDOF_v_trial_element+j;
7766  register int ebN_i_j = ebN*4*nDOF_v_test_X_v_trial_element + i*nDOF_v_trial_element + j,ebN_local_kb_j=ebN_local_kb*nDOF_v_trial_element+j;
7767  globalJacobian.data()[csrRowIndeces_u_u.data()[eN_i] + csrColumnOffsets_eb_u_u.data()[ebN_i_j]] +=
7768  H_s*(fluxJacobian_u_u[j]*vel_test_dS[i]+
7769  ck.ExteriorElementBoundaryDiffusionAdjointJacobian(isDOFBoundary_u.data()[ebNE_kb],
7770  isDiffusiveFluxBoundary_u.data()[ebNE_kb],
7771  eb_adjoint_sigma,
7772  vel_trial_trace_ref.data()[ebN_local_kb_j],
7773  normal,
7774  sdInfo_u_u_rowptr.data(),
7775  sdInfo_u_u_colind.data(),
7776  mom_uu_diff_ten_ext,
7777  &vel_grad_test_dS[i*nSpace]));
7778  globalJacobian.data()[csrRowIndeces_u_v.data()[eN_i] + csrColumnOffsets_eb_u_v.data()[ebN_i_j]] +=
7779  H_s*(fluxJacobian_u_v[j]*vel_test_dS[i]+
7780  ck.ExteriorElementBoundaryDiffusionAdjointJacobian(isDOFBoundary_v.data()[ebNE_kb],
7781  isDiffusiveFluxBoundary_u.data()[ebNE_kb],
7782  eb_adjoint_sigma,
7783  vel_trial_trace_ref.data()[ebN_local_kb_j],
7784  normal,
7785  sdInfo_u_v_rowptr.data(),
7786  sdInfo_u_v_colind.data(),
7787  mom_uv_diff_ten_ext,
7788  &vel_grad_test_dS[i*nSpace]));
7789  globalJacobian.data()[csrRowIndeces_u_w.data()[eN_i] + csrColumnOffsets_eb_u_w.data()[ebN_i_j]] +=
7790  H_s*(fluxJacobian_u_w[j]*vel_test_dS[i]+
7791  ck.ExteriorElementBoundaryDiffusionAdjointJacobian(isDOFBoundary_w.data()[ebNE_kb],
7792  isDiffusiveFluxBoundary_u.data()[ebNE_kb],
7793  eb_adjoint_sigma,
7794  vel_trial_trace_ref.data()[ebN_local_kb_j],
7795  normal,
7796  sdInfo_u_w_rowptr.data(),
7797  sdInfo_u_w_colind.data(),
7798  mom_uw_diff_ten_ext,
7799  &vel_grad_test_dS[i*nSpace]));
7800  globalJacobian.data()[csrRowIndeces_v_u.data()[eN_i] + csrColumnOffsets_eb_v_u.data()[ebN_i_j]] +=
7801  H_s*(fluxJacobian_v_u[j]*vel_test_dS[i]+
7802  ck.ExteriorElementBoundaryDiffusionAdjointJacobian(isDOFBoundary_u.data()[ebNE_kb],
7803  isDiffusiveFluxBoundary_v.data()[ebNE_kb],
7804  eb_adjoint_sigma,
7805  vel_trial_trace_ref.data()[ebN_local_kb_j],
7806  normal,
7807  sdInfo_v_u_rowptr.data(),
7808  sdInfo_v_u_colind.data(),
7809  mom_vu_diff_ten_ext,
7810  &vel_grad_test_dS[i*nSpace]));
7811  globalJacobian.data()[csrRowIndeces_v_v.data()[eN_i] + csrColumnOffsets_eb_v_v.data()[ebN_i_j]] +=
7812  H_s*(fluxJacobian_v_v[j]*vel_test_dS[i]+
7813  ck.ExteriorElementBoundaryDiffusionAdjointJacobian(isDOFBoundary_v.data()[ebNE_kb],
7814  isDiffusiveFluxBoundary_v.data()[ebNE_kb],
7815  eb_adjoint_sigma,
7816  vel_trial_trace_ref.data()[ebN_local_kb_j],
7817  normal,
7818  sdInfo_v_v_rowptr.data(),
7819  sdInfo_v_v_colind.data(),
7820  mom_vv_diff_ten_ext,
7821  &vel_grad_test_dS[i*nSpace]));
7822  globalJacobian.data()[csrRowIndeces_v_w.data()[eN_i] + csrColumnOffsets_eb_v_w.data()[ebN_i_j]] +=
7823  H_s*(fluxJacobian_v_w[j]*vel_test_dS[i]+
7824  ck.ExteriorElementBoundaryDiffusionAdjointJacobian(isDOFBoundary_w.data()[ebNE_kb],
7825  isDiffusiveFluxBoundary_v.data()[ebNE_kb],
7826  eb_adjoint_sigma,
7827  vel_trial_trace_ref.data()[ebN_local_kb_j],
7828  normal,
7829  sdInfo_v_w_rowptr.data(),
7830  sdInfo_v_w_colind.data(),
7831  mom_vw_diff_ten_ext,
7832  &vel_grad_test_dS[i*nSpace]));
7833  globalJacobian.data()[csrRowIndeces_w_u.data()[eN_i] + csrColumnOffsets_eb_w_u.data()[ebN_i_j]] +=
7834  H_s*(fluxJacobian_w_u[j]*vel_test_dS[i]+
7835  ck.ExteriorElementBoundaryDiffusionAdjointJacobian(isDOFBoundary_u.data()[ebNE_kb],
7836  isDiffusiveFluxBoundary_w.data()[ebNE_kb],
7837  eb_adjoint_sigma,
7838  vel_trial_trace_ref.data()[ebN_local_kb_j],
7839  normal,
7840  sdInfo_w_u_rowptr.data(),
7841  sdInfo_w_u_colind.data(),
7842  mom_wu_diff_ten_ext,
7843  &vel_grad_test_dS[i*nSpace]));
7844  globalJacobian.data()[csrRowIndeces_w_v.data()[eN_i] + csrColumnOffsets_eb_w_v.data()[ebN_i_j]] +=
7845  H_s*(fluxJacobian_w_v[j]*vel_test_dS[i]+
7846  ck.ExteriorElementBoundaryDiffusionAdjointJacobian(isDOFBoundary_v.data()[ebNE_kb],
7847  isDiffusiveFluxBoundary_w.data()[ebNE_kb],
7848  eb_adjoint_sigma,
7849  vel_trial_trace_ref.data()[ebN_local_kb_j],
7850  normal,
7851  sdInfo_w_v_rowptr.data(),
7852  sdInfo_w_v_colind.data(),
7853  mom_wv_diff_ten_ext,
7854  &vel_grad_test_dS[i*nSpace]));
7855  globalJacobian.data()[csrRowIndeces_w_w.data()[eN_i] + csrColumnOffsets_eb_w_w.data()[ebN_i_j]] +=
7856  H_s*(fluxJacobian_w_w[j]*vel_test_dS[i]+
7857  ck.ExteriorElementBoundaryDiffusionAdjointJacobian(isDOFBoundary_w.data()[ebNE_kb],
7858  isDiffusiveFluxBoundary_w.data()[ebNE_kb],
7859  eb_adjoint_sigma,
7860  vel_trial_trace_ref.data()[ebN_local_kb_j],
7861  normal,
7862  sdInfo_w_w_rowptr.data(),
7863  sdInfo_w_w_colind.data(),
7864  mom_ww_diff_ten_ext,
7865  &vel_grad_test_dS[i*nSpace]));
7866  }//j
7867  }//i
7868  }
7869  }//kb
7870  }//ebNE
7871  }//computeJacobian
7872 
7874  {
7875  int nExteriorElementBoundaries_global = args.scalar<int>("nExteriorElementBoundaries_global");
7876  xt::pyarray<int>& exteriorElementBoundariesArray = args.array<int>("exteriorElementBoundariesArray");
7877  int nInteriorElementBoundaries_global = args.scalar<int>("nInteriorElementBoundaries_global");
7878  xt::pyarray<int>& interiorElementBoundariesArray = args.array<int>("interiorElementBoundariesArray");
7879  xt::pyarray<int>& elementBoundaryElementsArray = args.array<int>("elementBoundaryElementsArray");
7880  xt::pyarray<int>& elementBoundaryLocalElementBoundariesArray = args.array<int>("elementBoundaryLocalElementBoundariesArray");
7881  xt::pyarray<double>& mesh_dof = args.array<double>("mesh_dof");
7882  xt::pyarray<double>& mesh_velocity_dof = args.array<double>("mesh_velocity_dof");
7883  double MOVING_DOMAIN = args.scalar<double>("MOVING_DOMAIN");
7884  xt::pyarray<int>& mesh_l2g = args.array<int>("mesh_l2g");
7885  xt::pyarray<double>& mesh_trial_trace_ref = args.array<double>("mesh_trial_trace_ref");
7886  xt::pyarray<double>& mesh_grad_trial_trace_ref = args.array<double>("mesh_grad_trial_trace_ref");
7887  xt::pyarray<double>& normal_ref = args.array<double>("normal_ref");
7888  xt::pyarray<double>& boundaryJac_ref = args.array<double>("boundaryJac_ref");
7889  xt::pyarray<int>& vel_l2g = args.array<int>("vel_l2g");
7890  xt::pyarray<double>& u_dof = args.array<double>("u_dof");
7891  xt::pyarray<double>& v_dof = args.array<double>("v_dof");
7892  xt::pyarray<double>& w_dof = args.array<double>("w_dof");
7893  xt::pyarray<double>& vel_trial_trace_ref = args.array<double>("vel_trial_trace_ref");
7894  xt::pyarray<double>& ebqe_velocity = args.array<double>("ebqe_velocity");
7895  xt::pyarray<double>& velocityAverage = args.array<double>("velocityAverage");
7896  xt::pyarray<int>& elementMaterialTypes = args.array<int>("elementMaterialTypes");
7897  xt::pyarray<double>& porosityTypes = args.array<double>("porosityTypes");
7898  int permutations[nQuadraturePoints_elementBoundary];
7899  double xArray_left[nQuadraturePoints_elementBoundary*nSpace],
7900  xArray_right[nQuadraturePoints_elementBoundary*nSpace];
7901  for (int i=0;i<nQuadraturePoints_elementBoundary;i++)
7902  permutations[i]=i;//just to initialize
7903  for (int ebNE = 0; ebNE < nExteriorElementBoundaries_global; ebNE++)
7904  {
7905  register int ebN = exteriorElementBoundariesArray.data()[ebNE];
7906  for (int kb=0;kb<nQuadraturePoints_elementBoundary;kb++)
7907  {
7908  register int ebN_kb_nSpace = ebN*nQuadraturePoints_elementBoundary*nSpace+kb*nSpace,
7909  ebNE_kb_nSpace = ebNE*nQuadraturePoints_elementBoundary*nSpace+kb*nSpace;
7910  velocityAverage.data()[ebN_kb_nSpace+0]=ebqe_velocity.data()[ebNE_kb_nSpace+0];
7911  velocityAverage.data()[ebN_kb_nSpace+1]=ebqe_velocity.data()[ebNE_kb_nSpace+1];
7912  velocityAverage.data()[ebN_kb_nSpace+2]=ebqe_velocity.data()[ebNE_kb_nSpace+2];
7913  }//ebNE
7914  }
7915  for (int ebNI = 0; ebNI < nInteriorElementBoundaries_global; ebNI++)
7916  {
7917  register int ebN = interiorElementBoundariesArray.data()[ebNI],
7918  left_eN_global = elementBoundaryElementsArray.data()[ebN*2+0],
7919  left_ebN_element = elementBoundaryLocalElementBoundariesArray.data()[ebN*2+0],
7920  right_eN_global = elementBoundaryElementsArray.data()[ebN*2+1],
7921  right_ebN_element = elementBoundaryLocalElementBoundariesArray.data()[ebN*2+1],
7922  left_eN_nDOF_trial_element = left_eN_global*nDOF_trial_element,
7923  right_eN_nDOF_trial_element = right_eN_global*nDOF_trial_element;
7924  double jac[nSpace*nSpace],
7925  jacDet,
7926  jacInv[nSpace*nSpace],
7927  boundaryJac[nSpace*(nSpace-1)],
7928  metricTensor[(nSpace-1)*(nSpace-1)],
7929  metricTensorDetSqrt,
7930  normal[nSpace],
7931  x,y,z,
7932  xt,yt,zt,integralScaling,
7933  left_porosity = porosityTypes[elementMaterialTypes[left_eN_global]],
7934  right_porosity = porosityTypes[elementMaterialTypes[right_eN_global]];
7935 
7936  for (int kb=0;kb<nQuadraturePoints_elementBoundary;kb++)
7937  {
7938  ck.calculateMapping_elementBoundary(left_eN_global,
7939  left_ebN_element,
7940  kb,
7941  left_ebN_element*nQuadraturePoints_elementBoundary+kb,
7942  mesh_dof.data(),
7943  mesh_l2g.data(),
7944  mesh_trial_trace_ref.data(),
7945  mesh_grad_trial_trace_ref.data(),
7946  boundaryJac_ref.data(),
7947  jac,
7948  jacDet,
7949  jacInv,
7950  boundaryJac,
7951  metricTensor,
7952  metricTensorDetSqrt,
7953  normal_ref.data(),
7954  normal,
7955  x,y,z);
7956  xArray_left[kb*nSpace+0] = x;
7957  xArray_left[kb*nSpace+1] = y;
7958  xArray_left[kb*nSpace+2] = z;
7959  ck.calculateMapping_elementBoundary(right_eN_global,
7960  right_ebN_element,
7961  kb,
7962  right_ebN_element*nQuadraturePoints_elementBoundary+kb,
7963  mesh_dof.data(),
7964  mesh_l2g.data(),
7965  mesh_trial_trace_ref.data(),
7966  mesh_grad_trial_trace_ref.data(),
7967  boundaryJac_ref.data(),
7968  jac,
7969  jacDet,
7970  jacInv,
7971  boundaryJac,
7972  metricTensor,
7973  metricTensorDetSqrt,
7974  normal_ref.data(),
7975  normal,
7976  x,y,z);
7977  ck.calculateMappingVelocity_elementBoundary(left_eN_global,
7978  left_ebN_element,
7979  kb,
7980  left_ebN_element*nQuadraturePoints_elementBoundary+kb,
7981  mesh_velocity_dof.data(),
7982  mesh_l2g.data(),
7983  mesh_trial_trace_ref.data(),
7984  xt,yt,zt,
7985  normal,
7986  boundaryJac,
7987  metricTensor,
7988  integralScaling);
7989  xArray_right[kb*nSpace+0] = x;
7990  xArray_right[kb*nSpace+1] = y;
7991  xArray_right[kb*nSpace+2] = z;
7992  }
7993  for (int kb_left=0;kb_left<nQuadraturePoints_elementBoundary;kb_left++)
7994  {
7995  double errorNormMin = 1.0;
7996  for (int kb_right=0;kb_right<nQuadraturePoints_elementBoundary;kb_right++)
7997  {
7998  double errorNorm=0.0;
7999  for (int I=0;I<nSpace;I++)
8000  {
8001  errorNorm += fabs(xArray_left[kb_left*nSpace+I]
8002  -
8003  xArray_right[kb_right*nSpace+I]);
8004  }
8005  if (errorNorm < errorNormMin)
8006  {
8007  permutations[kb_right] = kb_left;
8008  errorNormMin = errorNorm;
8009  }
8010  }
8011  }
8012  for (int kb=0;kb<nQuadraturePoints_elementBoundary;kb++)
8013  {
8014  register int ebN_kb_nSpace = ebN*nQuadraturePoints_elementBoundary*nSpace+kb*nSpace;
8015  register double u_left=0.0,
8016  v_left=0.0,
8017  w_left=0.0,
8018  u_right=0.0,
8019  v_right=0.0,
8020  w_right=0.0;
8021  register int left_kb = kb,
8022  right_kb = permutations[kb],
8023  left_ebN_element_kb_nDOF_test_element=(left_ebN_element*nQuadraturePoints_elementBoundary+left_kb)*nDOF_test_element,
8024  right_ebN_element_kb_nDOF_test_element=(right_ebN_element*nQuadraturePoints_elementBoundary+right_kb)*nDOF_test_element;
8025  //
8026  //calculate the velocity solution at quadrature points on left and right
8027  //
8028  ck.valFromDOF(u_dof.data(),&vel_l2g.data()[left_eN_nDOF_trial_element],&vel_trial_trace_ref.data()[left_ebN_element_kb_nDOF_test_element],u_left);
8029  ck.valFromDOF(v_dof.data(),&vel_l2g.data()[left_eN_nDOF_trial_element],&vel_trial_trace_ref.data()[left_ebN_element_kb_nDOF_test_element],v_left);
8030  ck.valFromDOF(w_dof.data(),&vel_l2g.data()[left_eN_nDOF_trial_element],&vel_trial_trace_ref.data()[left_ebN_element_kb_nDOF_test_element],w_left);
8031  //
8032  ck.valFromDOF(u_dof.data(),&vel_l2g.data()[right_eN_nDOF_trial_element],&vel_trial_trace_ref.data()[right_ebN_element_kb_nDOF_test_element],u_right);
8033  ck.valFromDOF(v_dof.data(),&vel_l2g.data()[right_eN_nDOF_trial_element],&vel_trial_trace_ref.data()[right_ebN_element_kb_nDOF_test_element],v_right);
8034  ck.valFromDOF(w_dof.data(),&vel_l2g.data()[right_eN_nDOF_trial_element],&vel_trial_trace_ref.data()[right_ebN_element_kb_nDOF_test_element],w_right);
8035  //
8036  velocityAverage.data()[ebN_kb_nSpace+0]=0.5*(left_porosity*u_left + right_porosity*u_right);
8037  velocityAverage.data()[ebN_kb_nSpace+1]=0.5*(left_porosity*v_left + right_porosity*v_right);
8038  velocityAverage.data()[ebN_kb_nSpace+2]=0.5*(left_porosity*w_left + right_porosity*w_right);
8039  }//ebNI
8040  }
8041  }
8042 
8043  inline
8044  void evaluateTPAdvectionCoefficients(const double eps_rho,
8045  const double rho_0,
8046  const double rho_1,
8047  const double useVF,
8048  const double& vf,
8049  const double& phi,
8050  const double& u,
8051  const double& v,
8052  const double& w,
8053  double dmass_adv_p[nSpace],
8054  double dmom_u_adv_u[nSpace],
8055  double dmom_v_adv_v[nSpace],
8056  double dmom_w_adv_w[nSpace])
8057  {
8058  double H_rho, ImH_rho, rho;
8059 
8060  H_rho = (1.0-useVF)*gf.H(eps_rho,phi) + useVF*fmin(1.0,fmax(0.0,vf));
8061  ImH_rho = (1.0-useVF)*gf.ImH(eps_rho,phi) + useVF*(1.0-fmin(1.0,fmax(0.0,vf)));
8062 
8063  rho = rho_0*ImH_rho + rho_1*H_rho;
8064 
8065  dmass_adv_p[0] = rho*u;
8066  dmass_adv_p[1] = rho*v;
8067  dmass_adv_p[2] = rho*w;
8068 
8069  dmom_u_adv_u[0] = rho*u;
8070  dmom_u_adv_u[1] = rho*v;
8071  dmom_u_adv_u[2] = rho*w;
8072 
8073  dmom_v_adv_v[0] = rho*u;
8074  dmom_v_adv_v[1] = rho*v;
8075  dmom_v_adv_v[2] = rho*w;
8076 
8077  dmom_w_adv_w[0] = rho*u;
8078  dmom_w_adv_w[1] = rho*v;
8079  dmom_w_adv_w[2] = rho*w;
8080  }
8081  inline
8082  void evaluateTPInvViscosityMassCoefficients(const int use_numerical_viscosity,
8083  const double numerical_viscosity,
8084  const double eps_rho,
8085  const double eps_mu,
8086  const double rho_0,
8087  double nu_0,
8088  const double rho_1,
8089  double nu_1,
8090  const double useVF,
8091  const double& vf,
8092  const double& phi,
8093  const double& p,
8094  const double& u,
8095  const double& v,
8096  const double& w,
8097  double& mom_p_acc,
8098  double& dmom_p_acc_p,
8099  double& mom_u_acc,
8100  double& dmom_u_acc_u,
8101  double& mom_v_acc,
8102  double& dmom_v_acc_v,
8103  double& mom_w_acc,
8104  double& dmom_w_acc_w)
8105  {
8106  // This should be split off into a seperate function
8107  double H_rho, ImH_rho, H_mu, ImH_mu, rho, nu, mu;
8108 
8109 
8110  H_rho = (1.0-useVF)*gf.H(eps_rho,phi) + useVF*fmin(1.0,fmax(0.0,vf));
8111  ImH_rho = (1.0-useVF)*gf.ImH(eps_rho,phi) + useVF*(1.0-fmin(1.0,fmax(0.0,vf)));
8112  H_mu = (1.0-useVF)*gf.H(eps_mu,phi) + useVF*fmin(1.0,fmax(0.0,vf));
8113  ImH_mu = (1.0-useVF)*gf.ImH(eps_mu,phi) + useVF*(1.0-fmin(1.0,fmax(0.0,vf)));
8114 
8115  rho = rho_0*ImH_rho + rho_1*H_rho;
8116  nu = nu_0*ImH_mu + nu_1*H_mu;
8117 
8118  mu = rho_0*nu_0*ImH_mu + rho_1*nu_1*H_mu + use_numerical_viscosity*numerical_viscosity;
8119  //mu = rho*nu;
8120 
8121  mom_p_acc = p / mu;
8122  dmom_p_acc_p = 1. / mu;
8123 
8124  mom_u_acc = u / mu;
8125  dmom_u_acc_u = 1. / mu;
8126 
8127  mom_v_acc = v / mu;
8128  dmom_v_acc_v = 1. / mu;
8129 
8130  mom_w_acc = w / mu;
8131  dmom_w_acc_w = 1. / mu;
8132  }
8133  inline
8134  void evaluateTPDensityMassCoefficients(const double eps_rho,
8135  const double rho_0,
8136  const double rho_1,
8137  const double useVF,
8138  const double& vf,
8139  const double& phi,
8140  const double& p,
8141  const double& u,
8142  const double& v,
8143  const double& w,
8144  double& mom_p_acc,
8145  double& dmom_p_acc_p,
8146  double& mom_u_acc,
8147  double& dmom_u_acc_u,
8148  double& mom_v_acc,
8149  double& dmom_v_acc_v,
8150  double& mom_w_acc,
8151  double& dmom_w_acc_w)
8152  {
8153  double H_rho, ImH_rho, rho;
8154 
8155  H_rho = (1.0-useVF)*gf.H(eps_rho,phi) + useVF*fmin(1.0,fmax(0.0,vf));
8156  ImH_rho = (1.0-useVF)*gf.ImH(eps_rho,phi) + useVF*(1.0-fmin(1.0,fmax(0.0,vf)));
8157 
8158  rho = rho_0*ImH_rho + rho_1*H_rho;
8159 
8160  mom_p_acc = p * rho;
8161  dmom_p_acc_p = rho;
8162 
8163  mom_u_acc = u * rho;
8164  dmom_u_acc_u = rho;
8165 
8166  mom_v_acc = v * rho;
8167  dmom_v_acc_v = rho;
8168 
8169  mom_w_acc = w * rho;
8170  dmom_w_acc_w = rho;
8171  }
8172  inline
8173  void evaluateTPInvDensityLaplaceCoefficients(const double eps_rho,
8174  const double rho_0,
8175  const double rho_1,
8176  const double useVF,
8177  const double& vf,
8178  const double& phi,
8179  double mom_p_diff_ten[nSpace],
8180  double mom_u_diff_ten[nSpace],
8181  double mom_v_diff_ten[nSpace],
8182  double mom_w_diff_ten[nSpace])
8183  {
8184  double H_rho, ImH_rho, rho;
8185 
8186  H_rho = (1.0-useVF)*gf.H(eps_rho,phi) + useVF*fmin(1.0,fmax(0.0,vf));
8187  ImH_rho = (1.0-useVF)*gf.ImH(eps_rho,phi) + useVF*(1.0-fmin(1.0,fmax(0.0,vf)));
8188 
8189  rho = rho_0*ImH_rho + rho_1*H_rho;
8190 
8191  mom_p_diff_ten[0] = 1.0 / rho ;
8192  mom_p_diff_ten[1] = 1.0 / rho ;
8193  mom_p_diff_ten[2] = 1.0 / rho ;
8194 
8195  mom_u_diff_ten[0] = 1.0 / rho ;
8196  mom_u_diff_ten[1] = 1.0 / rho ;
8197  mom_u_diff_ten[2] = 1.0 / rho ;
8198 
8199  mom_v_diff_ten[0] = 1.0 / rho ;
8200  mom_v_diff_ten[1] = 1.0 / rho ;
8201  mom_v_diff_ten[2] = 1.0 / rho ;
8202 
8203  mom_w_diff_ten[0] = 1.0 / rho ;
8204  mom_w_diff_ten[1] = 1.0 / rho ;
8205  mom_w_diff_ten[2] = 1.0 / rho ;
8206  }
8207 
8209  {
8210  xt::pyarray<double>& mesh_trial_ref = args.array<double>("mesh_trial_ref");
8211  xt::pyarray<double>& mesh_grad_trial_ref = args.array<double>("mesh_grad_trial_ref");
8212  xt::pyarray<double>& mesh_dof = args.array<double>("mesh_dof");
8213  xt::pyarray<int>& mesh_l2g = args.array<int>("mesh_l2g");
8214  xt::pyarray<double>& dV_ref = args.array<double>("dV_ref");
8215  xt::pyarray<double>& p_trial_ref = args.array<double>("p_trial_ref");
8216  xt::pyarray<double>& p_grad_trial_ref = args.array<double>("p_grad_trial_ref");
8217  xt::pyarray<double>& vel_trial_ref = args.array<double>("vel_trial_ref");
8218  xt::pyarray<double>& vel_grad_trial_ref = args.array<double>("vel_grad_trial_ref");
8219  xt::pyarray<double>& elementDiameter = args.array<double>("elementDiameter");
8220  xt::pyarray<double>& nodeDiametersArray = args.array<double>("nodeDiametersArray");
8221  int nElements_global = args.scalar<int>("nElements_global");
8222  double useMetrics = args.scalar<double>("useMetrics");
8223  double epsFact_rho = args.scalar<double>("epsFact_rho");
8224  double epsFact_mu = args.scalar<double>("epsFact_mu");
8225  double rho_0 = args.scalar<double>("rho_0");
8226  double nu_0 = args.scalar<double>("nu_0");
8227  double rho_1 = args.scalar<double>("rho_1");
8228  double nu_1 = args.scalar<double>("nu_1");
8229  xt::pyarray<int>& vel_l2g = args.array<int>("vel_l2g");
8230  xt::pyarray<double>& u_dof = args.array<double>("u_dof");
8231  xt::pyarray<double>& v_dof = args.array<double>("v_dof");
8232  xt::pyarray<double>& w_dof = args.array<double>("w_dof");
8233  const double useVF = args.scalar<double>("useVF");
8234  xt::pyarray<double> &vf = args.array<double>("&vf");
8235  xt::pyarray<double> &phi = args.array<double>("&phi");
8236  xt::pyarray<int>& csrRowIndeces_p_p = args.array<int>("csrRowIndeces_p_p");
8237  xt::pyarray<int>& csrColumnOffsets_p_p = args.array<int>("csrColumnOffsets_p_p");
8238  xt::pyarray<int>& csrRowIndeces_u_u = args.array<int>("csrRowIndeces_u_u");
8239  xt::pyarray<int>& csrColumnOffsets_u_u = args.array<int>("csrColumnOffsets_u_u");
8240  xt::pyarray<int>& csrRowIndeces_v_v = args.array<int>("csrRowIndeces_v_v");
8241  xt::pyarray<int>& csrColumnOffsets_v_v = args.array<int>("csrColumnOffsets_v_v");
8242  xt::pyarray<int>& csrRowIndeces_w_w = args.array<int>("csrRowIndeces_w_w");
8243  xt::pyarray<int>& csrColumnOffsets_w_w = args.array<int>("csrColumnOffsets_w_w");
8244  xt::pyarray<double>& advection_matrix = args.array<double>("advection_matrix");
8245  gf.useExact = false;
8246  for (int eN=0 ; eN < nElements_global ; ++eN)
8247  {
8248  // local matrix allocations
8249  double eps_rho;
8250 
8251  double local_matrix_p_p[nDOF_test_element][nDOF_trial_element];
8252  double local_matrix_u_u[nDOF_test_element][nDOF_trial_element];
8253  double local_matrix_v_v[nDOF_test_element][nDOF_trial_element];
8254  double local_matrix_w_w[nDOF_test_element][nDOF_trial_element];
8255 
8256  // clear local matrix entries
8257  for (int i=0 ; i < nDOF_test_element ; ++i)
8258  for (int j=0 ; j < nDOF_trial_element ; ++j){
8259  local_matrix_p_p[i][j] = 0. ;
8260  local_matrix_u_u[i][j] = 0. ;
8261  local_matrix_v_v[i][j] = 0. ;
8262  }
8263 
8264  for (int k=0 ; k < nQuadraturePoints_element ; ++k){
8265 
8266  int eN_k = eN*nQuadraturePoints_element + k;
8267  int eN_nDOF_trial_element = eN*nDOF_trial_element;
8268 
8269  double jac[nSpace*nSpace];
8270  double jacInv[nSpace*nSpace];
8271  double u=0.0, v=0.0, w=0.0;
8272  double dmass_adv_p[nSpace], dmom_u_adv_u[nSpace], dmom_v_adv_v[nSpace], dmom_w_adv_w[nSpace];
8273  double p_grad_trial[nDOF_trial_element*nSpace],
8274  vel_grad_trial[nDOF_trial_element*nSpace];
8275  double p_test_dV[nDOF_test_element], vel_test_dV[nDOF_test_element];
8276  double p_grad_test_dV[nDOF_test_element*nSpace],
8277  vel_grad_test_dV[nDOF_test_element*nSpace];
8278  double jacDet, x, y, z, dV, h_phi;
8279 
8280  ck.calculateMapping_element(eN,
8281  k,
8282  mesh_dof.data(),
8283  mesh_l2g.data(),
8284  mesh_trial_ref.data(),
8285  mesh_grad_trial_ref.data(),
8286  jac,
8287  jacDet,
8288  jacInv,
8289  x,y,z);
8290 
8291  ck.calculateH_element(eN,
8292  k,
8293  nodeDiametersArray.data(),
8294  mesh_l2g.data(),
8295  mesh_trial_ref.data(),
8296  h_phi);
8297 
8298  dV = fabs(jacDet)*dV_ref.data()[k];
8299 
8300  eps_rho = epsFact_rho*(useMetrics*h_phi+(1.0-useMetrics)*elementDiameter.data()[eN]);
8301 
8302  ck.gradTrialFromRef(&p_grad_trial_ref.data()[k*nDOF_trial_element*nSpace],jacInv,p_grad_trial);
8303  ck.gradTrialFromRef(&vel_grad_trial_ref.data()[k*nDOF_trial_element*nSpace],jacInv,vel_grad_trial);
8304 
8305  ck.valFromDOF(u_dof.data(),&vel_l2g.data()[eN_nDOF_trial_element],&vel_trial_ref.data()[k*nDOF_trial_element],u);
8306  ck.valFromDOF(v_dof.data(),&vel_l2g.data()[eN_nDOF_trial_element],&vel_trial_ref.data()[k*nDOF_trial_element],v);
8307  ck.valFromDOF(w_dof.data(),&vel_l2g.data()[eN_nDOF_trial_element],&vel_trial_ref.data()[k*nDOF_trial_element],w);
8308 
8309  for (int j=0; j<nDOF_trial_element;++j)
8310  {
8311  p_test_dV[j] = p_trial_ref.data()[k*nDOF_trial_element+j]*dV;
8312  vel_test_dV[j] = vel_trial_ref.data()[k*nDOF_trial_element+j]*dV;
8313  for (int i=0; i<nSpace; ++i)
8314  {
8315  p_grad_test_dV[j*nSpace+i] = p_grad_trial[j*nSpace+i]*dV;
8316  vel_grad_test_dV[j*nSpace+i] = vel_grad_trial[j*nSpace+i]*dV;
8317  }
8318  }
8319 
8320 
8322  rho_0,
8323  rho_1,
8324  useVF,
8325  vf.data()[eN_k],
8326  phi.data()[eN_k],
8327  u,
8328  v,
8329  w,
8330  dmass_adv_p,
8331  dmom_u_adv_u,
8332  dmom_v_adv_v,
8333  dmom_w_adv_w);
8334 
8335 
8336  for(int i=0; i<nDOF_test_element;++i){
8337  int i_nSpace = i*nSpace;
8338 
8339  for(int j=0; j<nDOF_trial_element;++j){
8340 
8341  int j_nSpace = j*nSpace;
8342 
8343  local_matrix_p_p[i][j] -= ck.HamiltonianJacobian_weak(dmass_adv_p,&p_grad_test_dV[i_nSpace],p_trial_ref.data()[j]);
8344  //local_matrix_p_p[i][j] += ck.HamiltonianJacobian_weak(dmass_adv_p ,&p_grad_trial[j_nSpace] ,p_test_dV[i]);
8345  local_matrix_u_u[i][j] += ck.HamiltonianJacobian_weak(dmom_u_adv_u,&vel_grad_trial[j_nSpace],vel_test_dV[i]);
8346  local_matrix_v_v[i][j] += ck.HamiltonianJacobian_weak(dmom_v_adv_v,&vel_grad_trial[j_nSpace],vel_test_dV[i]);
8347  local_matrix_w_w[i][j] += ck.HamiltonianJacobian_weak(dmom_w_adv_w,&vel_grad_trial[j_nSpace],vel_test_dV[i]);
8348  }
8349  }
8350 
8351 
8352  }//k
8353 
8354  // Write local matrix information into global system
8355  for (int i=0 ; i < nDOF_test_element ; ++i)
8356  {
8357  int eN_i = eN*nDOF_test_element + i;
8358  for (int j=0 ; j < nDOF_trial_element ; ++j)
8359  {
8360  int eN_i_j = eN_i*nDOF_trial_element + j;
8361  advection_matrix.data()[csrRowIndeces_p_p.data()[eN_i] + csrColumnOffsets_p_p.data()[eN_i_j]] += local_matrix_p_p[i][j] ;
8362  advection_matrix.data()[csrRowIndeces_u_u.data()[eN_i] + csrColumnOffsets_u_u.data()[eN_i_j]] += local_matrix_u_u[i][j] ;
8363  advection_matrix.data()[csrRowIndeces_v_v.data()[eN_i] + csrColumnOffsets_v_v.data()[eN_i_j]] += local_matrix_v_v[i][j] ;
8364  advection_matrix.data()[csrRowIndeces_w_w.data()[eN_i] + csrColumnOffsets_w_w.data()[eN_i_j]] += local_matrix_w_w[i][j] ;
8365  }
8366  }
8367 
8368  }//eN
8369  } // getTwoPhaseAdvectionOperator
8370 
8372  {
8373  xt::pyarray<double>& mesh_trial_ref = args.array<double>("mesh_trial_ref");
8374  xt::pyarray<double>& mesh_grad_trial_ref = args.array<double>("mesh_grad_trial_ref");
8375  xt::pyarray<double>& mesh_dof = args.array<double>("mesh_dof");
8376  xt::pyarray<int>& mesh_l2g = args.array<int>("mesh_l2g");
8377  xt::pyarray<double>& dV_ref = args.array<double>("dV_ref");
8378  xt::pyarray<double>& p_grad_trial_ref = args.array<double>("p_grad_trial_ref");
8379  xt::pyarray<double>& vel_grad_trial_ref = args.array<double>("vel_grad_trial_ref");
8380  xt::pyarray<double>& elementDiameter = args.array<double>("elementDiameter");
8381  xt::pyarray<double>& nodeDiametersArray = args.array<double>("nodeDiametersArray");
8382  int nElements_global = args.scalar<int>("nElements_global");
8383  double useMetrics = args.scalar<double>("useMetrics");
8384  double epsFact_rho = args.scalar<double>("epsFact_rho");
8385  double epsFact_mu = args.scalar<double>("epsFact_mu");
8386  double rho_0 = args.scalar<double>("rho_0");
8387  double nu_0 = args.scalar<double>("nu_0");
8388  double rho_1 = args.scalar<double>("rho_1");
8389  double nu_1 = args.scalar<double>("nu_1");
8390  xt::pyarray<int>& p_l2g = args.array<int>("p_l2g");
8391  xt::pyarray<int>& vel_l2g = args.array<int>("vel_l2g");
8392  xt::pyarray<double>& p_dof = args.array<double>("p_dof");
8393  xt::pyarray<double>& u_dof = args.array<double>("u_dof");
8394  xt::pyarray<double>& v_dof = args.array<double>("v_dof");
8395  xt::pyarray<double>& w_dof = args.array<double>("w_dof");
8396  const double useVF = args.scalar<double>("useVF");
8397  xt::pyarray<double>& vf = args.array<double>("vf");
8398  xt::pyarray<double>& phi = args.array<double>("phi");
8399  xt::pyarray<int>& sdInfo_p_p_rowptr = args.array<int>("sdInfo_p_p_rowptr");
8400  xt::pyarray<int>& sdInfo_p_p_colind = args.array<int>("sdInfo_p_p_colind");
8401  xt::pyarray<int>& sdInfo_u_u_rowptr = args.array<int>("sdInfo_u_u_rowptr");
8402  xt::pyarray<int>& sdInfo_u_u_colind = args.array<int>("sdInfo_u_u_colind");
8403  xt::pyarray<int>& sdInfo_v_v_rowptr = args.array<int>("sdInfo_v_v_rowptr");
8404  xt::pyarray<int>& sdInfo_v_v_colind = args.array<int>("sdInfo_v_v_colind");
8405  xt::pyarray<int>& sdInfo_w_w_rowptr = args.array<int>("sdInfo_w_w_rowptr");
8406  xt::pyarray<int>& sdInfo_w_w_colind = args.array<int>("sdInfo_w_w_colind");
8407  xt::pyarray<int>& csrRowIndeces_p_p = args.array<int>("csrRowIndeces_p_p");
8408  xt::pyarray<int>& csrColumnOffsets_p_p = args.array<int>("csrColumnOffsets_p_p");
8409  xt::pyarray<int>& csrRowIndeces_u_u = args.array<int>("csrRowIndeces_u_u");
8410  xt::pyarray<int>& csrColumnOffsets_u_u = args.array<int>("csrColumnOffsets_u_u");
8411  xt::pyarray<int>& csrRowIndeces_v_v = args.array<int>("csrRowIndeces_v_v");
8412  xt::pyarray<int>& csrColumnOffsets_v_v = args.array<int>("csrColumnOffsets_v_v");
8413  xt::pyarray<int>& csrRowIndeces_w_w = args.array<int>("csrRowIndeces_w_w");
8414  xt::pyarray<int>& csrColumnOffsets_w_w = args.array<int>("csrColumnOffsets_w_w");
8415  xt::pyarray<double>& laplace_matrix = args.array<double>("laplace_matrix");
8416  gf.useExact = false;
8417  for (int eN=0 ; eN < nElements_global ; ++eN)
8418  {
8419  // local matrix allocations
8420  double eps_rho, eps_mu;
8421 
8422  double local_matrix_p_p[nDOF_test_element][nDOF_trial_element];
8423  double local_matrix_u_u[nDOF_test_element][nDOF_trial_element];
8424  double local_matrix_v_v[nDOF_test_element][nDOF_trial_element];
8425  double local_matrix_w_w[nDOF_test_element][nDOF_trial_element];
8426 
8427  // reset local matrix entries
8428  for (int i=0 ; i < nDOF_test_element ; ++i)
8429  for (int j=0 ; j < nDOF_trial_element ; ++j){
8430  // set local matrices to 0
8431  local_matrix_p_p[i][j] = 0.;
8432  local_matrix_u_u[i][j] = 0.;
8433  local_matrix_v_v[i][j] = 0.;
8434  local_matrix_w_w[i][j] = 0.;
8435  }
8436 
8437  // Loop over quadrature points on element
8438  for (int k=0 ; k < nQuadraturePoints_element; ++k){
8439 
8440  int eN_k = eN*nQuadraturePoints_element + k;
8441  int eN_nDOF_trial_element = eN*nDOF_trial_element;
8442 
8443  double grad_p[nSpace], grad_u[nSpace], grad_v[nSpace], grad_w[nSpace];
8444  double jac[nSpace*nSpace];
8445  double jacInv[nSpace*nSpace];
8446  double mom_pp_diff_ten[nSpace];
8447  double mom_uu_diff_ten[nSpace];
8448  double mom_vv_diff_ten[nSpace];
8449  double mom_ww_diff_ten[nSpace];
8450  double p_grad_trial[nDOF_trial_element*nSpace],
8451  vel_grad_trial[nDOF_trial_element*nSpace];
8452  double p_grad_test_dV[nDOF_test_element*nSpace],
8453  vel_grad_test_dV[nDOF_test_element*nSpace];
8454  double jacDet, x, y, z, dV, h_phi;
8455 
8456  ck.calculateMapping_element(eN,
8457  k,
8458  mesh_dof.data(),
8459  mesh_l2g.data(),
8460  mesh_trial_ref.data(),
8461  mesh_grad_trial_ref.data(),
8462  jac,
8463  jacDet,
8464  jacInv,
8465  x,y,z);
8466 
8467  ck.calculateH_element(eN,
8468  k,
8469  nodeDiametersArray.data(),
8470  mesh_l2g.data(),
8471  mesh_trial_ref.data(),
8472  h_phi);
8473 
8474  dV = fabs(jacDet)*dV_ref.data()[k];
8475 
8476  eps_mu = epsFact_mu * (useMetrics*h_phi+(1.0-useMetrics)*elementDiameter.data()[eN]);
8477  eps_rho = epsFact_rho * (useMetrics*h_phi+(1.0-useMetrics)*elementDiameter.data()[eN]);
8478 
8479  ck.gradTrialFromRef(&p_grad_trial_ref.data()[k*nDOF_trial_element*nSpace],jacInv,p_grad_trial);
8480  ck.gradTrialFromRef(&vel_grad_trial_ref.data()[k*nDOF_trial_element*nSpace],jacInv,vel_grad_trial);
8481 
8482  ck.gradFromDOF(p_dof.data(),&p_l2g.data()[eN_nDOF_trial_element],p_grad_trial,grad_p);
8483  ck.gradFromDOF(u_dof.data(),&vel_l2g.data()[eN_nDOF_trial_element],vel_grad_trial,grad_u);
8484  ck.gradFromDOF(v_dof.data(),&vel_l2g.data()[eN_nDOF_trial_element],vel_grad_trial,grad_v);
8485  ck.gradFromDOF(w_dof.data(),&vel_l2g.data()[eN_nDOF_trial_element],vel_grad_trial,grad_w);
8486 
8487  for (int j=0; j<nDOF_trial_element;++j)
8488  for (int i=0; i<nSpace; ++i)
8489  {
8490  p_grad_test_dV[j*nSpace+i] = p_grad_trial[j*nSpace+i]*dV;
8491  vel_grad_test_dV[j*nSpace+i] = vel_grad_trial[j*nSpace+i]*dV;
8492  }
8493 
8495  rho_0,
8496  rho_1,
8497  useVF,
8498  vf.data()[eN_k],
8499  phi.data()[eN_k],
8500  mom_pp_diff_ten,
8501  mom_uu_diff_ten,
8502  mom_vv_diff_ten,
8503  mom_ww_diff_ten);
8504 
8505  // loop over test and weighted trial functions to evaluate local inner products
8506  for (int i=0 ; i < nDOF_test_element ; ++i)
8507  {
8508  int i_nSpace = i*nSpace ;
8509  for (int j=0; j < nDOF_trial_element ; ++j){
8510  int j_nSpace = j*nSpace ;
8511  /* local_matrix_p_p[i][j] += ck.SimpleDiffusionJacobian_weak(sdInfo_p_p_rowptr.data(), */
8512  /* sdInfo_p_p_colind.data(), */
8513  /* mom_pp_diff_ten, */
8514  /* &p_grad_trial[j_nSpace], */
8515  /* &p_grad_test_dV[i_nSpace]); */
8516 
8517  /* local_matrix_u_u[i][j] += ck.SimpleDiffusionJacobian_weak(sdInfo_u_u_rowptr.data(), */
8518  /* sdInfo_u_u_colind.data(), */
8519  /* mom_uu_diff_ten, */
8520  /* &vel_grad_trial[j_nSpace], */
8521  /* &vel_grad_test_dV[i_nSpace]); */
8522 
8523  /* local_matrix_v_v[i][j] += ck.SimpleDiffusionJacobian_weak(sdInfo_v_v_rowptr.data(), */
8524  /* sdInfo_v_v_colind.data(), */
8525  /* mom_vv_diff_ten, */
8526  /* &vel_grad_trial[j_nSpace], */
8527  /* &vel_grad_test_dV[i_nSpace]); */
8528  local_matrix_p_p[i][j] += ck.NumericalDiffusionJacobian(mom_pp_diff_ten[0],
8529  &p_grad_trial[j_nSpace],
8530  &p_grad_test_dV[i_nSpace]);
8531 
8532  local_matrix_u_u[i][j] += ck.NumericalDiffusionJacobian(mom_uu_diff_ten[0],
8533  &vel_grad_trial[j_nSpace],
8534  &vel_grad_test_dV[i_nSpace]);
8535 
8536  local_matrix_v_v[i][j] += ck.NumericalDiffusionJacobian(mom_vv_diff_ten[0],
8537  &vel_grad_trial[j_nSpace],
8538  &vel_grad_test_dV[i_nSpace]);
8539 
8540  local_matrix_w_w[i][j] += ck.NumericalDiffusionJacobian(mom_ww_diff_ten[0],
8541  &vel_grad_trial[j_nSpace],
8542  &vel_grad_test_dV[i_nSpace]);
8543 
8544  } // j
8545  } // i
8546 
8547  } // k
8548 
8549  // Write local matrix information into global system
8550  for (int i=0 ; i < nDOF_test_element ; ++i)
8551  {
8552  int eN_i = eN*nDOF_test_element + i;
8553  for (int j=0 ; j < nDOF_trial_element ; ++j)
8554  {
8555  int eN_i_j = eN_i*nDOF_trial_element + j;
8556  laplace_matrix.data()[csrRowIndeces_p_p.data()[eN_i] + csrColumnOffsets_p_p.data()[eN_i_j]] += local_matrix_p_p[i][j] ;
8557  laplace_matrix.data()[csrRowIndeces_u_u.data()[eN_i] + csrColumnOffsets_u_u.data()[eN_i_j]] += local_matrix_u_u[i][j] ;
8558  laplace_matrix.data()[csrRowIndeces_v_v.data()[eN_i] + csrColumnOffsets_v_v.data()[eN_i_j]] += local_matrix_v_v[i][j] ;
8559  laplace_matrix.data()[csrRowIndeces_w_w.data()[eN_i] + csrColumnOffsets_w_w.data()[eN_i_j]] += local_matrix_w_w[i][j] ;
8560  }
8561  }
8562 
8563  } // eN
8564  }
8565 
8567  {
8568  int scale_type = args.scalar<int>("scale_type");
8569  int use_numerical_viscosity = args.scalar<int>("use_numerical_viscosity");
8570  int lumped = args.scalar<int>("lumped");
8571  xt::pyarray<double> &mesh_trial_ref = args.array<double>("&mesh_trial_ref");
8572  xt::pyarray<double> &mesh_grad_trial_ref = args.array<double>("&mesh_grad_trial_ref");
8573  xt::pyarray<double> &mesh_dof = args.array<double>("&mesh_dof");
8574  xt::pyarray<int>& mesh_l2g = args.array<int>("mesh_l2g");
8575  xt::pyarray<double>& dV_ref = args.array<double>("dV_ref");
8576  xt::pyarray<double>& p_trial_ref = args.array<double>("p_trial_ref");
8577  xt::pyarray<double>& p_test_ref = args.array<double>("p_test_ref");
8578  xt::pyarray<double>& vel_trial_ref = args.array<double>("vel_trial_ref");
8579  xt::pyarray<double>& vel_test_ref = args.array<double>("vel_test_ref");
8580  xt::pyarray<double>& elementDiameter = args.array<double>("elementDiameter");
8581  xt::pyarray<double>& nodeDiametersArray = args.array<double>("nodeDiametersArray");
8582  xt::pyarray<double>& numerical_viscosity = args.array<double>("numerical_viscosity");
8583  int nElements_global = args.scalar<int>("nElements_global");
8584  double useMetrics = args.scalar<double>("useMetrics");
8585  double epsFact_rho = args.scalar<double>("epsFact_rho");
8586  double epsFact_mu = args.scalar<double>("epsFact_mu");
8587  double rho_0 = args.scalar<double>("rho_0");
8588  double nu_0 = args.scalar<double>("nu_0");
8589  double rho_1 = args.scalar<double>("rho_1");
8590  double nu_1 = args.scalar<double>("nu_1");
8591  xt::pyarray<int>& p_l2g = args.array<int>("p_l2g");
8592  xt::pyarray<int>& vel_l2g = args.array<int>("vel_l2g");
8593  xt::pyarray<double>& p_dof = args.array<double>("p_dof");
8594  xt::pyarray<double>& u_dof = args.array<double>("u_dof");
8595  xt::pyarray<double>& v_dof = args.array<double>("v_dof");
8596  xt::pyarray<double>& w_dof = args.array<double>("w_dof");
8597  const double useVF = args.scalar<double>("useVF");
8598  xt::pyarray<double>& vf = args.array<double>("vf");
8599  xt::pyarray<double>& phi = args.array<double>("phi");
8600  xt::pyarray<int>& csrRowIndeces_p_p = args.array<int>("csrRowIndeces_p_p");
8601  xt::pyarray<int>& csrColumnOffsets_p_p = args.array<int>("csrColumnOffsets_p_p");
8602  xt::pyarray<int>& csrRowIndeces_u_u = args.array<int>("csrRowIndeces_u_u");
8603  xt::pyarray<int>& csrColumnOffsets_u_u = args.array<int>("csrColumnOffsets_u_u");
8604  xt::pyarray<int>& csrRowIndeces_v_v = args.array<int>("csrRowIndeces_v_v");
8605  xt::pyarray<int>& csrColumnOffsets_v_v = args.array<int>("csrColumnOffsets_v_v");
8606  xt::pyarray<int>& csrRowIndeces_w_w = args.array<int>("csrRowIndeces_w_w");
8607  xt::pyarray<int>& csrColumnOffsets_w_w = args.array<int>("csrColumnOffsets_w_w");
8608  xt::pyarray<double>& mass_matrix = args.array<double>("mass_matrix");
8609  // Step 1.1 - Initialize local matrix
8610 
8611  for (int eN=0 ; eN < nElements_global; ++eN){
8612 
8613  double local_matrix_p_p[nDOF_test_element][nDOF_trial_element];
8614  double local_matrix_u_u[nDOF_test_element][nDOF_trial_element];
8615  double local_matrix_v_v[nDOF_test_element][nDOF_trial_element];
8616  double local_matrix_w_w[nDOF_test_element][nDOF_trial_element];
8617  double eps_rho, eps_mu;
8618 
8619  // reset local matrix entries
8620  for (int i=0; i<nDOF_test_element; ++i)
8621  for (int j=0; j<nDOF_trial_element; ++j){
8622  local_matrix_p_p[i][j] = 0.0 ;
8623  local_matrix_u_u[i][j] = 0.0 ;
8624  local_matrix_v_v[i][j] = 0.0 ;
8625  local_matrix_w_w[i][j] = 0.0 ;
8626  }
8627  // Step 1.2 - Loop over quadrature points on element
8628  for (int k=0 ; k < nQuadraturePoints_element; ++k){
8629 
8630  int eN_k = eN*nQuadraturePoints_element+k;
8631  int eN_nDOF_trial_element = eN*nDOF_trial_element;
8632  // *** Local storage arrays ***
8633  double p = 0.0, u = 0.0, v= 0.0 , w= 0.0 ;
8634  double dV;
8635  double mom_p_acc = 0.0, dmom_p_acc_p = 0.0;
8636  double mom_u_acc = 0.0, dmom_u_acc_u = 0.0;
8637  double mom_v_acc = 0.0, dmom_v_acc_v = 0.0;
8638  double mom_w_acc = 0.0, dmom_w_acc_w = 0.0;
8639  double jac[nSpace*nSpace] ;
8640  double jacInv[nSpace*nSpace] ;
8641  double jacDet,x,y,z ;
8642  double p_test_dV[nDOF_test_element], vel_test_dV[nDOF_test_element];
8643  double h_phi;
8644 
8645  // Step 1.2.1 Calculate integration weights
8646 
8647  ck.calculateMapping_element(eN,
8648  k,
8649  mesh_dof.data(),
8650  mesh_l2g.data(),
8651  mesh_trial_ref.data(),
8652  mesh_grad_trial_ref.data(),
8653  jac,
8654  jacDet,
8655  jacInv,
8656  x,y,z);
8657 
8658  ck.calculateH_element(eN,
8659  k,
8660  nodeDiametersArray.data(),
8661  mesh_l2g.data(),
8662  mesh_trial_ref.data(),
8663  h_phi);
8664 
8665  dV = fabs(jacDet)*dV_ref.data()[k];
8666 
8667  ck.valFromDOF(p_dof.data(),&p_l2g.data()[eN_nDOF_trial_element],&p_trial_ref.data()[k*nDOF_trial_element],p);
8668  ck.valFromDOF(u_dof.data(),&vel_l2g.data()[eN_nDOF_trial_element],&vel_trial_ref.data()[k*nDOF_trial_element],u);
8669  ck.valFromDOF(v_dof.data(),&vel_l2g.data()[eN_nDOF_trial_element],&vel_trial_ref.data()[k*nDOF_trial_element],v);
8670  ck.valFromDOF(w_dof.data(),&vel_l2g.data()[eN_nDOF_trial_element],&vel_trial_ref.data()[k*nDOF_trial_element],w);
8671 
8672  eps_rho = epsFact_rho*(useMetrics*h_phi+(1.0-useMetrics)*elementDiameter.data()[eN]);
8673  eps_mu = epsFact_mu * (useMetrics*h_phi+(1.0-useMetrics)*elementDiameter.data()[eN]);
8674  // Step 1.2.2 Scale test functions with integration weights.
8675  for (int j=0 ; j<nDOF_trial_element ; ++j){
8676  p_test_dV[j] = p_test_ref.data()[k*nDOF_trial_element + j]*dV;
8677  vel_test_dV[j] = vel_test_ref.data()[k*nDOF_trial_element + j] * dV;
8678  }
8679 
8680  // Step 1.2.2 Evaluate coefficients
8681  if (scale_type==0){
8682  evaluateTPInvViscosityMassCoefficients(use_numerical_viscosity,
8683  numerical_viscosity.data()[eN_k],
8684  eps_rho,
8685  eps_mu,
8686  rho_0,
8687  nu_0,
8688  rho_1,
8689  nu_1,
8690  useVF,
8691  vf.data()[eN_k],
8692  phi.data()[eN_k],
8693  p,
8694  u,
8695  v,
8696  w,
8697  mom_p_acc,
8698  dmom_p_acc_p,
8699  mom_u_acc,
8700  dmom_u_acc_u,
8701  mom_v_acc,
8702  dmom_v_acc_v,
8703  mom_w_acc,
8704  dmom_w_acc_w) ; }
8705  else if(scale_type==1){
8707  rho_0,
8708  rho_1,
8709  useVF,
8710  vf.data()[eN_k],
8711  phi.data()[eN_k],
8712  p,
8713  u,
8714  v,
8715  w,
8716  mom_p_acc,
8717  dmom_p_acc_p,
8718  mom_u_acc,
8719  dmom_u_acc_u,
8720  mom_v_acc,
8721  dmom_v_acc_v,
8722  mom_w_acc,
8723  dmom_w_acc_w) ;
8724  }
8725 
8726  // Step 1.2.3 Loop over test and weighted trial functions
8727  // to evaluate local inner product contrubtions
8728  for (int i=0 ; i < nDOF_test_element; ++i)
8729  {
8730  int i_nSpace = i*nSpace;
8731  for (int j=0 ; j < nDOF_trial_element; ++j)
8732  {
8733  int j_nSpace = j*nSpace;
8734  local_matrix_p_p[i][j] += ck.MassJacobian_weak(dmom_p_acc_p,
8735  p_trial_ref.data()[k*nDOF_trial_element+j],
8736  p_test_dV[i]) ;
8737  local_matrix_u_u[i][j] += ck.MassJacobian_weak(dmom_u_acc_u,
8738  vel_trial_ref.data()[k*nDOF_trial_element+j],
8739  vel_test_dV[i]) ;
8740  local_matrix_v_v[i][j] += ck.MassJacobian_weak(dmom_v_acc_v,
8741  vel_trial_ref.data()[k*nDOF_trial_element+j],
8742  vel_test_dV[i]) ;
8743  local_matrix_w_w[i][j] += ck.MassJacobian_weak(dmom_w_acc_w,
8744  vel_trial_ref.data()[k*nDOF_trial_element+j],
8745  vel_test_dV[i]) ;
8746  }//j
8747  }//i
8748 
8749 
8750  } // k
8751 
8752  // Step 1.3 - Write local matrix information into global system
8753  for (int i=0 ; i<nDOF_test_element; ++i)
8754  {
8755  int eN_i = eN*nDOF_test_element+i;
8756  int eN_i_i = eN_i*nDOF_trial_element + i;
8757  for (int j=0 ; j < nDOF_trial_element; ++j)
8758  {
8759  int eN_i_j = eN_i*nDOF_trial_element + j;
8760  if (lumped)
8761  {
8762  mass_matrix.data()[csrRowIndeces_p_p.data()[eN_i] + csrColumnOffsets_p_p.data()[eN_i_i]] += local_matrix_p_p[i][j] ;
8763  mass_matrix.data()[csrRowIndeces_u_u.data()[eN_i] + csrColumnOffsets_u_u.data()[eN_i_i]] += local_matrix_u_u[i][j] ;
8764  mass_matrix.data()[csrRowIndeces_v_v.data()[eN_i] + csrColumnOffsets_v_v.data()[eN_i_i]] += local_matrix_v_v[i][j] ;
8765  mass_matrix.data()[csrRowIndeces_w_w.data()[eN_i] + csrColumnOffsets_w_w.data()[eN_i_i]] += local_matrix_w_w[i][j] ;
8766  }
8767  else
8768  {
8769  mass_matrix.data()[csrRowIndeces_p_p.data()[eN_i] + csrColumnOffsets_p_p.data()[eN_i_j]] += local_matrix_p_p[i][j] ;
8770  mass_matrix.data()[csrRowIndeces_u_u.data()[eN_i] + csrColumnOffsets_u_u.data()[eN_i_j]] += local_matrix_u_u[i][j] ;
8771  mass_matrix.data()[csrRowIndeces_v_v.data()[eN_i] + csrColumnOffsets_v_v.data()[eN_i_j]] += local_matrix_v_v[i][j] ;
8772  mass_matrix.data()[csrRowIndeces_w_w.data()[eN_i] + csrColumnOffsets_w_w.data()[eN_i_j]] += local_matrix_w_w[i][j] ;
8773  }
8774  }
8775  }
8776  } // eN
8777  }
8778  };//RANS2P
8779 
8780  inline RANS2P_base* newRANS2P(int nSpaceIn,
8781  int nQuadraturePoints_elementIn,
8782  int nDOF_mesh_trial_elementIn,
8783  int nDOF_trial_elementIn,
8784  int nDOF_test_elementIn,
8785  int nDOF_v_trial_elementIn,
8786  int nDOF_v_test_elementIn,
8787  int nQuadraturePoints_elementBoundaryIn,
8788  int CompKernelFlag)
8789  {
8790  return proteus::chooseAndAllocateDiscretization<RANS2P_base,RANS2P,CompKernel,CompKernel>(nSpaceIn,
8791  nQuadraturePoints_elementIn,
8792  nDOF_mesh_trial_elementIn,
8793  nDOF_trial_elementIn,
8794  nDOF_test_elementIn,
8795  nDOF_v_trial_elementIn,
8796  nDOF_v_test_elementIn,
8797  nQuadraturePoints_elementBoundaryIn,
8798  CompKernelFlag);
8799  }
8800 }//proteus
8801 
8802 #endif
proteus::RANS2P::evaluateCoefficients
void evaluateCoefficients(const double NONCONSERVATIVE_FORM, const double sigma, const double rho, double nu, 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 &kappa, const double porosity, const double phi_solid, const double p_old, const double u_old, const double v_old, const double w_old, const double grad_p_old[nSpace], const double grad_u_old[nSpace], const double grad_v_old[nSpace], const double grad_w_old[nSpace], 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 LAG_LES, double &eddy_viscosity, double &eddy_viscosity_last, 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 &dmom_u_ham_u, double &dmom_u_ham_v, double &dmom_u_ham_w, double &mom_v_ham, double dmom_v_ham_grad_p[nSpace], double dmom_v_ham_grad_v[nSpace], double &dmom_v_ham_u, double &dmom_v_ham_v, double &dmom_v_ham_w, double &mom_w_ham, double dmom_w_ham_grad_p[nSpace], double dmom_w_ham_grad_w[nSpace], double &dmom_w_ham_u, double &dmom_w_ham_v, double &dmom_w_ham_w, double forcex, double forcey, double forcez)
Definition: RANS2P.h:335
inertial_term
const double inertial_term
Definition: RANS2P.h:28
sign
#define sign(x, y)
Definition: jf.h:44
proteus::RANS2P::updateSolidParticleTerms
void updateSolidParticleTerms(int particle_index, const double NONCONSERVATIVE_FORM, 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, const int use_ball_as_particle, const double *ball_center, const double *ball_radius, const double *ball_velocity, const double *ball_angular_velocity, const double *ball_density, 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 &mass_source, 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 dmom_u_ham_grad_v[nSpace], double dmom_u_ham_grad_w[nSpace], double &dmom_u_ham_u, double &dmom_u_ham_v, double &dmom_u_ham_w, double &mom_v_ham, double dmom_v_ham_grad_u[nSpace], double dmom_v_ham_grad_v[nSpace], double dmom_v_ham_grad_w[nSpace], double &dmom_v_ham_u, double &dmom_v_ham_v, double &dmom_v_ham_w, double &mom_w_ham, double dmom_w_ham_grad_u[nSpace], double dmom_w_ham_grad_v[nSpace], double dmom_w_ham_grad_w[nSpace], double &dmom_w_ham_u, double &dmom_w_ham_v, double &dmom_w_ham_w, double &mass_ham, double &dmass_ham_u, double &dmass_ham_v, double &dmass_ham_w, double *particle_netForces, double *particle_netMoments, double *particle_surfaceArea)
Definition: RANS2P.h:856
proteus::RANS2P::calculateJacobian
void calculateJacobian(arguments_dict &args)
Definition: RANS2P.h:5068
proteus::RANS2P::nDOF_test_X_trial_element
const int nDOF_test_X_trial_element
Definition: RANS2P.h:316
w
#define w(x)
Definition: jf.h:22
proteus::RANS2P::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: RANS2P.h:1400
proteus::RANS2P_base::calculateVelocityAverage
virtual void calculateVelocityAverage(arguments_dict &args)=0
proteus::RANS2P::nDOF_v_test_X_v_trial_element
const int nDOF_v_test_X_v_trial_element
Definition: RANS2P.h:319
DM3
const double DM3
Definition: RANS2P.h:27
proteus::RANS2P::get_normal_to_ith_ball
void get_normal_to_ith_ball(int n_balls, const double *ball_center, const double *ball_radius, int I, const double x, const double y, const double z, double &nx, double &ny, double &nz)
Definition: RANS2P.h:813
proteus::RANS2P::evaluateTPInvViscosityMassCoefficients
void evaluateTPInvViscosityMassCoefficients(const int use_numerical_viscosity, const double numerical_viscosity, const double eps_rho, const double eps_mu, const double rho_0, double nu_0, const double rho_1, double nu_1, const double useVF, const double &vf, const double &phi, const double &p, const double &u, const double &v, const double &w, double &mom_p_acc, double &dmom_p_acc_p, 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)
Definition: RANS2P.h:8082
proteus::RANS2P_base::step6DOF
void step6DOF(arguments_dict &args)
Definition: RANS2P.h:134
proteus::RANS2P::getTwoPhaseInvScaledLaplaceOperator
void getTwoPhaseInvScaledLaplaceOperator(arguments_dict &args)
Definition: RANS2P.h:8371
proteus::RANS2P_base::~RANS2P_base
virtual ~RANS2P_base()
Definition: RANS2P.h:127
proteus::RANS2P::ifem_boundaries
std::set< int > ifem_boundaries
Definition: RANS2P.h:312
proteus::RANS2P::calculateSubgridErrorDerivatives_tauRes
void calculateSubgridErrorDerivatives_tauRes(const double &tau_p, const double &tau_v, const double dpdeResidualP_du[nDOF_v_trial_element], const double dpdeResidualP_dv[nDOF_v_trial_element], const double dpdeResidualP_dw[nDOF_v_trial_element], const double dpdeResidualU_dp[nDOF_trial_element], const double dpdeResidualU_du[nDOF_v_trial_element], const double dpdeResidualV_dp[nDOF_trial_element], const double dpdeResidualV_dv[nDOF_v_trial_element], const double dpdeResidualW_dp[nDOF_trial_element], const double dpdeResidualW_dw[nDOF_v_trial_element], double dsubgridErrorP_du[nDOF_v_trial_element], double dsubgridErrorP_dv[nDOF_v_trial_element], double dsubgridErrorP_dw[nDOF_v_trial_element], double dsubgridErrorU_dp[nDOF_trial_element], double dsubgridErrorU_du[nDOF_v_trial_element], double dsubgridErrorV_dp[nDOF_trial_element], double dsubgridErrorV_dv[nDOF_v_trial_element], double dsubgridErrorW_dp[nDOF_trial_element], double dsubgridErrorW_dw[nDOF_v_trial_element])
Definition: RANS2P.h:1468
proteus::RANS2P::getTwoPhaseAdvectionOperator
void getTwoPhaseAdvectionOperator(arguments_dict &args)
Definition: RANS2P.h:8208
proteus::RANS2P_base
Definition: RANS2P.h:125
L
Double L
Definition: Headers.h:72
proteus::newRANS2P
RANS2P_base * newRANS2P(int nSpaceIn, int nQuadraturePoints_elementIn, int nDOF_mesh_trial_elementIn, int nDOF_trial_elementIn, int nDOF_test_elementIn, int nDOF_v_trial_elementIn, int nDOF_v_test_elementIn, int nQuadraturePoints_elementBoundaryIn, int CompKernelFlag)
Definition: RANS2P.h:8780
n
Int n
Definition: Headers.h:28
proteus::enorm
double enorm(double *v)
Definition: RANS2P.h:31
df
double df(double C, double b, double a, int q, int r)
Definition: analyticalSolutions.c:2209
proteus::RANS2P::get_distance_to_ith_ball
void get_distance_to_ith_ball(int n_balls, const double *ball_center, const double *ball_radius, int I, const double x, const double y, const double z, double &distance)
Definition: RANS2P.h:803
CompKernel.h
proteus::arguments_dict::scalar
T & scalar(const std::string &key)
proteus::RANS2P::ck
CompKernelType ck
Definition: RANS2P.h:320
proteus::arguments_dict::array
xt::pyarray< T > & array(const std::string &key)
proteus::RANS2P::gf
GeneralizedFunctions< nSpace, 3, nQuadraturePoints_element, nQuadraturePoints_elementBoundary > gf
Definition: RANS2P.h:322
proteus::RANS2P::updateTurbulenceClosure
void updateTurbulenceClosure(const double NONCONSERVATIVE_FORM, 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: RANS2P.h:1274
vel
void vel(double rS, double norm_v, double r, double theta, double *vR, double *vTHETA)
Definition: analyticalSolutions.c:2163
dgetrf_
int dgetrf_(int *m, int *n, double *a, int *lda, int *ipiv, int *info)
ZEROVEC
#define ZEROVEC
Definition: RANS2P.h:22
proteus::RANS2P::exteriorNumericalAdvectiveFlux
void exteriorNumericalAdvectiveFlux(const double NONCONSERVATIVE_FORM, 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 &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 dham_grad[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)
Definition: RANS2P.h:1516
H
Double H
Definition: Headers.h:65
vx
Double vx
Definition: Headers.h:97
DM2
const double DM2
Definition: RANS2P.h:26
proteus::F6DOF
void F6DOF(double DT, double mass, double *Iref, double *last_u, double *FT, double *last_FT, double *last_mom, double *u, double *mom, double *r, double *J)
Definition: RANS2P.h:42
nu_0
double nu_0
Definition: ErrorResidualMethod.cpp:22
proteus::RANS2P::updateDarcyForchheimerTerms_Ergun
void updateDarcyForchheimerTerms_Ergun(const double NONCONSERVATIVE_FORM, 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 u, const double v, const double w, const double uStar, const double vStar, const double wStar, const double eps_porous, const double phi_porous, const double u_porous, const double v_porous, const double w_porous, 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])
Definition: RANS2P.h:1192
proteus::RANS2P::gf_s
GeneralizedFunctions< nSpace, 3, nQuadraturePoints_element, nQuadraturePoints_elementBoundary > gf_s
Definition: RANS2P.h:324
v
Double v
Definition: Headers.h:95
proteus::RANS2P::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: RANS2P.h:2062
nu_1
double nu_1
Definition: ErrorResidualMethod.cpp:22
proteus::RANS2P::cutfem_local_boundaries
std::map< int, int > cutfem_local_boundaries
Definition: RANS2P.h:314
proteus::RANS2P::nDOF_v_test_X_trial_element
const int nDOF_v_test_X_trial_element
Definition: RANS2P.h:318
proteus::RANS2P::ifem_boundary_elements
std::set< int > ifem_boundary_elements
Definition: RANS2P.h:312
equivalent_polynomials.h
proteus::RANS2P::calculateVelocityAverage
void calculateVelocityAverage(arguments_dict &args)
Definition: RANS2P.h:7873
vy
Double vy
Definition: Headers.h:98
z
Double * z
Definition: Headers.h:49
proteus::RANS2P::cutfem_boundaries
std::set< int > cutfem_boundaries
Definition: RANS2P.h:313
proteus::RANS2P_base::getTwoPhaseAdvectionOperator
virtual void getTwoPhaseAdvectionOperator(arguments_dict &args)=0
proteus::RANS2P::exteriorNumericalAdvectiveFluxDerivatives
void exteriorNumericalAdvectiveFluxDerivatives(const double NONCONSERVATIVE_FORM, 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 &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 &dmom_u_acc_u, 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 dham_grad[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)
Definition: RANS2P.h:1745
pe
Double pe
Definition: Headers.h:75
u
Double u
Definition: Headers.h:89
proteus::RANS2P_base::getTwoPhaseInvScaledLaplaceOperator
virtual void getTwoPhaseInvScaledLaplaceOperator(arguments_dict &args)=0
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
proteus::RANS2P::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: RANS2P.h:1448
xt
Definition: AddedMass.cpp:7
rho_1
double rho_1
Definition: ErrorResidualMethod.cpp:22
MixedModelFactory.h
proteus::RANS2P::getTwoPhaseScaledMassOperator
void getTwoPhaseScaledMassOperator(arguments_dict &args)
Definition: RANS2P.h:8566
proteus::RANS2P::nDOF_test_X_v_trial_element
const int nDOF_test_X_v_trial_element
Definition: RANS2P.h:317
proteus::RANS2P
Definition: RANS2P.h:310
equivalent_polynomials::GeneralizedFunctions_mix
Definition: equivalent_polynomials.h:767
Q
Double Q
Definition: Headers.h:80
proteus::RANS2P::evaluateTPAdvectionCoefficients
void evaluateTPAdvectionCoefficients(const double eps_rho, const double rho_0, const double rho_1, const double useVF, const double &vf, const double &phi, const double &u, const double &v, const double &w, double dmass_adv_p[nSpace], double dmom_u_adv_u[nSpace], double dmom_v_adv_v[nSpace], double dmom_w_adv_w[nSpace])
Definition: RANS2P.h:8044
proteus::RANS2P::ck_v
CompKernelType_v ck_v
Definition: RANS2P.h:321
proteus_lapack.h
proteus::RANS2P::get_cross_product
void get_cross_product(const double *u, const double *v, double res[3])
Definition: RANS2P.h:836
proteus::RANS2P_base::calculateJacobian
virtual void calculateJacobian(arguments_dict &args)=0
proteus::RANS2P::calculateResidual
void calculateResidual(arguments_dict &args)
Definition: RANS2P.h:2145
proteus
Definition: ADR.h:17
proteus::GeneralizedFunctions
equivalent_polynomials::GeneralizedFunctions_mix< nSpace, nP, nQ, nEBQ > GeneralizedFunctions
Definition: ADR.h:19
dgetrs_
int dgetrs_(char *trans, int *n, int *nrhs, double *a, int *lda, int *ipiv, double *b, int *ldb, int *info)
proteus::RANS2P_base::calculateResidual
virtual void calculateResidual(arguments_dict &args)=0
proteus::RANS2P::evaluateTPInvDensityLaplaceCoefficients
void evaluateTPInvDensityLaplaceCoefficients(const double eps_rho, const double rho_0, const double rho_1, const double useVF, const double &vf, const double &phi, double mom_p_diff_ten[nSpace], double mom_u_diff_ten[nSpace], double mom_v_diff_ten[nSpace], double mom_w_diff_ten[nSpace])
Definition: RANS2P.h:8173
proteus::f
double f(const double &g, const double &h, const double &hZ)
Definition: SW2DCV.h:58
proteus::RANS2P::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: RANS2P.h:2112
r
Double r
Definition: Headers.h:83
proteus::RANS2P::evaluateTPDensityMassCoefficients
void evaluateTPDensityMassCoefficients(const double eps_rho, const double rho_0, const double rho_1, const double useVF, const double &vf, const double &phi, const double &p, const double &u, const double &v, const double &w, double &mom_p_acc, double &dmom_p_acc_p, 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)
Definition: RANS2P.h:8134
proteus::arguments_dict
Definition: ArgumentsDict.h:70
proteus::RANS2P::RANS2P
RANS2P()
Definition: RANS2P.h:325
proteus::RANS2P::gf_p
GeneralizedFunctions< nSpace, 3, nQuadraturePoints_element, nQuadraturePoints_elementBoundary > gf_p
Definition: RANS2P.h:323
proteus::RANS2P::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: RANS2P.h:1426
rho_0
double rho_0
Definition: ErrorResidualMethod.cpp:22
proteus::rnorm
double rnorm(double *r)
Definition: RANS2P.h:35
UPWIND_DIRICHLET
const bool UPWIND_DIRICHLET
Definition: RANS2P.h:23
proteus::RANS2P::get_velocity_to_ith_ball
void get_velocity_to_ith_ball(int n_balls, const double *ball_center, const double *ball_radius, const double *ball_velocity, const double *ball_angular_velocity, int I, const double x, const double y, const double z, double &vx, double &vy, double &vz)
Definition: RANS2P.h:842
proteus::RANS2P_base::getTwoPhaseScaledMassOperator
virtual void getTwoPhaseScaledMassOperator(arguments_dict &args)=0
proteus::RANS2P::get_distance_to_ball
int get_distance_to_ball(int n_balls, const double *ball_center, const double *ball_radius, const double x, const double y, const double z, double &distance)
Definition: RANS2P.h:783
ArgumentsDict.h
DM
const double DM
Definition: RANS2P.h:25
cs
Double cs
Definition: Headers.h:58
PyEmbeddedFunctions.h