26 void fem_product::init() {
28 GMM_ASSERT1(pfems[0]->target_dim() == 1,
"To be done");
29 GMM_ASSERT1(pfems[1]->target_dim() == 1,
30 "The second finite element should be scalar");
32 cvr = pfems[0]->ref_convex(cv);
33 dim_ = cvr->structure()->dim();
34 is_equiv = real_element_defined =
true;
35 is_polycomp = is_pol = is_lag = is_standard_fem =
false;
39 nm <<
"FEM_PRODUCT(" << pfems[0]->debug_name() <<
","
40 << pfems[1]->debug_name() <<
"," << cv <<
")";
41 debug_name_ = nm.str();
44 for (dal::bv_visitor i(enriched_dof1); !i.finished(); ++i) {
45 for (
size_type j = 0; j < pfems[1]->nb_dof(cv); ++j)
46 add_node(
xfem_dof(pfems[0]->dof_types()[i], xfem_index+j),
47 pfems[0]->node_of_dof(cv,i));
51 void fem_product::base_value(
const base_node &,
53 { GMM_ASSERT1(
false,
"No base values, real only element."); }
54 void fem_product::grad_base_value(
const base_node &,
56 { GMM_ASSERT1(
false,
"No base values, real only element."); }
57 void fem_product::hess_base_value(
const base_node &,
59 { GMM_ASSERT1(
false,
"No base values, real only element."); }
61 void fem_product::real_base_value(
const fem_interpolation_context &c,
62 base_tensor &t,
bool)
const {
63 bgeot::multi_index mi(2);
64 mi[1] = target_dim(); mi[0] =
short_type(nb_dof(0));
66 base_tensor::iterator it = t.begin(), itf;
68 fem_interpolation_context c0 = c;
69 std::vector<base_tensor> val_e(2);
72 c0.set_pfp(
fem_precomp(pfems[k], c0.pfp()->get_ppoint_tab(),
74 }
else { c0.set_pf(pfems[k]); }
75 c0.base_value(val_e[k]);
78 assert(target_dim() == 1);
79 for (dal::bv_visitor i(enriched_dof1); !i.finished(); ++i) {
80 itf = val_e[1].begin();
81 scalar_type e = val_e[0][i];
82 for (
size_type j = 0; j < pfems[1]->nb_dof(cv); ++j)
85 assert(it == t.end());
88 void fem_product::real_grad_base_value(
const fem_interpolation_context &c,
89 base_tensor &t,
bool)
const {
90 bgeot::multi_index mi(3);
91 mi[2] =
short_type(c.N()); mi[1] = target_dim();
94 base_tensor::iterator it = t.begin();
96 fem_interpolation_context c0 = c;
97 std::vector<base_tensor> grad_e(2), val_e(2);
100 c0.set_pfp(
fem_precomp(pfems[k], c0.pfp()->get_ppoint_tab(),
102 }
else { c0.set_pf(pfems[k]); }
103 c0.grad_base_value(grad_e[k]);
104 c0.base_value(val_e[k]);
107 assert(target_dim() == 1);
108 for (dim_type k = 0; k < c.N() ; ++k) {
109 for (dal::bv_visitor i(enriched_dof1); !i.finished(); ++i) {
110 size_type posg0 = k * pfems[0]->nb_dof(cv);
111 size_type posg1 = k * pfems[1]->nb_dof(cv);
112 for (
size_type j = 0; j < pfems[1]->nb_dof(cv); ++j)
113 *it++ = grad_e[0][i + posg0] * val_e[1][j]
114 + grad_e[1][j + posg1] * val_e[0][i];
117 assert(it == t.end());
120 void fem_product::real_hess_base_value(
const fem_interpolation_context &c,
121 base_tensor &t,
bool)
const {
122 t.adjust_sizes(nb_dof(0), target_dim(), gmm::sqr(c.N()));
123 base_tensor::iterator it = t.begin();
125 fem_interpolation_context c0 = c;
126 std::vector<base_tensor> hess_e(2), grad_e(2), val_e(2);
129 c0.set_pfp(
fem_precomp(pfems[k], c0.pfp()->get_ppoint_tab(),
131 }
else { c0.set_pf(pfems[k]); }
132 c0.hess_base_value(hess_e[k]);
133 c0.grad_base_value(grad_e[k]);
134 c0.base_value(val_e[k]);
137 assert(target_dim() == 1);
138 for (dim_type k0 = 0; k0 < c.N(); ++k0) {
139 for (dim_type k1 = 0; k1 < c.N() ; ++k1) {
140 for (dal::bv_visitor i(enriched_dof1); !i.finished(); ++i) {
141 size_type posh0 = (k0*c.N()+k1) * pfems[0]->nb_dof(cv);
142 size_type posh1 = (k0*c.N()+k1) * pfems[1]->nb_dof(cv);
143 size_type posg00 = k0 * pfems[0]->nb_dof(cv);
144 size_type posg01 = k1 * pfems[0]->nb_dof(cv);
145 size_type posg10 = k0 * pfems[1]->nb_dof(cv);
146 size_type posg11 = k1 * pfems[1]->nb_dof(cv);
147 for (
size_type j = 0; j < pfems[1]->nb_dof(cv); ++j) {
148 *it++ = hess_e[0][i + posh0] * val_e[1][j] +
149 hess_e[1][j + posh1] * val_e[0][i] +
150 grad_e[0][i + posg00] * grad_e[1][j + posg11] +
151 grad_e[0][i + posg01] * grad_e[1][j + posg10];
156 assert(it == t.end());
159 void mesh_fem_product::clear_build_methods() {
160 for (
size_type i = 0; i < build_methods.size(); ++i)
162 build_methods.clear();
164 void mesh_fem_product::clear() {
166 clear_build_methods();
170 DAL_SIMPLE_KEY(special_mflproduct_key,
pfem);
172 void mesh_fem_product::adapt() {
176 GMM_ASSERT1(!mf1.is_reduced() && !mf2.is_reduced(),
177 "Sorry, mesh_fem_product not defined for reduced mesh_fems");
179 for (dal::bv_visitor cv(linked_mesh().convex_index()); !cv.finished();
181 dal::bit_vector local_enriched_dof;
182 for (
size_type i = 0; i < mf1.nb_basic_dof_of_element(cv); ++i)
183 if (enriched_dof.is_in(mf1.ind_basic_dof_of_element(cv)[i]))
184 local_enriched_dof.add(i);
185 if (local_enriched_dof.card() > 0) {
186 pfem pf = std::make_shared<fem_product>
187 (mf1.fem_of_element(cv), mf2.fem_of_element(cv), cv,
188 xfem_index, local_enriched_dof);
189 dal::pstatic_stored_object_key
190 pk = std::make_shared<special_mflproduct_key>(pf);
192 build_methods.push_back(pf);
193 set_finite_element(cv, pf);
196 is_adapted =
true; touch();
A kind of product of two mesh_fems. Specific for Xfem enrichment.
void clear(L &l)
clear (fill with zeros) a vector or matrix.
pdof_description xfem_dof(pdof_description p, size_type ind)
Description of a special dof for Xfem.
std::shared_ptr< const getfem::virtual_fem > pfem
type of pointer on a fem description
pfem_precomp fem_precomp(pfem pf, bgeot::pstored_point_tab pspt, dal::pstatic_stored_object dep)
Handles precomputations for FEM.
gmm::uint16_type short_type
used as the common short type integer in the library
size_t size_type
used as the common size type in the library
void add_stored_object(pstatic_stored_object_key k, pstatic_stored_object o, permanence perm)
Add an object with two optional dependencies.
void del_stored_object(const pstatic_stored_object &o, bool ignore_unstored)
Delete an object and the object which depend on it.
GEneric Tool for Finite Element Methods.