14 const std::vector<double>&
x,
15 std::vector<double>& x_local) {
16 for (
unsigned int node=0; node<e.
nnode; node++)
17 for (
unsigned int eqn=0; eqn<neqn; eqn++)
18 x_local[node*neqn+eqn] = x[e.
gid[node]*neqn+eqn];
23 const std::vector<double>&
x,
24 std::vector<double>& u,
25 std::vector<double>& du,
26 std::vector<double>& f,
27 std::vector< std::vector<double> >& jac) {
29 for (
unsigned int qp=0; qp<e.
nqp; qp++) {
30 for (
unsigned int eqn=0; eqn<neqn; eqn++) {
32 du[qp*neqn+eqn] = 0.0;
33 for (
unsigned int node=0; node<e.
nnode; node++) {
34 u[qp*neqn+eqn] += x[node*neqn+eqn] * e.
phi[qp][node];
35 du[qp*neqn+eqn] += x[node*neqn+eqn] * e.
dphi[qp][node];
41 std::vector<double> s(e.
nqp);
42 for (
unsigned int qp=0; qp<e.
nqp; qp++) {
44 for (
unsigned int eqn=0; eqn<neqn; eqn++)
45 s[qp] += u[qp*neqn+eqn]*u[qp*neqn+eqn];
49 for (
unsigned int node_row=0; node_row<e.
nnode; node_row++) {
50 for (
unsigned int eqn_row=0; eqn_row<neqn; eqn_row++) {
51 unsigned int row = node_row*neqn+eqn_row;
53 for (
unsigned int node_col=0; node_col<e.
nnode; node_col++) {
54 for (
unsigned int eqn_col=0; eqn_col<neqn; eqn_col++) {
55 unsigned int col = node_col*neqn+eqn_col;
59 for (
unsigned int qp=0; qp<e.
nqp; qp++) {
60 double c1 = e.
w[qp]*e.
jac[qp];
61 double c2 = -e.
dphi[qp][node_row]/(e.
jac[qp]*e.
jac[qp]);
62 double c3 =
exp(u[qp*neqn+eqn_row]);
63 double c4 = e.
phi[qp][node_row]*s[qp]*c3;
64 f[row] += c1*(c2*du[qp*neqn+eqn_row] + c4);
65 for (
unsigned int node_col=0; node_col<e.
nnode; node_col++) {
66 jac[row][node_col*neqn+eqn_row] +=
67 c1*(c2*e.
dphi[qp][node_col] + c4*e.
phi[qp][node_col]);
68 for (
unsigned int eqn_col=0; eqn_col<neqn; eqn_col++)
69 jac[row][node_col*neqn+eqn_col] +=
70 2.0*c1*e.
phi[qp][node_row]*u[qp*neqn+eqn_col]*e.
phi[qp][node_col]*c3;
79 const std::vector<double>& f_local,
80 const std::vector< std::vector<double> >& jac_local,
81 std::vector<double>& f,
82 std::vector< std::vector<double> >& jac) {
83 for (
unsigned int eqn_row=0; eqn_row<neqn; eqn_row++) {
84 f[e.
gid[0]*neqn+eqn_row] += f_local[0*neqn+eqn_row];
85 f[e.
gid[1]*neqn+eqn_row] += f_local[1*neqn+eqn_row];
86 for (
unsigned int node_col=0; node_col<e.
nnode; node_col++) {
87 for (
unsigned int eqn_col=0; eqn_col<neqn; eqn_col++) {
88 unsigned int col = node_col*neqn+eqn_col;
89 unsigned int next_col = (node_col+1)*neqn+eqn_col;
90 jac[e.
gid[0]*neqn+eqn_row][next_col] += jac_local[0*neqn+eqn_row][col];
91 jac[e.
gid[1]*neqn+eqn_row][col] += jac_local[1*neqn+eqn_row][col];
98 double mesh_spacing) {
102 std::vector<double>
x(num_nodes*num_eqns),
f(num_nodes*num_eqns);
103 std::vector< std::vector<double> > jac(num_nodes*num_eqns);
104 for (
unsigned int node_row=0; node_row<num_nodes; node_row++) {
105 for (
unsigned int eqn_row=0; eqn_row<num_eqns; eqn_row++) {
106 unsigned int row = node_row*num_eqns + eqn_row;
107 x[row] = (mesh_spacing*node_row - 0.5)*(mesh_spacing*node_row - 0.5);
109 jac[row] = std::vector<double>((e.
nnode+1)*num_eqns);
110 for (
unsigned int node_col=0; node_col<e.
nnode+1; node_col++) {
111 for (
unsigned int eqn_col=0; eqn_col<num_eqns; eqn_col++) {
112 unsigned int col = node_col*num_eqns + eqn_col;
121 std::vector<double> x_local(e.
nnode*num_eqns), f_local(e.
nnode*num_eqns);
122 std::vector< std::vector<double> > jac_local(e.
nnode*num_eqns);
123 std::vector<double> u(e.
nqp*num_eqns), du(e.
nqp*num_eqns);
124 for (
unsigned int i=0;
i<e.
nnode*num_eqns;
i++)
125 jac_local[
i] = std::vector<double>(e.
nnode*num_eqns);
126 for (
unsigned int i=0;
i<num_nodes-1;
i++) {
156 const std::vector<double>& f_local,
157 std::vector<double>& f) {
158 for (
unsigned int eqn_row=0; eqn_row<neqn; eqn_row++) {
159 f[e.
gid[0]*neqn+eqn_row] += f_local[0*neqn+eqn_row];
160 f[e.
gid[1]*neqn+eqn_row] += f_local[1*neqn+eqn_row];
165 double mesh_spacing) {
169 std::vector<double>
x(num_nodes*num_eqns),
f(num_nodes*num_eqns);
170 for (
unsigned int node_row=0; node_row<num_nodes; node_row++) {
171 for (
unsigned int eqn_row=0; eqn_row<num_eqns; eqn_row++) {
172 unsigned int row = node_row*num_eqns + eqn_row;
173 x[row] = (mesh_spacing*node_row - 0.5)*(mesh_spacing*node_row - 0.5);
180 std::vector<double> x_local(e.
nnode*num_eqns), f_local(e.
nnode*num_eqns);
181 std::vector<double> u(e.
nqp*num_eqns), du(e.
nqp*num_eqns);
182 for (
unsigned int i=0;
i<num_nodes-1;
i++) {
201 #ifndef ADOLC_TAPELESS
202 void adolc_init_fill(
bool retape,
206 const std::vector<double>&
x,
207 std::vector<double>& x_local,
208 std::vector<adouble>& x_ad) {
211 for (
unsigned int node=0; node<e.
nnode; node++)
212 for (
unsigned int eqn=0; eqn<neqn; eqn++) {
213 x_local[node*neqn+eqn] = x[e.
gid[node]*neqn+eqn];
215 x_ad[node*neqn+eqn] <<= x_local[node*neqn+eqn];
219 void adolc_process_fill(
bool retape,
223 std::vector<double>& x_local,
224 std::vector<adouble>& f_ad,
225 std::vector<double>& f,
226 std::vector<double>& f_local,
227 std::vector< std::vector<double> >& jac,
229 double **jac_local) {
231 for (
unsigned int eqn_row=0; eqn_row<neqn; eqn_row++)
232 f_ad[0*neqn+eqn_row] >>= f_local[0*neqn+eqn_row];
233 for (
unsigned int eqn_row=0; eqn_row<neqn; eqn_row++)
234 f_ad[1*neqn+eqn_row] >>= f_local[1*neqn+eqn_row];
240 seed, &f_local[0], jac_local);
242 for (
unsigned int eqn_row=0; eqn_row<neqn; eqn_row++) {
243 f[e.
gid[0]*neqn+eqn_row] += f_local[0*neqn+eqn_row];
244 f[e.
gid[1]*neqn+eqn_row] += f_local[1*neqn+eqn_row];
245 for (
unsigned int node_col=0; node_col<e.
nnode; node_col++) {
246 for (
unsigned int eqn_col=0; eqn_col<neqn; eqn_col++) {
247 unsigned int col = node_col*neqn+eqn_col;
248 unsigned int next_col = (node_col+1)*neqn+eqn_col;
249 jac[e.
gid[0]*neqn+eqn_row][next_col] += jac_local[0*neqn+eqn_row][col];
250 jac[e.
gid[1]*neqn+eqn_row][col] += jac_local[1*neqn+eqn_row][col];
256 double adolc_jac_fill(
unsigned int num_nodes,
unsigned int num_eqns,
257 double mesh_spacing) {
261 std::vector<double>
x(num_nodes*num_eqns), f(num_nodes*num_eqns);
262 std::vector< std::vector<double> > jac(num_nodes*num_eqns);
263 for (
unsigned int node_row=0; node_row<num_nodes; node_row++) {
264 for (
unsigned int eqn_row=0; eqn_row<num_eqns; eqn_row++) {
265 unsigned int row = node_row*num_eqns + eqn_row;
266 x[row] = (mesh_spacing*node_row - 0.5)*(mesh_spacing*node_row - 0.5);
268 jac[row] = std::vector<double>((e.
nnode+1)*num_eqns);
269 for (
unsigned int node_col=0; node_col<e.
nnode+1; node_col++) {
270 for (
unsigned int eqn_col=0; eqn_col<num_eqns; eqn_col++) {
271 unsigned int col = node_col*num_eqns + eqn_col;
280 std::vector<adouble> x_ad(e.
nnode*num_eqns), f_ad(e.
nnode*num_eqns);
281 std::vector<adouble> u(e.
nqp*num_eqns), du(e.
nqp*num_eqns);
282 std::vector<double> x_local(e.
nnode*num_eqns);
283 std::vector<double> f_local(e.
nnode*num_eqns);
284 double **jac_local =
new double*[e.
nnode*num_eqns];
285 double **seed =
new double*[e.
nnode*num_eqns];
286 for (
unsigned int i=0;
i<e.
nnode*num_eqns;
i++) {
287 jac_local[
i] =
new double[e.
nnode*num_eqns];
288 seed[
i] =
new double[e.
nnode*num_eqns];
289 for (
unsigned int j=0; j<e.
nnode*num_eqns; j++)
297 adolc_init_fill(
true, 0, e, num_eqns, x, x_local, x_ad);
299 adolc_process_fill(
true, 0, e, num_eqns, x_local, f_ad, f, f_local,
300 jac, seed, jac_local);
303 for (
unsigned int i=1;
i<num_nodes-1;
i++) {
307 adolc_init_fill(
false, 0, e, num_eqns, x, x_local, x_ad);
308 adolc_process_fill(
false, 0, e, num_eqns, x_local, f_ad, f, f_local,
309 jac, seed, jac_local);
311 for (
unsigned int i=0;
i<e.
nnode*num_eqns;
i++) {
312 delete [] jac_local[
i];
332 return timer.totalElapsedTime();
335 double adolc_retape_jac_fill(
unsigned int num_nodes,
unsigned int num_eqns,
336 double mesh_spacing) {
340 std::vector<double>
x(num_nodes*num_eqns), f(num_nodes*num_eqns);
341 std::vector< std::vector<double> > jac(num_nodes*num_eqns);
342 for (
unsigned int node_row=0; node_row<num_nodes; node_row++) {
343 for (
unsigned int eqn_row=0; eqn_row<num_eqns; eqn_row++) {
344 unsigned int row = node_row*num_eqns + eqn_row;
345 x[row] = (mesh_spacing*node_row - 0.5)*(mesh_spacing*node_row - 0.5);
347 jac[row] = std::vector<double>((e.
nnode+1)*num_eqns);
348 for (
unsigned int node_col=0; node_col<e.
nnode+1; node_col++) {
349 for (
unsigned int eqn_col=0; eqn_col<num_eqns; eqn_col++) {
350 unsigned int col = node_col*num_eqns + eqn_col;
357 Teuchos::Time timer(
"FE ADOL-C Retape Jacobian Fill",
false);
359 std::vector<adouble> x_ad(e.
nnode*num_eqns), f_ad(e.
nnode*num_eqns);
360 std::vector<adouble> u(e.
nqp*num_eqns), du(e.
nqp*num_eqns);
361 std::vector<double> x_local(e.
nnode*num_eqns);
362 std::vector<double> f_local(e.
nnode*num_eqns);
363 double **jac_local =
new double*[e.
nnode*num_eqns];
364 double **seed =
new double*[e.
nnode*num_eqns];
365 for (
unsigned int i=0;
i<e.
nnode*num_eqns;
i++) {
366 jac_local[
i] =
new double[e.
nnode*num_eqns];
367 seed[
i] =
new double[e.
nnode*num_eqns];
368 for (
unsigned int j=0; j<e.
nnode*num_eqns; j++)
372 for (
unsigned int i=0;
i<num_nodes-1;
i++) {
376 adolc_init_fill(
true, 1, e, num_eqns, x, x_local, x_ad);
378 adolc_process_fill(
true, 1, e, num_eqns, x_local, f_ad, f, f_local,
379 jac, seed, jac_local);
381 for (
unsigned int i=0;
i<e.
nnode*num_eqns;
i++) {
382 delete [] jac_local[
i];
402 return timer.totalElapsedTime();
407 void adolc_tapeless_init_fill(
const ElemData& e,
409 const std::vector<double>& x,
410 std::vector<adtl::adouble>& x_ad) {
411 for (
unsigned int node=0; node<e.
nnode; node++)
412 for (
unsigned int eqn=0; eqn<neqn; eqn++) {
413 x_ad[node*neqn+eqn] = x[e.
gid[node]*neqn+eqn];
414 for (
unsigned int i=0;
i<neqn*e.
nnode;
i++)
415 x_ad[node*neqn+eqn].setADValue(
i, 0.0);
416 x_ad[node*neqn+eqn].setADValue(node*neqn+eqn, 1.0);
421 void adolc_tapeless_process_fill(
const ElemData& e,
423 const std::vector<adtl::adouble>& f_ad,
424 std::vector<double>& f,
425 std::vector< std::vector<double> >& jac) {
426 for (
unsigned int eqn_row=0; eqn_row<neqn; eqn_row++) {
427 f[e.
gid[0]*neqn+eqn_row] += f_ad[0*neqn+eqn_row].getValue();
428 f[e.
gid[1]*neqn+eqn_row] += f_ad[1*neqn+eqn_row].getValue();
429 for (
unsigned int node_col=0; node_col<e.
nnode; node_col++) {
430 for (
unsigned int eqn_col=0; eqn_col<neqn; eqn_col++) {
431 unsigned int col = node_col*neqn+eqn_col;
432 unsigned int next_col = (node_col+1)*neqn+eqn_col;
433 jac[e.
gid[0]*neqn+eqn_row][next_col] +=
434 f_ad[0*neqn+eqn_row].getADValue(col);
435 jac[e.
gid[1]*neqn+eqn_row][col] +=
436 f_ad[1*neqn+eqn_row].getADValue(col);
442 double adolc_tapeless_jac_fill(
unsigned int num_nodes,
unsigned int num_eqns,
443 double mesh_spacing) {
447 std::vector<double>
x(num_nodes*num_eqns), f(num_nodes*num_eqns);
448 std::vector< std::vector<double> > jac(num_nodes*num_eqns);
449 for (
unsigned int node_row=0; node_row<num_nodes; node_row++) {
450 for (
unsigned int eqn_row=0; eqn_row<num_eqns; eqn_row++) {
451 unsigned int row = node_row*num_eqns + eqn_row;
452 x[row] = (mesh_spacing*node_row - 0.5)*(mesh_spacing*node_row - 0.5);
454 jac[row] = std::vector<double>((e.
nnode+1)*num_eqns);
455 for (
unsigned int node_col=0; node_col<e.
nnode+1; node_col++) {
456 for (
unsigned int eqn_col=0; eqn_col<num_eqns; eqn_col++) {
457 unsigned int col = node_col*num_eqns + eqn_col;
464 Teuchos::Time timer(
"FE Tapeless ADOL-C Jacobian Fill",
false);
466 std::vector<adtl::adouble> x_ad(e.
nnode*num_eqns), f_ad(e.
nnode*num_eqns);
467 std::vector<adtl::adouble> u(e.
nqp*num_eqns), du(e.
nqp*num_eqns);
468 for (
unsigned int i=0;
i<num_nodes-1;
i++) {
472 adolc_tapeless_init_fill(e, num_eqns, x, x_ad);
474 adolc_tapeless_process_fill(e, num_eqns, f_ad, f, jac);
491 return timer.totalElapsedTime();
497 void adic_init_fill(
const ElemData& e,
499 const std::vector<double>& x,
500 std::vector<DERIV_TYPE>& x_fad) {
501 static bool first =
true;
502 for (
unsigned int node=0; node<e.
nnode; node++)
503 for (
unsigned int eqn=0; eqn<neqn; eqn++) {
504 x_fad[node*neqn+eqn].value = x[e.
gid[node]*neqn+eqn];
506 ad_AD_SetIndep(x_fad[node*neqn+eqn]);
509 ad_AD_SetIndepDone();
531 unsigned int var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7;
553 for (
unsigned int qp = 0; qp < e->
nqp; ) {
554 for (
unsigned int eqn = 0; eqn < neqn; ) {
556 ad_grad_axpy_0(&(u[qp * neqn + eqn]));
560 ad_grad_axpy_0(&(du[qp * neqn + eqn]));
563 for (
unsigned int node = 0; node < e->
nnode; ) {
565 loc_0 =
DERIV_val(x[node * neqn + eqn]) * e->
phi[qp][node];
566 loc_1 =
DERIV_val(u[qp * neqn + eqn]) + loc_0;
567 ad_grad_axpy_2(&(u[qp * neqn + eqn]), 1.000000000000000e+00, &(u[qp * neqn + eqn]), e->
phi[qp][node], &(x[node * neqn + eqn]));
572 loc_1 =
DERIV_val(du[qp * neqn + eqn]) + loc_0;
573 ad_grad_axpy_2(&(du[qp * neqn + eqn]), 1.000000000000000e+00, &(du[qp * neqn + eqn]), e->
dphi[qp][node], &(x[node * neqn + eqn]));
583 std::vector<DERIV_TYPE> s(e->
nqp);
584 for (
unsigned int qp = 0; qp < e->
nqp; ) {
586 ad_grad_axpy_0(&(s[qp]));
589 for (
unsigned int eqn = 0; eqn < neqn; ) {
593 ad_grad_axpy_3(&(s[qp]), 1.000000000000000e+00, &(s[qp]),
DERIV_val(u[qp * neqn + eqn]), &(u[qp * neqn + eqn]),
DERIV_val(u[qp * neqn + eqn]), &(u[qp * neqn + eqn]));
600 for (
unsigned int node = 0; node < e->
nnode; ) {
601 for (
unsigned int eqn = 0; eqn < neqn; ) {
602 unsigned int row = node * neqn + eqn;
604 ad_grad_axpy_0(&(f[row]));
607 for (
unsigned int qp = 0; qp < e->
nqp; ) {
611 ad_grad_axpy_1(&(var_8), adji_0, &(u[qp * neqn + eqn]));
614 loc_0 = e->
w[qp] * e->
jac[qp];
615 loc_1 = -e->
dphi[qp][node];
616 loc_2 = e->
jac[qp] * e->
jac[qp];
617 loc_3 = loc_1 / loc_2;
618 loc_4 = loc_3 *
DERIV_val(du[qp * neqn + eqn]);
621 loc_7 = loc_4 + loc_6;
622 loc_8 = loc_0 * loc_7;
624 adj_0 = loc_5 * loc_0;
626 adj_2 = e->
phi[qp][node] * adj_1;
627 adj_3 = loc_3 * loc_0;
628 ad_grad_axpy_4(&(f[row]), 1.000000000000000e+00, &(f[row]), adj_3, &(du[qp * neqn + eqn]), adj_2, &(s[qp]), adj_0, &(var_8));
640 void adic_process_fill(
const ElemData& e,
642 const std::vector<DERIV_TYPE>& f_fad,
643 std::vector<double>& f,
644 std::vector< std::vector<double> >& jac) {
645 for (
unsigned int eqn_row=0; eqn_row<neqn; eqn_row++) {
646 f[e.
gid[0]*neqn+eqn_row] += f_fad[0*neqn+eqn_row].value;
647 f[e.
gid[1]*neqn+eqn_row] += f_fad[1*neqn+eqn_row].value;
648 for (
unsigned int node_col=0; node_col<e.
nnode; node_col++) {
649 for (
unsigned int eqn_col=0; eqn_col<neqn; eqn_col++) {
650 unsigned int col = node_col*neqn+eqn_col;
651 unsigned int next_col = (node_col+1)*neqn+eqn_col;
652 jac[e.
gid[0]*neqn+eqn_row][next_col] +=
653 f_fad[0*neqn+eqn_row].grad[col];
654 jac[e.
gid[1]*neqn+eqn_row][col] +=
655 f_fad[1*neqn+eqn_row].grad[col];
661 double adic_jac_fill(
unsigned int num_nodes,
unsigned int num_eqns,
662 double mesh_spacing) {
667 std::vector<double>
x(num_nodes*num_eqns), f(num_nodes*num_eqns);
668 std::vector< std::vector<double> > jac(num_nodes*num_eqns);
669 for (
unsigned int node_row=0; node_row<num_nodes; node_row++) {
670 for (
unsigned int eqn_row=0; eqn_row<num_eqns; eqn_row++) {
671 unsigned int row = node_row*num_eqns + eqn_row;
672 x[row] = (mesh_spacing*node_row - 0.5)*(mesh_spacing*node_row - 0.5);
674 jac[row] = std::vector<double>((e.
nnode+1)*num_eqns);
675 for (
unsigned int node_col=0; node_col<e.
nnode+1; node_col++) {
676 for (
unsigned int eqn_col=0; eqn_col<num_eqns; eqn_col++) {
677 unsigned int col = node_col*num_eqns + eqn_col;
686 std::vector<DERIV_TYPE> x_fad(e.
nnode*num_eqns), f_fad(e.
nnode*num_eqns);
687 std::vector<DERIV_TYPE> u(e.
nqp*num_eqns), du(e.
nqp*num_eqns);
688 for (
unsigned int i=0;
i<num_nodes-1;
i++) {
692 adic_init_fill(e, num_eqns, x, x_fad);
694 adic_process_fill(e, num_eqns, f_fad, f, jac);
713 return timer.totalElapsedTime();
double residual_fill(unsigned int num_nodes, unsigned int num_eqns, double mesh_spacing)
void template_element_fill(const ElemData &e, unsigned int neqn, const std::vector< T > &x, std::vector< T > &u, std::vector< T > &du, std::vector< T > &f)
void adic_element_fill(ElemData *e, unsigned int neqn, const DERIV_TYPE *x, DERIV_TYPE *u, DERIV_TYPE *du, DERIV_TYPE *f)
double analytic_jac_fill(unsigned int num_nodes, unsigned int num_eqns, double mesh_spacing)
void analytic_element_fill(const ElemData &e, unsigned int neqn, const std::vector< double > &x, std::vector< double > &u, std::vector< double > &du, std::vector< double > &f, std::vector< std::vector< double > > &jac)
void analytic_process_fill(const ElemData &e, unsigned int neqn, const std::vector< double > &f_local, const std::vector< std::vector< double > > &jac_local, std::vector< double > &f, std::vector< std::vector< double > > &jac)
void start(bool reset=false)
void analytic_init_fill(const ElemData &e, unsigned int neqn, const std::vector< double > &x, std::vector< double > &x_local)
void residual_process_fill(const ElemData &e, unsigned int neqn, const std::vector< double > &f_local, std::vector< double > &f)
double totalElapsedTime(bool readCurrentTime=false) const