MFEM  v4.0
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
tmop.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
2 // the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
3 // reserved. See file COPYRIGHT for details.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability see http://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the GNU Lesser General Public License (as published by the Free
10 // Software Foundation) version 2.1 dated February 1999.
11 
12 #include "tmop.hpp"
13 #include "linearform.hpp"
14 #include "pgridfunc.hpp"
15 
16 namespace mfem
17 {
18 
19 // Target-matrix optimization paradigm (TMOP) mesh quality metrics.
20 
21 double TMOP_Metric_001::EvalW(const DenseMatrix &Jpt) const
22 {
23  ie.SetJacobian(Jpt.GetData());
24  return ie.Get_I1();
25 }
26 
28 {
29  ie.SetJacobian(Jpt.GetData());
30  P = ie.Get_dI1();
31 }
32 
34  const DenseMatrix &DS,
35  const double weight,
36  DenseMatrix &A) const
37 {
38  ie.SetJacobian(Jpt.GetData());
40  ie.Assemble_ddI1(weight, A.GetData());
41 }
42 
43 double TMOP_Metric_skew2D::EvalW(const DenseMatrix &Jpt) const
44 {
45  MFEM_VERIFY(Jtr != NULL,
46  "Requires a target Jacobian, use SetTargetJacobian().");
47 
48  DenseMatrix Jpr(2, 2);
49  Mult(Jpt, *Jtr, Jpr);
50 
51  Vector col1, col2;
52  Jpr.GetColumn(0, col1);
53  Jpr.GetColumn(1, col2);
54  double norm_prod = col1.Norml2() * col2.Norml2();
55  const double cos_Jpr = (col1 * col2) / norm_prod,
56  sin_Jpr = fabs(Jpr.Det()) / norm_prod;
57 
58  Jtr->GetColumn(0, col1);
59  Jtr->GetColumn(1, col2);
60  norm_prod = col1.Norml2() * col2.Norml2();
61  const double cos_Jtr = (col1 * col2) / norm_prod,
62  sin_Jtr = fabs(Jtr->Det()) / norm_prod;
63 
64  return 0.5 * (1.0 - cos_Jpr * cos_Jtr - sin_Jpr * sin_Jtr);
65 }
66 
67 double TMOP_Metric_skew3D::EvalW(const DenseMatrix &Jpt) const
68 {
69  MFEM_VERIFY(Jtr != NULL,
70  "Requires a target Jacobian, use SetTargetJacobian().");
71 
72  DenseMatrix Jpr(3, 3);
73  Mult(Jpt, *Jtr, Jpr);
74 
75  Vector col1, col2, col3;
76  Jpr.GetColumn(0, col1);
77  Jpr.GetColumn(1, col2);
78  Jpr.GetColumn(2, col3);
79  double norm_c1 = col1.Norml2(),
80  norm_c2 = col2.Norml2(),
81  norm_c3 = col3.Norml2();
82  double cos_Jpr_12 = (col1 * col2) / (norm_c1 * norm_c2),
83  cos_Jpr_13 = (col1 * col3) / (norm_c1 * norm_c3),
84  cos_Jpr_23 = (col2 * col3) / (norm_c2 * norm_c3);
85  double sin_Jpr_12 = std::sqrt(1.0 - cos_Jpr_12 * cos_Jpr_12),
86  sin_Jpr_13 = std::sqrt(1.0 - cos_Jpr_13 * cos_Jpr_13),
87  sin_Jpr_23 = std::sqrt(1.0 - cos_Jpr_23 * cos_Jpr_23);
88 
89  Jtr->GetColumn(0, col1);
90  Jtr->GetColumn(1, col2);
91  Jtr->GetColumn(2, col3);
92  norm_c1 = col1.Norml2();
93  norm_c2 = col2.Norml2(),
94  norm_c3 = col3.Norml2();
95  double cos_Jtr_12 = (col1 * col2) / (norm_c1 * norm_c2),
96  cos_Jtr_13 = (col1 * col3) / (norm_c1 * norm_c3),
97  cos_Jtr_23 = (col2 * col3) / (norm_c2 * norm_c3);
98  double sin_Jtr_12 = std::sqrt(1.0 - cos_Jtr_12 * cos_Jtr_12),
99  sin_Jtr_13 = std::sqrt(1.0 - cos_Jtr_13 * cos_Jtr_13),
100  sin_Jtr_23 = std::sqrt(1.0 - cos_Jtr_23 * cos_Jtr_23);
101 
102  return (3.0 - cos_Jpr_12 * cos_Jtr_12 - sin_Jpr_12 * sin_Jtr_12
103  - cos_Jpr_13 * cos_Jtr_13 - sin_Jpr_13 * sin_Jtr_13
104  - cos_Jpr_23 * cos_Jtr_23 - sin_Jpr_23 * sin_Jtr_23) / 6.0;
105 }
106 
108 {
109  MFEM_VERIFY(Jtr != NULL,
110  "Requires a target Jacobian, use SetTargetJacobian().");
111 
112  DenseMatrix Jpr(2, 2);
113  Mult(Jpt, *Jtr, Jpr);
114 
115  Vector col1, col2;
116  Jpr.GetColumn(0, col1);
117  Jpr.GetColumn(1, col2);
118  const double ratio_Jpr = col2.Norml2() / col1.Norml2();
119 
120  Jtr->GetColumn(0, col1);
121  Jtr->GetColumn(1, col2);
122  const double ratio_Jtr = col2.Norml2() / col1.Norml2();
123 
124  return 0.5 * (ratio_Jpr / ratio_Jtr + ratio_Jtr / ratio_Jpr) - 1.0;
125 }
126 
128 {
129  MFEM_VERIFY(Jtr != NULL,
130  "Requires a target Jacobian, use SetTargetJacobian().");
131 
132  DenseMatrix Jpr(3, 3);
133  Mult(Jpt, *Jtr, Jpr);
134 
135  Vector col1, col2, col3;
136  Jpr.GetColumn(0, col1);
137  Jpr.GetColumn(1, col2);
138  Jpr.GetColumn(2, col3);
139  double norm_c1 = col1.Norml2(),
140  norm_c2 = col2.Norml2(),
141  norm_c3 = col3.Norml2();
142  double ratio_Jpr_1 = norm_c1 / std::sqrt(norm_c2 * norm_c3),
143  ratio_Jpr_2 = norm_c2 / std::sqrt(norm_c1 * norm_c3),
144  ratio_Jpr_3 = norm_c3 / std::sqrt(norm_c1 * norm_c2);
145 
146  Jtr->GetColumn(0, col1);
147  Jtr->GetColumn(1, col2);
148  Jtr->GetColumn(2, col3);
149  norm_c1 = col1.Norml2();
150  norm_c2 = col2.Norml2();
151  norm_c3 = col3.Norml2();
152  double ratio_Jtr_1 = norm_c1 / std::sqrt(norm_c2 * norm_c3),
153  ratio_Jtr_2 = norm_c2 / std::sqrt(norm_c1 * norm_c3),
154  ratio_Jtr_3 = norm_c3 / std::sqrt(norm_c1 * norm_c2);
155 
156  return ( 0.5 * (ratio_Jpr_1 / ratio_Jtr_1 + ratio_Jtr_1 / ratio_Jpr_1) +
157  0.5 * (ratio_Jpr_2 / ratio_Jtr_2 + ratio_Jtr_2 / ratio_Jpr_2) +
158  0.5 * (ratio_Jpr_3 / ratio_Jtr_3 + ratio_Jtr_3 / ratio_Jpr_3) - 3.0
159  ) / 3.0;
160 }
161 
162 double TMOP_Metric_002::EvalW(const DenseMatrix &Jpt) const
163 {
164  ie.SetJacobian(Jpt.GetData());
165  return 0.5 * ie.Get_I1b() - 1.0;
166 }
167 
169 {
170  ie.SetJacobian(Jpt.GetData());
171  P.Set(0.5, ie.Get_dI1b());
172 }
173 
175  const DenseMatrix &DS,
176  const double weight,
177  DenseMatrix &A) const
178 {
179  ie.SetJacobian(Jpt.GetData());
180  ie.SetDerivativeMatrix(DS.Height(), DS.GetData());
181  ie.Assemble_ddI1b(0.5*weight, A.GetData());
182 }
183 
184 double TMOP_Metric_007::EvalW(const DenseMatrix &Jpt) const
185 {
186  // mu_7 = |J-J^{-t}|^2 = |J|^2 + |J^{-1}|^2 - 4
187  ie.SetJacobian(Jpt.GetData());
188  return ie.Get_I1()*(1. + 1./ie.Get_I2()) - 4.0;
189 }
190 
192 {
193  // P = d(I1*(1 + 1/I2)) = (1 + 1/I2) dI1 - I1/I2^2 dI2
194  ie.SetJacobian(Jpt.GetData());
195  const double I2 = ie.Get_I2();
196  Add(1. + 1./I2, ie.Get_dI1(), -ie.Get_I1()/(I2*I2), ie.Get_dI2(), P);
197 }
198 
200  const DenseMatrix &DS,
201  const double weight,
202  DenseMatrix &A) const
203 {
204  // P = d(I1*(1 + 1/I2))
205  // = (1 + 1/I2) dI1 - I1/I2^2 dI2
206  //
207  // dP = (-1/I2^2) (dI1 x dI2) + (1 + 1/I2) ddI1 -
208  // (dI2 x d(I1/I2^2)) - I1/I2^2 ddI2
209  // = (-1/I2^2) (dI1 x dI2) + (1 + 1/I2) ddI1 +
210  // (-1/I2^2) (dI2 x [dI1 - 2 I1/I2 dI2]) - I1/I2^2 ddI2
211  // = (-1/I2^2) (dI1 x dI2 + dI2 x dI1) + (1 + 1/I2) ddI1 +
212  // (2 I1/I2^3) (dI2 x dI2) - I1/I2^2 ddI2
213  ie.SetJacobian(Jpt.GetData());
214  ie.SetDerivativeMatrix(DS.Height(), DS.GetData());
215  const double c1 = 1./ie.Get_I2();
216  const double c2 = weight*c1*c1;
217  const double c3 = ie.Get_I1()*c2;
218  ie.Assemble_ddI1(weight*(1. + c1), A.GetData());
219  ie.Assemble_ddI2(-c3, A.GetData());
220  ie.Assemble_TProd(-c2, ie.Get_dI1(), ie.Get_dI2(), A.GetData());
221  ie.Assemble_TProd(2*c1*c3, ie.Get_dI2(), A.GetData());
222 }
223 
224 double TMOP_Metric_009::EvalW(const DenseMatrix &Jpt) const
225 {
226  // mu_9 = det(J)*|J-J^{-t}|^2 = I1b * (I2b^2 + 1) - 4 * I2b
227  // = (I1 - 4)*I2b + I1b
228  ie.SetJacobian(Jpt.GetData());
229  return (ie.Get_I1() - 4.0)*ie.Get_I2b() + ie.Get_I1b();
230 }
231 
233 {
234  // mu_9 = (I1 - 4)*I2b + I1b
235  // P = (I1 - 4)*dI2b + I2b*dI1 + dI1b
236  ie.SetJacobian(Jpt.GetData());
237  Add(ie.Get_I1() - 4.0, ie.Get_dI2b(), ie.Get_I2b(), ie.Get_dI1(), P);
238  P += ie.Get_dI1b();
239 }
240 
242  const DenseMatrix &DS,
243  const double weight,
244  DenseMatrix &A) const
245 {
246  // P = (I1 - 4)*dI2b + I2b*dI1 + dI1b
247  // dP = dI2b x dI1 + (I1-4)*ddI2b + dI1 x dI2b + I2b*ddI1 + ddI1b
248  // = (dI1 x dI2b + dI2b x dI1) + (I1-4)*ddI2b + I2b*ddI1 + ddI1b
249  ie.SetJacobian(Jpt.GetData());
250  ie.SetDerivativeMatrix(DS.Height(), DS.GetData());
251  ie.Assemble_TProd(weight, ie.Get_dI1(), ie.Get_dI2b(), A.GetData());
252  ie.Assemble_ddI2b(weight*(ie.Get_I1()-4.0), A.GetData());
253  ie.Assemble_ddI1(weight*ie.Get_I2b(), A.GetData());
254  ie.Assemble_ddI1b(weight, A.GetData());
255 }
256 
257 double TMOP_Metric_022::EvalW(const DenseMatrix &Jpt) const
258 {
259  // mu_22 = (0.5*|J|^2 - det(J)) / (det(J) - tau0)
260  // = (0.5*I1 - I2b) / (I2b - tau0)
261  ie.SetJacobian(Jpt.GetData());
262  const double I2b = ie.Get_I2b();
263  return (0.5*ie.Get_I1() - I2b) / (I2b - tau0);
264 }
265 
267 {
268  // mu_22 = (0.5*I1 - I2b) / (I2b - tau0)
269  // P = 1/(I2b - tau0)*(0.5*dI1 - dI2b) - (0.5*I1 - I2b)/(I2b - tau0)^2*dI2b
270  // = 0.5/(I2b - tau0)*dI1 + (tau0 - 0.5*I1)/(I2b - tau0)^2*dI2b
271  ie.SetJacobian(Jpt.GetData());
272  const double c1 = 1.0/(ie.Get_I2b() - tau0);
273  Add(c1/2, ie.Get_dI1(), (tau0 - ie.Get_I1()/2)*c1*c1, ie.Get_dI2b(), P);
274 }
275 
277  const DenseMatrix &DS,
278  const double weight,
279  DenseMatrix &A) const
280 {
281  // P = 0.5/(I2b - tau0)*dI1 + (tau0 - 0.5*I1)/(I2b - tau0)^2*dI2b
282  // dP = -0.5/(I2b - tau0)^2*(dI1 x dI2b) + 0.5/(I2b - tau0)*ddI1
283  // + (dI2b x dz) + z*ddI2b
284  //
285  // z = (tau0 - 0.5*I1)/(I2b - tau0)^2
286  // dz = -0.5/(I2b - tau0)^2*dI1 - 2*(tau0 - 0.5*I1)/(I2b - tau0)^3*dI2b
287  //
288  // dP = -0.5/(I2b - tau0)^2*(dI1 x dI2b + dI2b x dI1)
289  // -2*z/(I2b - tau0)*(dI2b x dI2b)
290  // +0.5/(I2b - tau0)*ddI1 + z*ddI2b
291  ie.SetJacobian(Jpt.GetData());
292  ie.SetDerivativeMatrix(DS.Height(), DS.GetData());
293  const double c1 = 1.0/(ie.Get_I2b() - tau0);
294  const double c2 = weight*c1/2;
295  const double c3 = c1*c2;
296  const double c4 = (2*tau0 - ie.Get_I1())*c3; // weight*z
297  ie.Assemble_TProd(-c3, ie.Get_dI1(), ie.Get_dI2b(), A.GetData());
298  ie.Assemble_TProd(-2*c1*c4, ie.Get_dI2b(), A.GetData());
299  ie.Assemble_ddI1(c2, A.GetData());
300  ie.Assemble_ddI2b(c4, A.GetData());
301 }
302 
303 double TMOP_Metric_050::EvalW(const DenseMatrix &Jpt) const
304 {
305  // mu_50 = 0.5*|J^t J|^2/det(J)^2 - 1
306  // = 0.5*(l1^4 + l2^4)/(l1*l2)^2 - 1
307  // = 0.5*((l1/l2)^2 + (l2/l1)^2) - 1 = 0.5*(l1/l2 - l2/l1)^2
308  // = 0.5*(l1/l2 + l2/l1)^2 - 2 = 0.5*I1b^2 - 2
309  ie.SetJacobian(Jpt.GetData());
310  const double I1b = ie.Get_I1b();
311  return 0.5*I1b*I1b - 2.0;
312 }
313 
315 {
316  // mu_50 = 0.5*I1b^2 - 2
317  // P = I1b*dI1b
318  ie.SetJacobian(Jpt.GetData());
319  P.Set(ie.Get_I1b(), ie.Get_dI1b());
320 }
321 
323  const DenseMatrix &DS,
324  const double weight,
325  DenseMatrix &A) const
326 {
327  // P = I1b*dI1b
328  // dP = dI1b x dI1b + I1b*ddI1b
329  ie.SetJacobian(Jpt.GetData());
330  ie.SetDerivativeMatrix(DS.Height(), DS.GetData());
331  ie.Assemble_TProd(weight, ie.Get_dI1b(), A.GetData());
332  ie.Assemble_ddI1b(weight*ie.Get_I1b(), A.GetData());
333 }
334 
335 double TMOP_Metric_055::EvalW(const DenseMatrix &Jpt) const
336 {
337  // mu_55 = (det(J) - 1)^2 = (I2b - 1)^2
338  ie.SetJacobian(Jpt.GetData());
339  const double c1 = ie.Get_I2b() - 1.0;
340  return c1*c1;
341 }
342 
344 {
345  // mu_55 = (I2b - 1)^2
346  // P = 2*(I2b - 1)*dI2b
347  ie.SetJacobian(Jpt.GetData());
348  P.Set(2*(ie.Get_I2b() - 1.0), ie.Get_dI2b());
349 }
350 
352  const DenseMatrix &DS,
353  const double weight,
354  DenseMatrix &A) const
355 {
356  // P = 2*(I2b - 1)*dI2b
357  // dP = 2*(dI2b x dI2b) + 2*(I2b - 1)*ddI2b
358  ie.SetJacobian(Jpt.GetData());
359  ie.SetDerivativeMatrix(DS.Height(), DS.GetData());
360  ie.Assemble_TProd(2*weight, ie.Get_dI2b(), A.GetData());
361  ie.Assemble_ddI2b(2*weight*(ie.Get_I2b() - 1.0), A.GetData());
362 }
363 
364 double TMOP_Metric_056::EvalW(const DenseMatrix &Jpt) const
365 {
366  // mu_56 = 0.5*(I2b + 1/I2b) - 1
367  ie.SetJacobian(Jpt.GetData());
368  const double I2b = ie.Get_I2b();
369  return 0.5*(I2b + 1.0/I2b) - 1.0;
370 }
371 
373 {
374  // mu_56 = 0.5*(I2b + 1/I2b) - 1
375  // P = 0.5*(1 - 1/I2b^2)*dI2b
376  ie.SetJacobian(Jpt.GetData());
377  P.Set(0.5 - 0.5/ie.Get_I2(), ie.Get_dI2b());
378 }
379 
381  const DenseMatrix &DS,
382  const double weight,
383  DenseMatrix &A) const
384 {
385  // P = 0.5*(1 - 1/I2b^2)*dI2b
386  // dP = (1/I2b^3)*(dI2b x dI2b) + (0.5 - 0.5/I2)*ddI2b
387  ie.SetJacobian(Jpt.GetData());
388  ie.SetDerivativeMatrix(DS.Height(), DS.GetData());
389  ie.Assemble_TProd(weight/(ie.Get_I2()*ie.Get_I2b()),
390  ie.Get_dI2b(), A.GetData());
391  ie.Assemble_ddI2b(weight*(0.5 - 0.5/ie.Get_I2()), A.GetData());
392 }
393 
394 double TMOP_Metric_058::EvalW(const DenseMatrix &Jpt) const
395 {
396  // mu_58 = I1b*(I1b - 2)
397  ie.SetJacobian(Jpt.GetData());
398  const double I1b = ie.Get_I1b();
399  return I1b*(I1b - 1.0);
400 }
401 
403 {
404  // mu_58 = I1b*(I1b - 2)
405  // P = (2*I1b - 2)*dI1b
406  ie.SetJacobian(Jpt.GetData());
407  P.Set(2*ie.Get_I1b() - 2.0, ie.Get_dI1b());
408 }
409 
411  const DenseMatrix &DS,
412  const double weight,
413  DenseMatrix &A) const
414 {
415  // P = (2*I1b - 2)*dI1b
416  // dP = 2*(dI1b x dI1b) + (2*I1b - 2)*ddI1b
417  ie.SetJacobian(Jpt.GetData());
418  ie.SetDerivativeMatrix(DS.Height(), DS.GetData());
419  ie.Assemble_TProd(2*weight, ie.Get_dI1b(), A.GetData());
420  ie.Assemble_ddI1b(weight*(2*ie.Get_I1b() - 2.0), A.GetData());
421 }
422 
423 double TMOP_Metric_077::EvalW(const DenseMatrix &Jpt) const
424 {
425  ie.SetJacobian(Jpt.GetData());
426  const double I2 = ie.Get_I2b();
427  return 0.5*(I2*I2 + 1./(I2*I2) - 2.);
428 }
429 
431 {
432  // Using I2b^2 = I2.
433  // dmu77_dJ = 1/2 (1 - 1/I2^2) dI2_dJ.
434  ie.SetJacobian(Jpt.GetData());
435  const double I2 = ie.Get_I2();
436  P.Set(0.5 * (1.0 - 1.0 / (I2 * I2)), ie.Get_dI2());
437 }
438 
440  const DenseMatrix &DS,
441  const double weight,
442  DenseMatrix &A) const
443 {
444  ie.SetJacobian(Jpt.GetData());
445  ie.SetDerivativeMatrix(DS.Height(), DS.GetData());
446  const double I2 = ie.Get_I2(), I2inv_sq = 1.0 / (I2 * I2);
447  ie.Assemble_ddI2(weight*0.5*(1.0 - I2inv_sq), A.GetData());
448  ie.Assemble_TProd(weight * I2inv_sq / I2, ie.Get_dI2(), A.GetData());
449 }
450 
451 double TMOP_Metric_211::EvalW(const DenseMatrix &Jpt) const
452 {
453  // mu_211 = (det(J) - 1)^2 - det(J) + (det(J)^2 + eps)^{1/2}
454  // = (I2b - 1)^2 - I2b + sqrt(I2b^2 + eps)
455  ie.SetJacobian(Jpt.GetData());
456  const double I2b = ie.Get_I2b();
457  return (I2b - 1.0)*(I2b - 1.0) - I2b + std::sqrt(I2b*I2b + eps);
458 }
459 
461 {
462  MFEM_ABORT("Metric not implemented yet. Use metric mu_55 instead.");
463 }
464 
466  const DenseMatrix &DS,
467  const double weight,
468  DenseMatrix &A) const
469 {
470  MFEM_ABORT("Metric not implemented yet. Use metric mu_55 instead.");
471 }
472 
473 double TMOP_Metric_252::EvalW(const DenseMatrix &Jpt) const
474 {
475  // mu_252 = 0.5*(det(J) - 1)^2 / (det(J) - tau0).
476  ie.SetJacobian(Jpt.GetData());
477  const double I2b = ie.Get_I2b();
478  return 0.5*(I2b - 1.0)*(I2b - 1.0)/(I2b - tau0);
479 }
480 
482 {
483  // mu_252 = 0.5*(det(J) - 1)^2 / (det(J) - tau0)
484  // P = (c - 0.5*c*c ) * dI2b
485  //
486  // c = (I2b - 1)/(I2b - tau0), see TMOP_Metric_352 for details
487  ie.SetJacobian(Jpt.GetData());
488  const double I2b = ie.Get_I2b();
489  const double c = (I2b - 1.0)/(I2b - tau0);
490  P.Set(c - 0.5*c*c, ie.Get_dI2b());
491 }
492 
494  const DenseMatrix &DS,
495  const double weight,
496  DenseMatrix &A) const
497 {
498  // c = (I2b - 1)/(I2b - tau0), see TMOP_Metric_352 for details
499  //
500  // P = (c - 0.5*c*c ) * dI2b
501  // dP = (1 - c)^2/(I2b - tau0)*(dI2b x dI2b) + (c - 0.5*c*c)*ddI2b
502  ie.SetJacobian(Jpt.GetData());
503  ie.SetDerivativeMatrix(DS.Height(), DS.GetData());
504  const double I2b = ie.Get_I2b();
505  const double c0 = 1.0/(I2b - tau0);
506  const double c = c0*(I2b - 1.0);
507  ie.Assemble_TProd(weight*c0*(1.0 - c)*(1.0 - c), ie.Get_dI2b(), A.GetData());
508  ie.Assemble_ddI2b(weight*(c - 0.5*c*c), A.GetData());
509 }
510 
511 double TMOP_Metric_301::EvalW(const DenseMatrix &Jpt) const
512 {
513  ie.SetJacobian(Jpt.GetData());
514  return std::sqrt(ie.Get_I1b()*ie.Get_I2b())/3. - 1.;
515 }
516 
518 {
519  // W = (1/3)*sqrt(I1b*I2b) - 1
520  // dW = (1/6)/sqrt(I1b*I2b)*[I2b*dI1b + I1b*dI2b]
521  ie.SetJacobian(Jpt.GetData());
522  const double a = 1./(6.*std::sqrt(ie.Get_I1b()*ie.Get_I2b()));
523  Add(a*ie.Get_I2b(), ie.Get_dI1b(), a*ie.Get_I1b(), ie.Get_dI2b(), P);
524 }
525 
527  const DenseMatrix &DS,
528  const double weight,
529  DenseMatrix &A) const
530 {
531  // dW = (1/6)/sqrt(I1b*I2b)*[I2b*dI1b + I1b*dI2b]
532  // dW = (1/6)*[z2*dI1b + z1*dI2b], z1 = sqrt(I1b/I2b), z2 = sqrt(I2b/I1b)
533  // ddW = (1/6)*[dI1b x dz2 + z2*ddI1b + dI2b x dz1 + z1*ddI2b]
534  //
535  // dz1 = (1/2)*sqrt(I2b/I1b) [ (1/I2b)*dI1b + (I1b/(I2b*I2b))*dI2b ]
536  // = (1/2)/sqrt(I1b*I2b) [ dI1b + (I1b/I2b)*dI2b ]
537  // dz2 = (1/2)/sqrt(I1b*I2b) [ (I2b/I1b)*dI1b + dI2b ]
538  //
539  // dI1b x dz2 + dI2b x dz1 =
540  // (1/2)/sqrt(I1b*I2b) dI1b x [ (I2b/I1b)*dI1b + dI2b ] +
541  // (1/2)/sqrt(I1b*I2b) dI2b x [ dI1b + (I1b/I2b)*dI2b ] =
542  // (1/2)/sqrt(I1b*I2b) [sqrt(I2b/I1b)*dI1b + sqrt(I1b/I2b)*dI2b] x
543  // [sqrt(I2b/I1b)*dI1b + sqrt(I1b/I2b)*dI2b] =
544  // (1/2)/sqrt(I1b*I2b) [ 6*dW x 6*dW ] =
545  // (1/2)*(I1b*I2b)^{-3/2} (I2b*dI1b + I1b*dI2b) x (I2b*dI1b + I1b*dI2b)
546  //
547  // z1 = I1b/sqrt(I1b*I2b), z2 = I2b/sqrt(I1b*I2b)
548 
549  ie.SetJacobian(Jpt.GetData());
550  ie.SetDerivativeMatrix(DS.Height(), DS.GetData());
551  double d_I1b_I2b_data[9];
552  DenseMatrix d_I1b_I2b(d_I1b_I2b_data, 3, 3);
553  Add(ie.Get_I2b(), ie.Get_dI1b(), ie.Get_I1b(), ie.Get_dI2b(), d_I1b_I2b);
554  const double I1b_I2b = ie.Get_I1b()*ie.Get_I2b();
555  const double a = weight/(6*std::sqrt(I1b_I2b));
556  ie.Assemble_ddI1b(a*ie.Get_I2b(), A.GetData());
557  ie.Assemble_ddI2b(a*ie.Get_I1b(), A.GetData());
558  ie.Assemble_TProd(a/(2*I1b_I2b), d_I1b_I2b_data, A.GetData());
559 }
560 
561 double TMOP_Metric_302::EvalW(const DenseMatrix &Jpt) const
562 {
563  // mu_2 = |J|^2 |J^{-1}|^2 / 9 - 1
564  // = (l1^2 + l2^2 + l3^3)*(l1^{-2} + l2^{-2} + l3^{-2}) / 9 - 1
565  // = I1*(l2^2*l3^2 + l1^2*l3^2 + l1^2*l2^2)/l1^2/l2^2/l3^2/9 - 1
566  // = I1*I2/det(J)^2/9 - 1 = I1b*I2b/9-1
567  ie.SetJacobian(Jpt.GetData());
568  return ie.Get_I1b()*ie.Get_I2b()/9. - 1.;
569 }
570 
572 {
573  // mu_2 = I1b*I2b/9-1
574  // P = (I1b/9)*dI2b + (I2b/9)*dI1b
575  ie.SetJacobian(Jpt.GetData());
576  Add(ie.Get_I1b()/9, ie.Get_dI2b(), ie.Get_I2b()/9, ie.Get_dI1b(), P);
577 }
578 
580  const DenseMatrix &DS,
581  const double weight,
582  DenseMatrix &A) const
583 {
584  // P = (I1b/9)*dI2b + (I2b/9)*dI1b
585  // dP = (dI2b x dI1b)/9 + (I1b/9)*ddI2b + (dI1b x dI2b)/9 + (I2b/9)*ddI1b
586  // = (dI2b x dI1b + dI1b x dI2b)/9 + (I1b/9)*ddI2b + (I2b/9)*ddI1b
587  ie.SetJacobian(Jpt.GetData());
588  ie.SetDerivativeMatrix(DS.Height(), DS.GetData());
589  const double c1 = weight/9;
590  ie.Assemble_TProd(c1, ie.Get_dI1b(), ie.Get_dI2b(), A.GetData());
591  ie.Assemble_ddI2b(c1*ie.Get_I1b(), A.GetData());
592  ie.Assemble_ddI1b(c1*ie.Get_I2b(), A.GetData());
593 }
594 
595 double TMOP_Metric_303::EvalW(const DenseMatrix &Jpt) const
596 {
597  ie.SetJacobian(Jpt.GetData());
598  return ie.Get_I1b()/3.0 - 1.0;
599 }
600 
602 {
603  ie.SetJacobian(Jpt.GetData());
604  P.Set(1./3., ie.Get_dI1b());
605 }
606 
608  const DenseMatrix &DS,
609  const double weight,
610  DenseMatrix &A) const
611 {
612  ie.SetJacobian(Jpt.GetData());
613  ie.SetDerivativeMatrix(DS.Height(), DS.GetData());
614  ie.Assemble_ddI1b(weight/3., A.GetData());
615 }
616 
617 double TMOP_Metric_315::EvalW(const DenseMatrix &Jpt) const
618 {
619  // mu_315 = mu_15_3D = (det(J) - 1)^2
620  ie.SetJacobian(Jpt.GetData());
621  const double c1 = ie.Get_I3b() - 1.0;
622  return c1*c1;
623 }
624 
626 {
627  // mu_315 = (I3b - 1)^2
628  // P = 2*(I3b - 1)*dI3b
629  ie.SetJacobian(Jpt.GetData());
630  P.Set(2*(ie.Get_I3b() - 1.0), ie.Get_dI3b());
631 }
632 
634  const DenseMatrix &DS,
635  const double weight,
636  DenseMatrix &A) const
637 {
638  // P = 2*(I3b - 1)*dI3b
639  // dP = 2*(dI3b x dI3b) + 2*(I3b - 1)*ddI3b
640  ie.SetJacobian(Jpt.GetData());
641  ie.SetDerivativeMatrix(DS.Height(), DS.GetData());
642  ie.Assemble_TProd(2*weight, ie.Get_dI3b(), A.GetData());
643  ie.Assemble_ddI3b(2*weight*(ie.Get_I3b() - 1.0), A.GetData());
644 }
645 
646 double TMOP_Metric_316::EvalW(const DenseMatrix &Jpt) const
647 {
648  // mu_316 = mu_16_3D = 0.5*(I3b + 1/I3b) - 1
649  ie.SetJacobian(Jpt.GetData());
650  const double I3b = ie.Get_I3b();
651  return 0.5*(I3b + 1.0/I3b) - 1.0;
652 }
653 
655 {
656  // mu_316 = mu_16_3D = 0.5*(I3b + 1/I3b) - 1
657  // P = 0.5*(1 - 1/I3b^2)*dI3b = (0.5 - 0.5/I3)*dI3b
658  ie.SetJacobian(Jpt.GetData());
659  P.Set(0.5 - 0.5/ie.Get_I3(), ie.Get_dI3b());
660 }
661 
663  const DenseMatrix &DS,
664  const double weight,
665  DenseMatrix &A) const
666 {
667  // P = 0.5*(1 - 1/I3b^2)*dI3b = (0.5 - 0.5/I3)*dI3b
668  // dP = (1/I3b^3)*(dI3b x dI3b) + (0.5 - 0.5/I3)*ddI3b
669  ie.SetJacobian(Jpt.GetData());
670  ie.SetDerivativeMatrix(DS.Height(), DS.GetData());
671  ie.Assemble_TProd(weight/(ie.Get_I3()*ie.Get_I3b()),
672  ie.Get_dI3b(), A.GetData());
673  ie.Assemble_ddI3b(weight*(0.5 - 0.5/ie.Get_I3()), A.GetData());
674 }
675 
676 double TMOP_Metric_321::EvalW(const DenseMatrix &Jpt) const
677 {
678  // mu_321 = mu_21_3D = |J - J^{-t}|^2
679  // = |J|^2 + |J^{-1}|^2 - 6
680  // = |J|^2 + (l1^{-2} + l2^{-2} + l3^{-2}) - 6
681  // = |J|^2 + (l2^2*l3^2 + l1^2*l3^2 + l1^2*l2^2)/det(J)^2 - 6
682  // = I1 + I2/I3b^2 - 6 = I1 + I2/I3 - 6
683  ie.SetJacobian(Jpt.GetData());
684  return ie.Get_I1() + ie.Get_I2()/ie.Get_I3() - 6.0;
685 }
686 
688 {
689  // mu_321 = I1 + I2/I3b^2 - 6 = I1 + I2/I3 - 6
690  // P = dI1 + (1/I3)*dI2 - (2*I2/I3b^3)*dI3b
691  ie.SetJacobian(Jpt.GetData());
692  const double I3 = ie.Get_I3();
693  Add(1.0/I3, ie.Get_dI2(),
694  -2*ie.Get_I2()/(I3*ie.Get_I3b()), ie.Get_dI3b(), P);
695  P += ie.Get_dI1();
696 }
697 
699  const DenseMatrix &DS,
700  const double weight,
701  DenseMatrix &A) const
702 {
703  // P = dI1 + (1/I3)*dI2 - (2*I2/I3b^3)*dI3b
704  // dP = ddI1 + (-2/I3b^3)*(dI2 x dI3b) + (1/I3)*ddI2 + (dI3b x dz) + z*ddI3b
705  //
706  // z = -2*I2/I3b^3
707  // dz = (-2/I3b^3)*dI2 + (2*I2)*(3/I3b^4)*dI3b
708  //
709  // dP = ddI1 + (-2/I3b^3)*(dI2 x dI3b + dI3b x dI2) + (1/I3)*ddI2
710  // + (6*I2/I3b^4)*(dI3b x dI3b) + (-2*I2/I3b^3)*ddI3b
711  ie.SetJacobian(Jpt.GetData());
712  ie.SetDerivativeMatrix(DS.Height(), DS.GetData());
713  const double c0 = 1.0/ie.Get_I3b();
714  const double c1 = weight*c0*c0;
715  const double c2 = -2*c0*c1;
716  const double c3 = c2*ie.Get_I2();
717  ie.Assemble_ddI1(weight, A.GetData());
718  ie.Assemble_ddI2(c1, A.GetData());
719  ie.Assemble_ddI3b(c3, A.GetData());
720  ie.Assemble_TProd(c2, ie.Get_dI2(), ie.Get_dI3b(), A.GetData());
721  ie.Assemble_TProd(-3*c0*c3, ie.Get_dI3b(), A.GetData());
722 }
723 
724 double TMOP_Metric_352::EvalW(const DenseMatrix &Jpt) const
725 {
726  // mu_352 = 0.5*(det(J) - 1)^2 / (det(J) - tau0)
727  ie.SetJacobian(Jpt.GetData());
728  const double I3b = ie.Get_I3b();
729  return 0.5*(I3b - 1.0)*(I3b - 1.0)/(I3b - tau0);
730 }
731 
733 {
734  // mu_352 = 0.5*(det(J) - 1)^2 / (det(J) - tau0)
735  // P = (I3b - 1)/(I3b - tau0)*dI3b + 0.5*(I3b - 1)^2*(-1/(I3b - tau0)^2)*dI3b
736  // = [ (I3b - 1)/(I3b - tau0) - 0.5*(I3b - 1)^2/(I3b - tau0)^2 ] * dI3b
737  // = (c - 0.5*c*c) * dI3b
738  ie.SetJacobian(Jpt.GetData());
739  const double I3b = ie.Get_I3b();
740  const double c = (I3b - 1.0)/(I3b - tau0);
741  P.Set(c - 0.5*c*c, ie.Get_dI3b());
742 }
743 
745  const DenseMatrix &DS,
746  const double weight,
747  DenseMatrix &A) const
748 {
749  // c = (I3b - 1)/(I3b - tau0)
750  //
751  // P = (c - 0.5*c*c) * dI3b
752  // dP = (1 - c)*(dI3b x dc) + (c - 0.5*c*c)*ddI3b
753  //
754  // dc = 1/(I3b - tau0)*dI3b - (I3b - 1)/(I3b - tau)^2*dI3b =
755  // = (1 - c)/(I3b - tau0)*dI3b
756  //
757  // dP = (1 - c)^2/(I3b - tau0)*(dI3b x dI3b) + (c - 0.5*c*c)*ddI3b
758  ie.SetJacobian(Jpt.GetData());
759  ie.SetDerivativeMatrix(DS.Height(), DS.GetData());
760  const double I3b = ie.Get_I3b();
761  const double c0 = 1.0/(I3b - tau0);
762  const double c = c0*(I3b - 1.0);
763  ie.Assemble_TProd(weight*c0*(1.0 - c)*(1.0 - c), ie.Get_dI3b(), A.GetData());
764  ie.Assemble_ddI3b(weight*(c - 0.5*c*c), A.GetData());
765 }
766 
767 
769 {
770  MFEM_VERIFY(nodes, "Nodes are not given!");
771  MFEM_ASSERT(avg_volume == 0.0, "the average volume is already computed!");
772 
773  Mesh *mesh = nodes->FESpace()->GetMesh();
774  const int NE = mesh->GetNE();
776  double volume = 0.0;
777 
778  for (int i = 0; i < NE; i++)
779  {
780  mesh->GetElementTransformation(i, *nodes, &Tr);
781  const IntegrationRule &ir =
782  IntRules.Get(mesh->GetElementBaseGeometry(i), Tr.OrderJ());
783  for (int j = 0; j < ir.GetNPoints(); j++)
784  {
785  const IntegrationPoint &ip = ir.IntPoint(j);
786  Tr.SetIntPoint(&ip);
787  volume += ip.weight * Tr.Weight();
788  }
789  }
790  if (!Parallel())
791  {
792  avg_volume = volume / NE;
793  }
794 #ifdef MFEM_USE_MPI
795  else
796  {
797  double area_NE[4];
798  area_NE[0] = volume; area_NE[1] = NE;
799  MPI_Allreduce(area_NE, area_NE + 2, 2, MPI_DOUBLE, MPI_SUM, comm);
800  avg_volume = area_NE[2] / area_NE[3];
801  }
802 #endif
803 }
804 
805 // virtual method
807  const IntegrationRule &ir,
808  DenseTensor &Jtr) const
809 {
810  MFEM_ASSERT(target_type == IDEAL_SHAPE_UNIT_SIZE || nodes != NULL, "");
811 
813  nodes->FESpace()->GetFE(e_id) : NULL;
814  const DenseMatrix &Wideal =
816  MFEM_ASSERT(Wideal.Height() == Jtr.SizeI(), "");
817  MFEM_ASSERT(Wideal.Width() == Jtr.SizeJ(), "");
818 
819  switch (target_type)
820  {
822  {
823  for (int i = 0; i < ir.GetNPoints(); i++) { Jtr(i) = Wideal; }
824  break;
825  }
827  {
828  if (avg_volume == 0.0) { ComputeAvgVolume(); }
829  DenseMatrix W(Wideal.Height());
830  W.Set(std::pow(volume_scale * avg_volume / Wideal.Det(),
831  1./W.Height()), Wideal);
832  for (int i = 0; i < ir.GetNPoints(); i++) { Jtr(i) = W; }
833  break;
834  }
837  {
838  const int dim = nfe->GetDim(), dof = nfe->GetDof();
839  MFEM_ASSERT(dim == nodes->FESpace()->GetVDim(), "");
840  DenseMatrix dshape(dof, dim), pos(dof, dim);
841  Array<int> xdofs(dof * dim);
842  Vector posV(pos.Data(), dof * dim);
843  double detW;
844 
845  // always initialize detW to suppress a warning:
846  detW = (target_type == IDEAL_SHAPE_GIVEN_SIZE) ? Wideal.Det() : 0.0;
847  nodes->FESpace()->GetElementVDofs(e_id, xdofs);
848  nodes->GetSubVector(xdofs, posV);
849  for (int i = 0; i < ir.GetNPoints(); i++)
850  {
851  nfe->CalcDShape(ir.IntPoint(i), dshape);
852  MultAtB(pos, dshape, Jtr(i));
854  {
855  const double det = Jtr(i).Det();
856  MFEM_VERIFY(det > 0.0, "Initial mesh is inverted!");
857  Jtr(i).Set(std::pow(det / detW, 1./dim), Wideal);
858  }
859  }
860  break;
861  }
862  default:
863  MFEM_ABORT("invalid target type!");
864  }
865 }
866 
868  const GridFunction &dist, Coefficient &w0,
869  TMOP_LimiterFunction *lfunc)
870 {
871  nodes0 = &n0;
872  coeff0 = &w0;
873  lim_dist = &dist;
874 
875  delete lim_func;
876  if (lfunc)
877  {
878  lim_func = lfunc;
879  }
880  else
881  {
883  }
884 }
886  TMOP_LimiterFunction *lfunc)
887 {
888  nodes0 = &n0;
889  coeff0 = &w0;
890  lim_dist = NULL;
891 
892  delete lim_func;
893  if (lfunc)
894  {
895  lim_func = lfunc;
896  }
897  else
898  {
900  }
901 }
902 
905  const Vector &elfun)
906 {
907  int dof = el.GetDof(), dim = el.GetDim();
908  double energy;
909 
910  DSh.SetSize(dof, dim);
911  Jrt.SetSize(dim);
912  Jpr.SetSize(dim);
913  Jpt.SetSize(dim);
914  PMatI.UseExternalData(elfun.GetData(), dof, dim);
915 
916  const IntegrationRule *ir = IntRule;
917  if (!ir)
918  {
919  ir = &(IntRules.Get(el.GetGeomType(), 2*el.GetOrder() + 3)); // <---
920  }
921 
922  energy = 0.0;
923  DenseTensor Jtr(dim, dim, ir->GetNPoints());
924  targetC->ComputeElementTargets(T.ElementNo, el, *ir, Jtr);
925 
926  // Limited case.
927  Vector shape, p, p0, d_vals;
928  DenseMatrix pos0;
929  if (coeff0)
930  {
931  shape.SetSize(dof);
932  p.SetSize(dim);
933  p0.SetSize(dim);
934  pos0.SetSize(dof, dim);
935  Vector pos0V(pos0.Data(), dof * dim);
936  Array<int> pos_dofs;
937  nodes0->FESpace()->GetElementVDofs(T.ElementNo, pos_dofs);
938  nodes0->GetSubVector(pos_dofs, pos0V);
939  if (lim_dist)
940  {
941  lim_dist->GetValues(T.ElementNo, *ir, d_vals);
942  }
943  else
944  {
945  d_vals.SetSize(ir->GetNPoints()); d_vals = 1.0;
946  }
947  }
948 
949  // Define ref->physical transformation, when a Coefficient is specified.
950  IsoparametricTransformation *Tpr = NULL;
951  if (coeff1 || coeff0)
952  {
953  Tpr = new IsoparametricTransformation;
954  Tpr->SetFE(&el);
955  Tpr->ElementNo = T.ElementNo;
956  Tpr->Attribute = T.Attribute;
957  Tpr->GetPointMat().Transpose(PMatI); // PointMat = PMatI^T
958  }
959  // TODO: computing the coefficients 'coeff1' and 'coeff0' in physical
960  // coordinates means that, generally, the gradient and Hessian of the
961  // TMOP_Integrator will depend on the derivatives of the coefficients.
962  //
963  // In some cases the coefficients are independent of any movement of
964  // the physical coordinates (i.e. changes in 'elfun'), e.g. when the
965  // coefficient is a ConstantCoefficient or a GridFunctionCoefficient.
966 
967  for (int i = 0; i < ir->GetNPoints(); i++)
968  {
969  const IntegrationPoint &ip = ir->IntPoint(i);
970  const DenseMatrix &Jtr_i = Jtr(i);
971  metric->SetTargetJacobian(Jtr_i);
972  CalcInverse(Jtr_i, Jrt);
973  const double weight = ip.weight * Jtr_i.Det();
974 
975  el.CalcDShape(ip, DSh);
976  MultAtB(PMatI, DSh, Jpr);
977  Mult(Jpr, Jrt, Jpt);
978 
979  double val = metric_normal * metric->EvalW(Jpt);
980  if (coeff1) { val *= coeff1->Eval(*Tpr, ip); }
981 
982  if (coeff0)
983  {
984  el.CalcShape(ip, shape);
985  PMatI.MultTranspose(shape, p);
986  pos0.MultTranspose(shape, p0);
987  val += lim_normal *
988  lim_func->Eval(p, p0, d_vals(i)) * coeff0->Eval(*Tpr, ip);
989  }
990  energy += weight * val;
991  }
992  delete Tpr;
993  return energy;
994 }
995 
998  const Vector &elfun, Vector &elvect)
999 {
1000  int dof = el.GetDof(), dim = el.GetDim();
1001 
1002  DSh.SetSize(dof, dim);
1003  DS.SetSize(dof, dim);
1004  Jrt.SetSize(dim);
1005  Jpt.SetSize(dim);
1006  P.SetSize(dim);
1007  PMatI.UseExternalData(elfun.GetData(), dof, dim);
1008  elvect.SetSize(dof*dim);
1009  PMatO.UseExternalData(elvect.GetData(), dof, dim);
1010 
1011  const IntegrationRule *ir = IntRule;
1012  if (!ir)
1013  {
1014  ir = &(IntRules.Get(el.GetGeomType(), 2*el.GetOrder() + 3)); // <---
1015  }
1016 
1017  elvect = 0.0;
1018  DenseTensor Jtr(dim, dim, ir->GetNPoints());
1019  targetC->ComputeElementTargets(T.ElementNo, el, *ir, Jtr);
1020 
1021  // Limited case.
1022  DenseMatrix pos0;
1023  Vector shape, p, p0, d_vals, grad;
1024  if (coeff0)
1025  {
1026  shape.SetSize(dof);
1027  p.SetSize(dim);
1028  p0.SetSize(dim);
1029  pos0.SetSize(dof, dim);
1030  Vector pos0V(pos0.Data(), dof * dim);
1031  Array<int> pos_dofs;
1032  nodes0->FESpace()->GetElementVDofs(T.ElementNo, pos_dofs);
1033  nodes0->GetSubVector(pos_dofs, pos0V);
1034  if (lim_dist)
1035  {
1036  lim_dist->GetValues(T.ElementNo, *ir, d_vals);
1037  }
1038  else
1039  {
1040  d_vals.SetSize(ir->GetNPoints()); d_vals = 1.0;
1041  }
1042  }
1043 
1044  // Define ref->physical transformation, when a Coefficient is specified.
1045  IsoparametricTransformation *Tpr = NULL;
1046  if (coeff1 || coeff0)
1047  {
1048  Tpr = new IsoparametricTransformation;
1049  Tpr->SetFE(&el);
1050  Tpr->ElementNo = T.ElementNo;
1051  Tpr->Attribute = T.Attribute;
1052  Tpr->GetPointMat().Transpose(PMatI); // PointMat = PMatI^T
1053  }
1054 
1055  for (int i = 0; i < ir->GetNPoints(); i++)
1056  {
1057  const IntegrationPoint &ip = ir->IntPoint(i);
1058  const DenseMatrix &Jtr_i = Jtr(i);
1059  metric->SetTargetJacobian(Jtr_i);
1060  CalcInverse(Jtr_i, Jrt);
1061  const double weight = ip.weight * Jtr_i.Det();
1062  double weight_m = weight * metric_normal;
1063 
1064  el.CalcDShape(ip, DSh);
1065  Mult(DSh, Jrt, DS);
1066  MultAtB(PMatI, DS, Jpt);
1067 
1068  metric->EvalP(Jpt, P);
1069 
1070  if (coeff1) { weight_m *= coeff1->Eval(*Tpr, ip); }
1071 
1072  P *= weight_m;
1073  AddMultABt(DS, P, PMatO);
1074 
1075  if (coeff0)
1076  {
1077  el.CalcShape(ip, shape);
1078  PMatI.MultTranspose(shape, p);
1079  pos0.MultTranspose(shape, p0);
1080  lim_func->Eval_d1(p, p0, d_vals(i), grad);
1081  grad *= weight * lim_normal * coeff0->Eval(*Tpr, ip);
1082  AddMultVWt(shape, grad, PMatO);
1083  }
1084  }
1085  delete Tpr;
1086 }
1087 
1090  const Vector &elfun,
1091  DenseMatrix &elmat)
1092 {
1093  int dof = el.GetDof(), dim = el.GetDim();
1094 
1095  DSh.SetSize(dof, dim);
1096  DS.SetSize(dof, dim);
1097  Jrt.SetSize(dim);
1098  Jpt.SetSize(dim);
1099  PMatI.UseExternalData(elfun.GetData(), dof, dim);
1100  elmat.SetSize(dof*dim);
1101 
1102  const IntegrationRule *ir = IntRule;
1103  if (!ir)
1104  {
1105  ir = &(IntRules.Get(el.GetGeomType(), 2*el.GetOrder() + 3)); // <---
1106  }
1107 
1108  elmat = 0.0;
1109  DenseTensor Jtr(dim, dim, ir->GetNPoints());
1110  targetC->ComputeElementTargets(T.ElementNo, el, *ir, Jtr);
1111 
1112  // Limited case.
1113  DenseMatrix pos0, grad_grad;
1114  Vector shape, p, p0, d_vals;
1115  if (coeff0)
1116  {
1117  shape.SetSize(dof);
1118  p.SetSize(dim);
1119  p0.SetSize(dim);
1120  pos0.SetSize(dof, dim);
1121  Vector pos0V(pos0.Data(), dof * dim);
1122  Array<int> pos_dofs;
1123  nodes0->FESpace()->GetElementVDofs(T.ElementNo, pos_dofs);
1124  nodes0->GetSubVector(pos_dofs, pos0V);
1125  if (lim_dist)
1126  {
1127  lim_dist->GetValues(T.ElementNo, *ir, d_vals);
1128  }
1129  else
1130  {
1131  d_vals.SetSize(ir->GetNPoints()); d_vals = 1.0;
1132  }
1133  }
1134 
1135  // Define ref->physical transformation, when a Coefficient is specified.
1136  IsoparametricTransformation *Tpr = NULL;
1137  if (coeff1 || coeff0)
1138  {
1139  Tpr = new IsoparametricTransformation;
1140  Tpr->SetFE(&el);
1141  Tpr->ElementNo = T.ElementNo;
1142  Tpr->Attribute = T.Attribute;
1143  Tpr->GetPointMat().Transpose(PMatI);
1144  }
1145 
1146  for (int i = 0; i < ir->GetNPoints(); i++)
1147  {
1148  const IntegrationPoint &ip = ir->IntPoint(i);
1149  const DenseMatrix &Jtr_i = Jtr(i);
1150  metric->SetTargetJacobian(Jtr_i);
1151  CalcInverse(Jtr_i, Jrt);
1152  const double weight = ip.weight * Jtr_i.Det();
1153  double weight_m = weight * metric_normal;
1154 
1155  el.CalcDShape(ip, DSh);
1156  Mult(DSh, Jrt, DS);
1157  MultAtB(PMatI, DS, Jpt);
1158 
1159  if (coeff1) { weight_m *= coeff1->Eval(*Tpr, ip); }
1160 
1161  metric->AssembleH(Jpt, DS, weight_m, elmat);
1162 
1163  if (coeff0)
1164  {
1165  el.CalcShape(ip, shape);
1166  PMatI.MultTranspose(shape, p);
1167  pos0.MultTranspose(shape, p0);
1168  weight_m = weight * lim_normal * coeff0->Eval(*Tpr, ip);
1169  lim_func->Eval_d2(p, p0, d_vals(i), grad_grad);
1170  for (int i = 0; i < dof; i++)
1171  {
1172  const double w_shape_i = weight_m * shape(i);
1173  for (int j = 0; j < dof; j++)
1174  {
1175  const double w = w_shape_i * shape(j);
1176  for (int d1 = 0; d1 < dim; d1++)
1177  {
1178  for (int d2 = 0; d2 < dim; d2++)
1179  {
1180  elmat(d1*dof + i, d2*dof + j) += w * grad_grad(d1, d2);
1181  }
1182  }
1183  }
1184  }
1185  }
1186  }
1187  delete Tpr;
1188 }
1189 
1191 {
1193  metric_normal = 1.0 / metric_normal;
1194  lim_normal = 1.0 / lim_normal;
1195 }
1196 
1197 #ifdef MFEM_USE_MPI
1199 {
1200  double loc[2];
1201  ComputeNormalizationEnergies(x, loc[0], loc[1]);
1202  double rdc[2];
1203  MPI_Allreduce(loc, rdc, 2, MPI_DOUBLE, MPI_SUM, x.ParFESpace()->GetComm());
1204  metric_normal = 1.0 / rdc[0]; lim_normal = 1.0 / rdc[1];
1205 }
1206 #endif
1207 
1209  double &metric_energy,
1210  double &lim_energy)
1211 {
1212  Array<int> vdofs;
1213  Vector x_vals;
1214  const FiniteElementSpace* const fes = x.FESpace();
1215  const FiniteElement *fe = fes->GetFE(0);
1216 
1217  const int dof = fes->GetFE(0)->GetDof(), dim = fes->GetFE(0)->GetDim();
1218 
1219  DSh.SetSize(dof, dim);
1220  Jrt.SetSize(dim);
1221  Jpr.SetSize(dim);
1222  Jpt.SetSize(dim);
1223 
1224  const IntegrationRule *ir = IntRule;
1225  if (!ir)
1226  {
1227  ir = &(IntRules.Get(fe->GetGeomType(), 2*fe->GetOrder() + 3)); // <---
1228  }
1229 
1230  DenseTensor Jtr(dim, dim, ir->GetNPoints());
1231 
1232  metric_energy = 0.0;
1233  lim_energy = 0.0;
1234  for (int i = 0; i < fes->GetNE(); i++)
1235  {
1236  fe = fes->GetFE(i);
1237  targetC->ComputeElementTargets(i, *fe, *ir, Jtr);
1238  fes->GetElementVDofs(i, vdofs);
1239  x.GetSubVector(vdofs, x_vals);
1240  PMatI.UseExternalData(x_vals.GetData(), dof, dim);
1241 
1242  for (int i = 0; i < ir->GetNPoints(); i++)
1243  {
1244  const IntegrationPoint &ip = ir->IntPoint(i);
1245  metric->SetTargetJacobian(Jtr(i));
1246  CalcInverse(Jtr(i), Jrt);
1247  const double weight = ip.weight * Jtr(i).Det();
1248 
1249  fe->CalcDShape(ip, DSh);
1250  MultAtB(PMatI, DSh, Jpr);
1251  Mult(Jpr, Jrt, Jpt);
1252 
1253  metric_energy += weight * metric->EvalW(Jpt);
1254  lim_energy += weight;
1255  }
1256  }
1257 }
1258 
1260  const TargetConstructor &tc,
1261  const Mesh &mesh, GridFunction &metric_gf)
1262 {
1263  const int NE = mesh.GetNE();
1264  const GridFunction &nodes = *mesh.GetNodes();
1265  const int dim = mesh.Dimension();
1266  DenseMatrix Winv(dim), T(dim), A(dim), dshape, pos;
1267  Array<int> pos_dofs, gf_dofs;
1268  DenseTensor W;
1269  Vector posV;
1270 
1271  for (int i = 0; i < NE; i++)
1272  {
1273  const FiniteElement &fe_pos = *nodes.FESpace()->GetFE(i);
1274  const IntegrationRule &ir = metric_gf.FESpace()->GetFE(i)->GetNodes();
1275  const int nsp = ir.GetNPoints(), dof = fe_pos.GetDof();
1276 
1277  W.SetSize(dim, dim, nsp);
1278  tc.ComputeElementTargets(i, fe_pos, ir, W);
1279 
1280  dshape.SetSize(dof, dim);
1281  pos.SetSize(dof, dim);
1282  posV.SetDataAndSize(pos.Data(), dof * dim);
1283 
1284  metric_gf.FESpace()->GetElementDofs(i, gf_dofs);
1285  nodes.FESpace()->GetElementVDofs(i, pos_dofs);
1286  nodes.GetSubVector(pos_dofs, posV);
1287 
1288  for (int j = 0; j < nsp; j++)
1289  {
1290  const DenseMatrix &Wj = W(j);
1291  metric.SetTargetJacobian(Wj);
1292  CalcInverse(Wj, Winv);
1293 
1294  const IntegrationPoint &ip = ir.IntPoint(j);
1295  fe_pos.CalcDShape(ip, dshape);
1296  MultAtB(pos, dshape, A);
1297  Mult(A, Winv, T);
1298 
1299  metric_gf(gf_dofs[j]) = metric.EvalW(T);
1300  }
1301  }
1302 }
1303 
1304 } // namespace mfem
int GetNPoints() const
Returns the number of the points in the integration rule.
Definition: intrules.hpp:237
Abstract class for Finite Elements.
Definition: fe.hpp:229
InvariantsEvaluator2D< double > ie
Definition: tmop.hpp:292
virtual void AssembleH(const DenseMatrix &Jpt, const DenseMatrix &DS, const double weight, DenseMatrix &A) const
Evaluate the derivative of the 1st Piola-Kirchhoff stress tensor and assemble its contribution to the...
Definition: tmop.cpp:276
virtual void AssembleH(const DenseMatrix &Jpt, const DenseMatrix &DS, const double weight, DenseMatrix &A) const
Evaluate the derivative of the 1st Piola-Kirchhoff stress tensor and assemble its contribution to the...
Definition: tmop.cpp:33
virtual double EvalW(const DenseMatrix &Jpt) const
Evaluate the strain energy density function, W = W(Jpt).
Definition: tmop.cpp:257
int GetDim() const
Returns the reference space dimension for the finite element.
Definition: fe.hpp:305
virtual void AssembleH(const DenseMatrix &Jpt, const DenseMatrix &DS, const double weight, DenseMatrix &A) const =0
Evaluate the derivative of the 1st Piola-Kirchhoff stress tensor and assemble its contribution to the...
void AddMultVWt(const Vector &v, const Vector &w, DenseMatrix &VWt)
VWt += v w^t.
Definition: densemat.cpp:3853
Class for an integration rule - an Array of IntegrationPoint.
Definition: intrules.hpp:85
DenseMatrix & GetPointMat()
Read and write access to the underlying point matrix describing the transformation.
Definition: eltrans.hpp:313
const TargetType target_type
Definition: tmop.hpp:551
Class for grid function - Vector with associated FE space.
Definition: gridfunc.hpp:27
DenseMatrix PMatO
Definition: tmop.hpp:640
const DenseMatrix * Jtr
Definition: tmop.hpp:27
InvariantsEvaluator3D< double > ie
Definition: tmop.hpp:430
void Assemble_ddI2b(scalar_t w, scalar_t *A)
Definition: invariants.hpp:387
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
Definition: intrules.cpp:877
virtual void EvalP(const DenseMatrix &Jpt, DenseMatrix &P) const
Evaluate the 1st Piola-Kirchhoff stress tensor, P = P(Jpt).
Definition: tmop.cpp:571
void Assemble_ddI2b(scalar_t w, scalar_t *A)
DenseMatrix Jrt
Definition: tmop.hpp:640
void SetDerivativeMatrix(int height, const scalar_t *Deriv)
The Deriv matrix is dof x 2, using column-major storage.
Definition: invariants.hpp:187
const GridFunction * lim_dist
Definition: tmop.hpp:624
Coefficient * coeff0
Definition: tmop.hpp:622
InvariantsEvaluator2D< double > ie
Definition: tmop.hpp:238
void EnableNormalization(const GridFunction &x)
Computes the normalization factors of the metric and limiting integrals using the mesh position given...
Definition: tmop.cpp:1190
const scalar_t * Get_dI3b()
Definition: invariants.hpp:786
void SetSize(int s)
Resize the vector to size s.
Definition: vector.hpp:400
void InterpolateTMOP_QualityMetric(TMOP_QualityMetric &metric, const TargetConstructor &tc, const Mesh &mesh, GridFunction &metric_gf)
Interpolates the metric&#39;s values at the nodes of metric_gf.
Definition: tmop.cpp:1259
void GetElementVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom in array dofs for i&#39;th element.
Definition: fespace.cpp:172
TMOP_QualityMetric * metric
Definition: tmop.hpp:610
InvariantsEvaluator2D< double > ie
Definition: tmop.hpp:255
double Det() const
Definition: densemat.cpp:472
Base class for limiting functions to be used in class TMOP_Integrator.
Definition: tmop.hpp:466
virtual double EvalW(const DenseMatrix &Jpt) const =0
Evaluate the strain energy density function, W = W(Jpt).
virtual void Eval_d2(const Vector &x, const Vector &x0, double dist, DenseMatrix &d2) const =0
Returns the Hessian of the limiting function f(x, x0, d) with respect to x.
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
Definition: table.cpp:476
virtual void AssembleH(const DenseMatrix &Jpt, const DenseMatrix &DS, const double weight, DenseMatrix &A) const
Evaluate the derivative of the 1st Piola-Kirchhoff stress tensor and assemble its contribution to the...
Definition: tmop.cpp:698
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Definition: operator.hpp:42
virtual void EvalP(const DenseMatrix &Jpt, DenseMatrix &P) const
Evaluate the 1st Piola-Kirchhoff stress tensor, P = P(Jpt).
Definition: tmop.cpp:625
double Norml2() const
Returns the l2 norm of the vector.
Definition: vector.cpp:709
virtual double EvalW(const DenseMatrix &Jpt) const
Evaluate the strain energy density function, W = W(Jpt).
Definition: tmop.cpp:162
DenseMatrix Jpr
Definition: tmop.hpp:640
virtual void ComputeElementTargets(int e_id, const FiniteElement &fe, const IntegrationRule &ir, DenseTensor &Jtr) const
Given an element and quadrature rule, computes ref-&gt;target transformation Jacobians for each quadratu...
Definition: tmop.cpp:806
virtual void EvalP(const DenseMatrix &Jpt, DenseMatrix &P) const
Evaluate the 1st Piola-Kirchhoff stress tensor, P = P(Jpt).
Definition: tmop.cpp:481
void SetIntPoint(const IntegrationPoint *ip)
Definition: eltrans.hpp:53
void GetSubVector(const Array< int > &dofs, Vector &elemvect) const
Definition: vector.cpp:472
virtual void EvalP(const DenseMatrix &Jpt, DenseMatrix &P) const =0
Evaluate the 1st Piola-Kirchhoff stress tensor, P = P(Jpt).
InvariantsEvaluator2D< double > ie
Definition: tmop.hpp:79
int GetOrder() const
Returns the order of the finite element. In the case of anisotropic orders, returns the maximum order...
Definition: fe.hpp:315
virtual double EvalW(const DenseMatrix &Jpt) const
Evaluate the strain energy density function, W = W(Jpt).
Definition: tmop.cpp:561
Data type dense matrix using column-major storage.
Definition: densemat.hpp:23
double metric_normal
Definition: tmop.hpp:616
void SetSize(int i, int j, int k)
Definition: densemat.hpp:699
int GetNE() const
Returns number of elements.
Definition: mesh.hpp:676
virtual void AssembleH(const DenseMatrix &Jpt, const DenseMatrix &DS, const double weight, DenseMatrix &A) const
Evaluate the derivative of the 1st Piola-Kirchhoff stress tensor and assemble its contribution to the...
Definition: tmop.cpp:493
Coefficient * coeff1
Definition: tmop.hpp:614
InvariantsEvaluator2D< double > ie
Definition: tmop.hpp:187
InvariantsEvaluator2D< double > ie
Definition: tmop.hpp:274
const GridFunction * nodes
Definition: tmop.hpp:548
void Assemble_TProd(scalar_t w, const scalar_t *X, const scalar_t *Y, scalar_t *A)
Definition: invariants.hpp:435
void Assemble_ddI1(scalar_t w, scalar_t *A)
Definition: invariants.hpp:229
double * GetData() const
Returns the matrix data array.
Definition: densemat.hpp:96
double * GetData() const
Return a pointer to the beginning of the Vector data.
Definition: vector.hpp:159
virtual void EvalP(const DenseMatrix &Jpt, DenseMatrix &P) const
Evaluate the 1st Piola-Kirchhoff stress tensor, P = P(Jpt).
Definition: tmop.cpp:687
Default limiter function in TMOP_Integrator.
Definition: tmop.hpp:487
Geometry::Type GetElementBaseGeometry(int i) const
Definition: mesh.hpp:759
void Set(double alpha, const double *A)
Set the matrix to alpha * A, assuming that A has the same dimensions as the matrix and uses column-ma...
Definition: densemat.cpp:556
void Assemble_ddI2(scalar_t w, scalar_t *A)
Definition: invariants.hpp:338
virtual double EvalW(const DenseMatrix &Jpt) const
Evaluate the strain energy density function, W = W(Jpt).
Definition: tmop.cpp:364
virtual void EvalP(const DenseMatrix &Jpt, DenseMatrix &P) const
Evaluate the 1st Piola-Kirchhoff stress tensor, P = P(Jpt).
Definition: tmop.cpp:517
const DenseMatrix & GetGeomToPerfGeomJac(int GeomType) const
Definition: geom.hpp:97
void SetTargetJacobian(const DenseMatrix &_Jtr)
Specify the reference-element -&gt; target-element Jacobian matrix for the point of interest.
Definition: tmop.hpp:44
virtual double EvalW(const DenseMatrix &Jpt) const
Evaluate the strain energy density function, W = W(Jpt).
Definition: tmop.cpp:67
virtual void AssembleH(const DenseMatrix &Jpt, const DenseMatrix &DS, const double weight, DenseMatrix &A) const
Evaluate the derivative of the 1st Piola-Kirchhoff stress tensor and assemble its contribution to the...
Definition: tmop.cpp:607
virtual void AssembleH(const DenseMatrix &Jpt, const DenseMatrix &DS, const double weight, DenseMatrix &A) const
Evaluate the derivative of the 1st Piola-Kirchhoff stress tensor and assemble its contribution to the...
Definition: tmop.cpp:380
Geometry::Type GetGeomType() const
Returns the Geometry::Type of the reference element.
Definition: fe.hpp:308
void Add(const DenseMatrix &A, const DenseMatrix &B, double alpha, DenseMatrix &C)
C = A + alpha*B.
Definition: densemat.cpp:3030
int GetNE() const
Returns number of elements in the mesh.
Definition: fespace.hpp:374
Abstract class for local mesh quality metrics in the target-matrix optimization paradigm (TMOP) by P...
Definition: tmop.hpp:24
Geometry Geometries
Definition: fe.cpp:11972
IntegrationPoint & IntPoint(int i)
Returns a reference to the i-th integration point.
Definition: intrules.hpp:240
void MultTranspose(const double *x, double *y) const
Multiply a vector with the transpose matrix.
Definition: densemat.cpp:224
void SetJacobian(const scalar_t *Jac)
The Jacobian should use column-major storage.
Definition: invariants.hpp:184
void Assemble_ddI3b(scalar_t w, scalar_t *A)
InvariantsEvaluator3D< double > ie
Definition: tmop.hpp:396
int dim
Definition: ex3.cpp:48
MPI_Comm GetComm() const
Definition: pfespace.hpp:239
virtual void EvalP(const DenseMatrix &Jpt, DenseMatrix &P) const
Evaluate the 1st Piola-Kirchhoff stress tensor, P = P(Jpt).
Definition: tmop.cpp:654
void EnableLimiting(const GridFunction &n0, const GridFunction &dist, Coefficient &w0, TMOP_LimiterFunction *lfunc=NULL)
Adds a limiting term to the integrator (general version).
Definition: tmop.cpp:867
virtual double EvalW(const DenseMatrix &Jpt) const
Evaluate the strain energy density function, W = W(Jpt).
Definition: tmop.cpp:451
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Definition: operator.hpp:36
virtual void AssembleH(const DenseMatrix &Jpt, const DenseMatrix &DS, const double weight, DenseMatrix &A) const
Evaluate the derivative of the 1st Piola-Kirchhoff stress tensor and assemble its contribution to the...
Definition: tmop.cpp:322
Mesh * GetMesh() const
Returns the mesh.
Definition: fespace.hpp:272
virtual void AssembleH(const DenseMatrix &Jpt, const DenseMatrix &DS, const double weight, DenseMatrix &A) const
Evaluate the derivative of the 1st Piola-Kirchhoff stress tensor and assemble its contribution to the...
Definition: tmop.cpp:351
virtual double EvalW(const DenseMatrix &Jpt) const
Evaluate the strain energy density function, W = W(Jpt).
Definition: tmop.cpp:224
InvariantsEvaluator2D< double > ie
Definition: tmop.hpp:310
virtual double EvalW(const DenseMatrix &Jpt) const
Evaluate the strain energy density function, W = W(Jpt).
Definition: tmop.cpp:595
const TargetConstructor * targetC
Definition: tmop.hpp:611
virtual void EvalP(const DenseMatrix &Jpt, DenseMatrix &P) const
Evaluate the 1st Piola-Kirchhoff stress tensor, P = P(Jpt).
Definition: tmop.cpp:460
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const =0
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
const scalar_t * Get_dI2b()
Definition: invariants.hpp:219
virtual void GetElementDofs(int i, Array< int > &dofs) const
Returns indexes of degrees of freedom in array dofs for i&#39;th element.
Definition: fespace.cpp:1439
virtual void AssembleH(const DenseMatrix &Jpt, const DenseMatrix &DS, const double weight, DenseMatrix &A) const
Evaluate the derivative of the 1st Piola-Kirchhoff stress tensor and assemble its contribution to the...
Definition: tmop.cpp:410
InvariantsEvaluator2D< double > ie
Definition: tmop.hpp:204
const IntegrationRule & GetNodes() const
Definition: fe.hpp:364
void SetDerivativeMatrix(int height, const scalar_t *Deriv)
The Deriv matrix is dof x 3, using column-major storage.
Definition: invariants.hpp:743
virtual double EvalW(const DenseMatrix &Jpt) const
Evaluate the strain energy density function, W = W(Jpt).
Definition: tmop.cpp:107
virtual double EvalW(const DenseMatrix &Jpt) const
Evaluate the strain energy density function, W = W(Jpt).
Definition: tmop.cpp:423
InvariantsEvaluator2D< double > ie
Definition: tmop.hpp:329
void GetValues(int i, const IntegrationRule &ir, Vector &vals, int vdim=1) const
Definition: gridfunc.cpp:445
virtual void AssembleElementVector(const FiniteElement &el, ElementTransformation &T, const Vector &elfun, Vector &elvect)
Perform the local action of the NonlinearFormIntegrator.
Definition: tmop.cpp:996
int GetVDim() const
Returns vector dimension.
Definition: fespace.hpp:336
virtual void AssembleH(const DenseMatrix &Jpt, const DenseMatrix &DS, const double weight, DenseMatrix &A) const
Evaluate the derivative of the 1st Piola-Kirchhoff stress tensor and assemble its contribution to the...
Definition: tmop.cpp:199
virtual void EvalP(const DenseMatrix &Jpt, DenseMatrix &P) const
Evaluate the 1st Piola-Kirchhoff stress tensor, P = P(Jpt).
Definition: tmop.cpp:27
FiniteElementSpace * FESpace()
Definition: gridfunc.hpp:430
int Dimension() const
Definition: mesh.hpp:713
void GetColumn(int c, Vector &col) const
Definition: densemat.cpp:2396
void Assemble_ddI1b(scalar_t w, scalar_t *A)
Definition: invariants.hpp:260
virtual void EvalP(const DenseMatrix &Jpt, DenseMatrix &P) const
Evaluate the 1st Piola-Kirchhoff stress tensor, P = P(Jpt).
Definition: tmop.cpp:191
void ComputeAvgVolume() const
Definition: tmop.cpp:768
int SizeI() const
Definition: densemat.hpp:693
void CalcInverse(const DenseMatrix &a, DenseMatrix &inva)
Definition: densemat.cpp:3240
virtual double EvalW(const DenseMatrix &Jpt) const
Evaluate the strain energy density function, W = W(Jpt).
Definition: tmop.cpp:676
double * Data() const
Returns the matrix data array.
Definition: densemat.hpp:94
void Transpose()
(*this) = (*this)^t
Definition: densemat.cpp:2485
void AddMultABt(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &ABt)
ABt += A * B^t.
Definition: densemat.cpp:3573
virtual void AssembleElementGrad(const FiniteElement &el, ElementTransformation &T, const Vector &elfun, DenseMatrix &elmat)
Assemble the local gradient matrix.
Definition: tmop.cpp:1088
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Definition: fespace.hpp:85
int GetDof() const
Returns the number of degrees of freedom in the finite element.
Definition: fe.hpp:311
void Assemble_ddI2(scalar_t w, scalar_t *A)
Definition: invariants.hpp:954
const double eps
Definition: tmop.hpp:309
const scalar_t * Get_dI1()
Definition: invariants.hpp:766
virtual void EvalP(const DenseMatrix &Jpt, DenseMatrix &P) const
Evaluate the 1st Piola-Kirchhoff stress tensor, P = P(Jpt).
Definition: tmop.cpp:430
Base class Coefficient that may optionally depend on time.
Definition: coefficient.hpp:31
InvariantsEvaluator3D< double > ie
Definition: tmop.hpp:447
const scalar_t * Get_dI1()
Definition: invariants.hpp:207
InvariantsEvaluator2D< double > ie
Definition: tmop.hpp:222
virtual double EvalW(const DenseMatrix &Jpt) const
Evaluate the strain energy density function, W = W(Jpt).
Definition: tmop.cpp:43
virtual void AssembleH(const DenseMatrix &Jpt, const DenseMatrix &DS, const double weight, DenseMatrix &A) const
Evaluate the derivative of the 1st Piola-Kirchhoff stress tensor and assemble its contribution to the...
Definition: tmop.cpp:174
virtual double EvalW(const DenseMatrix &Jpt) const
Evaluate the strain energy density function, W = W(Jpt).
Definition: tmop.cpp:303
virtual double EvalW(const DenseMatrix &Jpt) const
Evaluate the strain energy density function, W = W(Jpt).
Definition: tmop.cpp:335
const scalar_t * Get_dI1b()
Definition: invariants.hpp:211
void SetDataAndSize(double *d, int s)
Set the Vector data and size.
Definition: vector.hpp:125
virtual double EvalW(const DenseMatrix &Jpt) const
Evaluate the strain energy density function, W = W(Jpt).
Definition: tmop.cpp:473
const IntegrationRule * IntRule
Definition: nonlininteg.hpp:29
virtual double EvalW(const DenseMatrix &Jpt) const
Evaluate the strain energy density function, W = W(Jpt).
Definition: tmop.cpp:394
const scalar_t * Get_dI1b()
Definition: invariants.hpp:770
virtual double EvalW(const DenseMatrix &Jpt) const
Evaluate the strain energy density function, W = W(Jpt).
Definition: tmop.cpp:184
virtual void AssembleH(const DenseMatrix &Jpt, const DenseMatrix &DS, const double weight, DenseMatrix &A) const
Evaluate the derivative of the 1st Piola-Kirchhoff stress tensor and assemble its contribution to the...
Definition: tmop.cpp:241
virtual void AssembleH(const DenseMatrix &Jpt, const DenseMatrix &DS, const double weight, DenseMatrix &A) const
Evaluate the derivative of the 1st Piola-Kirchhoff stress tensor and assemble its contribution to the...
Definition: tmop.cpp:633
virtual void EvalP(const DenseMatrix &Jpt, DenseMatrix &P) const
Evaluate the 1st Piola-Kirchhoff stress tensor, P = P(Jpt).
Definition: tmop.cpp:402
DenseMatrix PMatI
Definition: tmop.hpp:640
InvariantsEvaluator3D< double > ie
Definition: tmop.hpp:412
virtual void EvalP(const DenseMatrix &Jpt, DenseMatrix &P) const
Evaluate the 1st Piola-Kirchhoff stress tensor, P = P(Jpt).
Definition: tmop.cpp:232
int SizeJ() const
Definition: densemat.hpp:694
const scalar_t * Get_dI2b()
Definition: invariants.hpp:778
virtual double Eval(const Vector &x, const Vector &x0, double d) const =0
Returns the limiting function, f(x, x0, d).
Class for integration point with weight.
Definition: intrules.hpp:25
InvariantsEvaluator3D< double > ie
Definition: tmop.hpp:348
void Assemble_TProd(scalar_t w, const scalar_t *X, const scalar_t *Y, scalar_t *A)
const scalar_t * Get_dI2()
Definition: invariants.hpp:774
virtual void AssembleH(const DenseMatrix &Jpt, const DenseMatrix &DS, const double weight, DenseMatrix &A) const
Evaluate the derivative of the 1st Piola-Kirchhoff stress tensor and assemble its contribution to the...
Definition: tmop.cpp:579
void GetElementTransformation(int i, IsoparametricTransformation *ElTr)
Definition: mesh.cpp:336
void ComputeNormalizationEnergies(const GridFunction &x, double &metric_energy, double &lim_energy)
Definition: tmop.cpp:1208
virtual void EvalP(const DenseMatrix &Jpt, DenseMatrix &P) const
Evaluate the 1st Piola-Kirchhoff stress tensor, P = P(Jpt).
Definition: tmop.cpp:372
virtual double GetElementEnergy(const FiniteElement &el, ElementTransformation &T, const Vector &elfun)
Computes the integral of W(Jacobian(Trt)) over a target zone.
Definition: tmop.cpp:903
virtual double EvalW(const DenseMatrix &Jpt) const
Evaluate the strain energy density function, W = W(Jpt).
Definition: tmop.cpp:21
void SetFE(const FiniteElement *FE)
Definition: eltrans.hpp:299
void Assemble_ddI1(scalar_t w, scalar_t *A)
Definition: invariants.hpp:796
virtual void Eval_d1(const Vector &x, const Vector &x0, double dist, Vector &d1) const =0
Returns the gradient of the limiting function f(x, x0, d) with respect to x.
const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement associated with i&#39;th element.
Definition: fespace.cpp:1541
virtual double EvalW(const DenseMatrix &Jpt) const
Evaluate the strain energy density function, W = W(Jpt).
Definition: tmop.cpp:646
InvariantsEvaluator2D< double > ie
Definition: tmop.hpp:155
virtual void AssembleH(const DenseMatrix &Jpt, const DenseMatrix &DS, const double weight, DenseMatrix &A) const
Evaluate the derivative of the 1st Piola-Kirchhoff stress tensor and assemble its contribution to the...
Definition: tmop.cpp:526
InvariantsEvaluator2D< double > ie
Definition: tmop.hpp:171
virtual double EvalW(const DenseMatrix &Jpt) const
Evaluate the strain energy density function, W = W(Jpt).
Definition: tmop.cpp:127
virtual void EvalP(const DenseMatrix &Jpt, DenseMatrix &P) const
Evaluate the 1st Piola-Kirchhoff stress tensor, P = P(Jpt).
Definition: tmop.cpp:266
virtual double Eval(ElementTransformation &T, const IntegrationPoint &ip)=0
Evaluate the coefficient in the element described by T at the point ip.
const scalar_t * Get_dI2()
Definition: invariants.hpp:215
virtual void AssembleH(const DenseMatrix &Jpt, const DenseMatrix &DS, const double weight, DenseMatrix &A) const
Evaluate the derivative of the 1st Piola-Kirchhoff stress tensor and assemble its contribution to the...
Definition: tmop.cpp:662
virtual double EvalW(const DenseMatrix &Jpt) const
Evaluate the strain energy density function, W = W(Jpt).
Definition: tmop.cpp:511
void MultAtB(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &AtB)
Multiply the transpose of a matrix A with a matrix B: At*B.
Definition: densemat.cpp:3725
Vector data type.
Definition: vector.hpp:48
DenseMatrix DSh
Definition: tmop.hpp:640
void GetNodes(Vector &node_coord) const
Definition: mesh.cpp:5837
DenseMatrix DS
Definition: tmop.hpp:640
InvariantsEvaluator3D< double > ie
Definition: tmop.hpp:380
const GridFunction * nodes0
Definition: tmop.hpp:621
virtual void EvalP(const DenseMatrix &Jpt, DenseMatrix &P) const
Evaluate the 1st Piola-Kirchhoff stress tensor, P = P(Jpt).
Definition: tmop.cpp:343
virtual void AssembleH(const DenseMatrix &Jpt, const DenseMatrix &DS, const double weight, DenseMatrix &A) const
Evaluate the derivative of the 1st Piola-Kirchhoff stress tensor and assemble its contribution to the...
Definition: tmop.cpp:465
virtual void EvalP(const DenseMatrix &Jpt, DenseMatrix &P) const
Evaluate the 1st Piola-Kirchhoff stress tensor, P = P(Jpt).
Definition: tmop.cpp:314
void UseExternalData(double *d, int h, int w)
Change the data array and the size of the DenseMatrix.
Definition: densemat.hpp:66
Class for parallel grid function.
Definition: pgridfunc.hpp:32
void Assemble_ddI1b(scalar_t w, scalar_t *A)
Definition: invariants.hpp:830
Base class representing target-matrix construction algorithms for mesh optimization via the target-ma...
Definition: tmop.hpp:526
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
Definition: densemat.hpp:88
virtual void EvalP(const DenseMatrix &Jpt, DenseMatrix &P) const
Evaluate the 1st Piola-Kirchhoff stress tensor, P = P(Jpt).
Definition: tmop.cpp:168
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const =0
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Rank 3 tensor (array of matrices)
Definition: densemat.hpp:656
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)
Definition: intrules.hpp:368
TMOP_LimiterFunction * lim_func
Definition: tmop.hpp:626
virtual double EvalW(const DenseMatrix &Jpt) const
Evaluate the strain energy density function, W = W(Jpt).
Definition: tmop.cpp:617
virtual void EvalP(const DenseMatrix &Jpt, DenseMatrix &P) const
Evaluate the 1st Piola-Kirchhoff stress tensor, P = P(Jpt).
Definition: tmop.cpp:601
InvariantsEvaluator3D< double > ie
Definition: tmop.hpp:364
DenseMatrix Jpt
Definition: tmop.hpp:640
void ParEnableNormalization(const ParGridFunction &x)
Definition: tmop.cpp:1198
virtual void EvalP(const DenseMatrix &Jpt, DenseMatrix &P) const
Evaluate the 1st Piola-Kirchhoff stress tensor, P = P(Jpt).
Definition: tmop.cpp:732
DenseMatrix P
Definition: tmop.hpp:640
virtual void AssembleH(const DenseMatrix &Jpt, const DenseMatrix &DS, const double weight, DenseMatrix &A) const
Evaluate the derivative of the 1st Piola-Kirchhoff stress tensor and assemble its contribution to the...
Definition: tmop.cpp:744
bool Parallel() const
Definition: tmop.hpp:555
virtual double EvalW(const DenseMatrix &Jpt) const
Evaluate the strain energy density function, W = W(Jpt).
Definition: tmop.cpp:724
virtual void AssembleH(const DenseMatrix &Jpt, const DenseMatrix &DS, const double weight, DenseMatrix &A) const
Evaluate the derivative of the 1st Piola-Kirchhoff stress tensor and assemble its contribution to the...
Definition: tmop.cpp:439
ParFiniteElementSpace * ParFESpace() const
Definition: pgridfunc.hpp:103
void SetJacobian(const scalar_t *Jac)
The Jacobian should use column-major storage.
Definition: invariants.hpp:740