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