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