[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Getfem-commits] (no subject)
From: |
Yves Renard |
Subject: |
[Getfem-commits] (no subject) |
Date: |
Fri, 13 Mar 2020 12:09:59 -0400 (EDT) |
branch: master
commit 08e00aa775ed6e25c6412202d34971b1ee270a65
Author: Yves Renard <address@hidden>
AuthorDate: Fri Mar 13 17:09:33 2020 +0100
minor fix
---
interface/src/#gf_model_set.cc# | 4038 ---------------------------------------
interface/src/.#gf_model_set.cc | 1 -
interface/src/gf_model_set.cc | 2 +-
3 files changed, 1 insertion(+), 4040 deletions(-)
diff --git a/interface/src/#gf_model_set.cc# b/interface/src/#gf_model_set.cc#
deleted file mode 100644
index 535f635..0000000
--- a/interface/src/#gf_model_set.cc#
+++ /dev/null
@@ -1,4038 +0,0 @@
-/*===========================================================================
-
- Copyright (C) 2009-2020 Yves Renard.
-
- This file is a part of GetFEM++
-
- GetFEM++ is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published
- by the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version along with the GCC Runtime Library
- Exception either version 3.1 or (at your option) any later version.
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License and GCC Runtime Library Exception for more details.
- You should have received a copy of the GNU Lesser General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-
-===========================================================================*/
-
-/**\file gf_model_set.cc
- \brief getfemint_model setter.
-*/
-
-#include <getfem/getfem_im_data.h>
-#include <getfem/getfem_contact_and_friction_nodal.h>
-#include <getfem/getfem_contact_and_friction_integral.h>
-#include <getfem/getfem_contact_and_friction_large_sliding.h>
-#include <getfem/getfem_nonlinear_elasticity.h>
-#include <getfem/getfem_plasticity.h>
-#include <getfem/getfem_HHO.h>
-#include <getfem/getfem_fourth_order.h>
-#include <getfem/getfem_linearized_plates.h>
-#include <getfemint_misc.h>
-#include <getfemint_workspace.h>
-#include <getfemint_gsparse.h>
-
-using namespace getfemint;
-
-
-/*@GFDOC
- Modifies a model object.
-@*/
-
-
-// Object for the declaration of a new sub-command.
-
-struct sub_gf_md_set : virtual public dal::static_stored_object {
- int arg_in_min, arg_in_max, arg_out_min, arg_out_max;
- virtual void run(getfemint::mexargs_in& in,
- getfemint::mexargs_out& out,
- getfem::model *md) = 0;
-};
-
-typedef std::shared_ptr<sub_gf_md_set> psub_command;
-
-typedef std::map<size_type, size_type> elt_corr_cont;
-
-// Function to avoid warning in macro with unused arguments.
-template <typename T> static inline void dummy_func(T &) {}
-
-#define sub_command(name, arginmin, arginmax, argoutmin, argoutmax, code) { \
- struct subc : public sub_gf_md_set { \
- virtual void run(getfemint::mexargs_in& in, \
- getfemint::mexargs_out& out, \
- getfem::model *md) \
- { dummy_func(in); dummy_func(out); code } \
- }; \
- psub_command psubc = std::make_shared<subc>(); \
- psubc->arg_in_min = arginmin; psubc->arg_in_max = arginmax; \
- psubc->arg_out_min = argoutmin; psubc->arg_out_max = argoutmax; \
- subc_tab[cmd_normalize(name)] = psubc; \
- }
-
-static void filter_lawname(std::string &lawname) {
- for (auto &c : lawname)
- { if (c == ' ') c = '_'; if (c >= 'A' && c <= 'Z') c = char(c+'a'-'A'); }
-}
-
-void gf_model_set(getfemint::mexargs_in& m_in,
- getfemint::mexargs_out& m_out) {
- typedef std::map<std::string, psub_command > SUBC_TAB;
- static SUBC_TAB subc_tab;
-
- if (subc_tab.size() == 0) {
-
- /*@SET ('clear')
- Clear the model.@*/
- sub_command
- ("clear", 0, 0, 0, 1,
- md->clear();
- );
-
-
- /*@SET ('add fem variable', @str name, @tmf mf)
- Add a variable to the model linked to a @tmf. `name` is the variable
- name. @*/
- sub_command
- ("add fem variable", 2, 2, 0, 0,
- std::string name = in.pop().to_string();
- getfem::mesh_fem *mf = to_meshfem_object(in.pop());
- md->add_fem_variable(name, *mf);
- workspace().set_dependence(md, mf);
- );
-
- /*@SET ('add filtered fem variable', @str name, @tmf mf, @int region)
- Add a variable to the model linked to a @tmf. The variable is filtered
- in the sense that only the dof on the region are considered.
- `name` is the variable name. @*/
- sub_command
- ("add filtered fem variable", 3, 3, 0, 0,
- std::string name = in.pop().to_string();
- getfem::mesh_fem *mf = to_meshfem_object(in.pop());
- size_type region = in.pop().to_integer();
- md->add_filtered_fem_variable(name, *mf, region);
- workspace().set_dependence(md, mf);
- );
-
-
- /*@SET ('add variable', @str name, sizes)
- Add a variable to the model of constant sizes. `sizes` is either a
- integer (for a scalar or vector variable) or a vector of dimensions
- for a tensor variable. `name` is the variable name. @*/
- sub_command
- ("add variable", 2, 2, 0, 0,
- std::string name = in.pop().to_string();
- mexarg_in argin = in.pop();
- bgeot::multi_index mi(1);
- if (argin.is_integer()) {
- mi[0] = argin.to_integer();
- } else {
- iarray v = argin.to_iarray();
- mi.resize(v.size());
- for (size_type i = 0; i < v.size(); ++i) mi[i] = v[i];
- }
- md->add_fixed_size_variable(name, mi);
- );
-
- /*@SET ('delete variable', @str name)
- Delete a variable or a data from the model. @*/
- sub_command
- ("delete variable", 1, 1, 0, 0,
- std::string name = in.pop().to_string();
- md->delete_variable(name);
- );
-
-
- /*@SET ('resize variable', @str name, sizes)
- Resize a constant size variable of the model. `sizes` is either a
- integer (for a scalar or vector variable) or a vector of dimensions
- for a tensor variable. `name` is the variable name. @*/
- sub_command
- ("resize variable", 2, 2, 0, 0,
- std::string name = in.pop().to_string();
- mexarg_in argin = in.pop();
- bgeot::multi_index mi(1);
- if (argin.is_integer()) {
- mi[0] = argin.to_integer();
- } else {
- iarray v = argin.to_iarray();
- mi.resize(v.size());
- for (size_type i = 0; i < v.size(); ++i) mi[i] = v[i];
- }
- md->resize_fixed_size_variable(name, mi);
- );
-
-
- /*@SET ('add multiplier', @str name, @tmf mf, @str primalname[, @tmim mim,
@int region])
- Add a particular variable linked to a fem being a multiplier with
- respect to a primal variable. The dof will be filtered with the
- ``gmm::range_basis`` function applied on the terms of the model
- which link the multiplier and the primal variable. This in order to
- retain only linearly independent constraints on the primal variable.
- Optimized for boundary multipliers. @*/
- sub_command
- ("add multiplier", 3, 5, 0, 0,
- std::string name = in.pop().to_string();
- getfem::mesh_fem *mf = to_meshfem_object(in.pop());
- std::string primalname = in.pop().to_string();
-
- getfem::mesh_im *mim = 0;
- size_type region = size_type(-1);
- if (in.remaining()) {
- mexarg_in argin = in.pop();
- mim = to_meshim_object(argin);
- region = in.pop().to_integer();
- }
- if (mim)
- md->add_multiplier(name, *mf, primalname, *mim, region);
- else
- md->add_multiplier(name, *mf, primalname);
- workspace().set_dependence(md, mf);
- );
-
-
- /*@SET ('add im data', @str name, @tmimd mimd)
- Add a data set to the model linked to a @tmimd. `name` is the data
- name. @*/
- sub_command
- ("add im data", 2, 2, 0, 0,
- std::string name = in.pop().to_string();
- getfem::im_data *mimd = to_meshimdata_object(in.pop());
- md->add_im_data(name, *mimd);
- workspace().set_dependence(md, mimd);
- );
-
-
- /*@SET ('add fem data', @str name, @tmf mf[, sizes])
- Add a data to the model linked to a @tmf. `name` is the data name,
- `sizes` an optional parameter which is either an
- integer or a vector of suplementary dimensions with respect to `mf`. @*/
- sub_command
- ("add fem data", 2, 3, 0, 0,
- std::string name = in.pop().to_string();
- getfem::mesh_fem *mf = to_meshfem_object(in.pop());
- bgeot::multi_index mi(1); mi[0] = 1;
- if (in.remaining()) {
- mexarg_in argin = in.pop();
- if (argin.is_integer()) {
- mi[0] = argin.to_integer();
- } else {
- iarray v = argin.to_iarray();
- mi.resize(v.size());
- for (size_type i = 0; i < v.size(); ++i) mi[i] = v[i];
- }
- }
- md->add_fem_data(name, *mf, mi);
- workspace().set_dependence(md, mf);
- );
-
-
- /*@SET ('add initialized fem data', @str name, @tmf mf, @vec V[, sizes])
- Add a data to the model linked to a @tmf. `name` is the data name.
- The data is initiakized with `V`. The data can be a scalar or vector
- field. `sizes` an optional parameter which is either an
- integer or a vector of suplementary dimensions with respect to `mf`.@*/
- sub_command
- ("add initialized fem data", 3, 4, 0, 0,
- std::string name = in.pop().to_string();
- getfem::mesh_fem *mf = to_meshfem_object(in.pop());
- if (!md->is_complex()) {
- darray st = in.pop().to_darray();
- std::vector<double> V(st.begin(), st.end());
- bgeot::multi_index mi(1);
- mi[0] = gmm::vect_size(V) / mf->nb_dof();
- if (in.remaining()) {
- mexarg_in argin = in.pop();
- if (argin.is_integer()) {
- mi[0] = argin.to_integer();
- } else {
- iarray v = argin.to_iarray();
- mi.resize(v.size());
- for (size_type i = 0; i < v.size(); ++i) mi[i] = v[i];
- }
- }
- md->add_initialized_fem_data(name, *mf, V, mi);
- } else {
- carray st = in.pop().to_carray();
- std::vector<std::complex<double> > V(st.begin(), st.end());
- bgeot::multi_index mi(1);
- mi[0] = gmm::vect_size(V) / mf->nb_dof();
- if (in.remaining()) {
- mexarg_in argin = in.pop();
- if (argin.is_integer()) {
- mi[0] = argin.to_integer();
- } else {
- iarray v = argin.to_iarray();
- mi.resize(v.size());
- for (size_type i = 0; i < v.size(); ++i) mi[i] = v[i];
- }
- }
- md->add_initialized_fem_data(name, *mf, V, mi);
- }
- workspace().set_dependence(md, mf);
- );
-
-
- /*@SET ('add data', @str name, @int size)
- Add a fixed size data to the model. `sizes` is either a
- integer (for a scalar or vector data) or a vector of dimensions
- for a tensor data. `name` is the data name. @*/
- sub_command
- ("add data", 2, 2, 0, 0,
- std::string name = in.pop().to_string();
- mexarg_in argin = in.pop();
- bgeot::multi_index mi(1);
- if (argin.is_integer()) {
- mi[0] = argin.to_integer();
- } else {
- iarray v = argin.to_iarray();
- mi.resize(v.size());
- for (size_type i = 0; i < v.size(); ++i) mi[i] = v[i];
- }
- md->add_fixed_size_data(name, mi);
- );
-
- /*@SET ('add macro', @str name, @str expr)
- Define a new macro for the high generic assembly language.
- The name include the parameters. For instance name='sp(a,b)', expr='a.b'
- is a valid definition. Macro without parameter can also be defined.
- For instance name='x1', expr='X[1]' is valid. The form name='grad(u)',
- expr='Grad_u' is also allowed but in that case, the parameter 'u' will
- only be allowed to be a variable name when using the macro. Note that
- macros can be directly defined inside the assembly strings with the
- keyword 'Def'.
- @*/
- sub_command
- ("add macro", 2, 2, 0, 0,
- std::string name = in.pop().to_string();
- std::string expr = in.pop().to_string();
- md->add_macro(name, expr);
- );
-
- /*@SET ('del macro', @str name)
- Delete a previously defined macro for the high generic assembly language.
- @*/
- sub_command
- ("del macro", 1, 1, 0, 0,
- std::string name = in.pop().to_string();
- md->del_macro(name);
- );
-
- /*@SET ('add initialized data', @str name, @vec V[, sizes])
- Add an initialized fixed size data to the model. `sizes` an
- optional parameter which is either an
- integer or a vector dimensions that describes the format of the
- data. By default, the data is considered to b a vector field.
- `name` is the data name and `V` is the value of the data.@*/
- sub_command
- ("add initialized data", 2, 3, 0, 0,
- std::string name = in.pop().to_string();
- if (!md->is_complex()) {
- darray st = in.pop().to_darray();
- std::vector<double> V(st.begin(), st.end());
- bgeot::multi_index mi(1);
- mi[0] = gmm::vect_size(V);
- if (in.remaining()) {
- mexarg_in argin = in.pop();
- if (argin.is_integer()) {
- mi[0] = argin.to_integer();
- } else {
- iarray v = argin.to_iarray();
- mi.resize(v.size());
- for (size_type i = 0; i < v.size(); ++i) mi[i] = v[i];
- }
- }
- md->add_initialized_fixed_size_data(name, V, mi);
- } else {
- carray st = in.pop().to_carray();
- std::vector<std::complex<double> > V(st.begin(), st.end());
- bgeot::multi_index mi(1);
- mi[0] = gmm::vect_size(V);
- if (in.remaining()) {
- mexarg_in argin = in.pop();
- if (argin.is_integer()) {
- mi[0] = argin.to_integer();
- } else {
- iarray v = argin.to_iarray();
- mi.resize(v.size());
- for (size_type i = 0; i < v.size(); ++i) mi[i] = v[i];
- }
- }
- md->add_initialized_fixed_size_data(name, V, mi);
- }
- );
-
-
- /*@SET ('variable', @str name, @vec V)
- Set the value of a variable or data. `name` is the data name.@*/
- sub_command
- ("variable", 2, 2, 0, 0,
- std::string name = in.pop().to_string();
- if (!md->is_complex()) {
- darray st = in.pop().to_darray();
- GMM_ASSERT1(st.size()==md->real_variable(name).size(),
- "Bad size in assignment");
- md->set_real_variable(name).assign(st.begin(),st.end());
- } else {
- carray st = in.pop().to_carray();
- GMM_ASSERT1(st.size() == md->complex_variable(name).size(),
- "Bad size in assignment");
- md->set_complex_variable(name).assign(st.begin(),
- st.end());
- }
- );
-
-
- /*@SET ('to variables', @vec V)
- Set the value of the variables of the model with the vector `V`.
- Typically, the vector `V` results of the solve of the tangent
- linear system (useful to solve your problem with you own solver).@*/
- sub_command
- ("to variables", 1, 1, 0, 0,
- if (!md->is_complex()) {
- darray st = in.pop().to_darray(-1);
- std::vector<double> V;
- V.assign(st.begin(), st.end());
- md->to_variables(V);
- } else {
- carray st = in.pop().to_carray(-1);
- std::vector<std::complex<double> > V;
- V.assign(st.begin(), st.end());
- md->to_variables(V);
- }
- );
-
- /*@SET ('delete brick', @int ind_brick)
- Delete a variable or a data from the model. @*/
- sub_command
- ("delete brick", 1, 1, 0, 0,
- size_type ib = in.pop().to_integer() - config::base_index();
- md->delete_brick(ib);
- );
-
- /*@SET ('define variable group', @str name[, @str varname, ...])
- Defines a group of variables for the interpolation (mainly for the
- raytracing interpolation transformation.@*/
- sub_command
- ("define variable group", 1, 1000, 0, 0,
- std::string name = in.pop().to_string();
- std::vector<std::string> nl;
- while (in.remaining()) nl.push_back(in.pop().to_string());
- md->define_variable_group(name, nl);
- );
-
- /*@SET ('add elementary rotated RT0 projection', @str transname)
- Add the elementary transformation corresponding to the projection
- on rotated RT0 element for two-dimensional elements to the model.
- The name is the name given to the elementary transformation. @*/
- sub_command
- ("add elementary rotated RT0 projection", 1, 1, 0, 0,
- std::string transname = in.pop().to_string();
- add_2D_rotated_RT0_projection(*md, transname);
- );
-
- /*@SET ('add elementary P0 projection', @str transname)
- Add the elementary transformation corresponding to the projection
- P0 element.
- The name is the name given to the elementary transformation. @*/
- sub_command
- ("add P0 projection", 1, 1, 0, 0,
- std::string transname = in.pop().to_string();
- add_P0_projection(*md, transname);
- );
-
- /*@SET ('add HHO reconstructed gradient', @str transname)
- Add to the model the elementary transformation corresponding to the
- reconstruction of a gradient for HHO methods.
- The name is the name given to the elementary transformation. @*/
- sub_command
- ("add HHO reconstructed gradient", 1, 1, 0, 0,
- std::string transname = in.pop().to_string();
- add_HHO_reconstructed_gradient(*md, transname);
- );
-
- /*@SET ('add HHO reconstructed symmetrized gradient', @str transname)
- Add to the model the elementary transformation corresponding to the
- reconstruction of a symmetrized gradient for HHO methods.
- The name is the name given to the elementary transformation. @*/
- sub_command
- ("add HHO reconstructed symmetrized gradient", 1, 1, 0, 0,
- std::string transname = in.pop().to_string();
- add_HHO_reconstructed_symmetrized_gradient(*md, transname);
- );
-
- /*@SET ('add HHO reconstructed value', @str transname)
- Add to the model the elementary transformation corresponding to the
- reconstruction of the variable for HHO methods.
- The name is the name given to the elementary transformation. @*/
- sub_command
- ("add HHO reconstructed value", 1, 1, 0, 0,
- std::string transname = in.pop().to_string();
- add_HHO_reconstructed_value(*md, transname);
- );
-
- /*@SET ('add HHO reconstructed symmetrized value', @str transname)
- Add to the model the elementary transformation corresponding to the
- reconstruction of the variable for HHO methods using a symmetrized
- gradient.
- The name is the name given to the elementary transformation. @*/
- sub_command
- ("add HHO reconstructed symmetrized value", 1, 1, 0, 0,
- std::string transname = in.pop().to_string();
- add_HHO_reconstructed_symmetrized_value(*md, transname);
- );
-
- /*@SET ('add HHO stabilization', @str transname)
- Add to the model the elementary transformation corresponding to the
- HHO stabilization operator.
- The name is the name given to the elementary transformation. @*/
- sub_command
- ("add HHO stabilization", 1, 1, 0, 0,
- std::string transname = in.pop().to_string();
- add_HHO_stabilization(*md, transname);
- );
-
- /*@SET ('add HHO symmetrized stabilization', @str transname)
- Add to the model the elementary transformation corresponding to the
- HHO stabilization operator using a symmetrized gradient.
- The name is the name given to the elementary transformation. @*/
- sub_command
- ("add HHO symmetrized stabilization", 1, 1, 0, 0,
- std::string transname = in.pop().to_string();
- add_HHO_symmetrized_stabilization(*md, transname);
- );
-
-
- /*@SET ('add interpolate transformation from expression', @str transname,
@tmesh source_mesh, @tmesh target_mesh, @str expr)
- Add a transformation to the model from mesh `source_mesh` to mesh
- `target_mesh` given by the expression `expr` which corresponds to a
- high-level generic assembly expression which may contains some
- variable of the model. CAUTION: the derivative of the
- transformation with used variable is taken into account in the
- computation of the tangen system. However, order two derivative is not
- implemented, so such tranformation is not allowed in the definition
- of a potential. @*/
- sub_command
- ("add interpolate transformation from expression", 4, 4, 0, 0,
- std::string transname = in.pop().to_string();
- getfem::mesh *sm = extract_mesh_object(in.pop());
- getfem::mesh *tm = extract_mesh_object(in.pop());
- std::string expr = in.pop().to_string();
- add_interpolate_transformation_from_expression(*md, transname, *sm,
- *tm, expr);
- );
-
- /*@SET ('add element extrapolation transformation', @str transname, @tmesh
source_mesh, @mat elt_corr)
- Add a special interpolation transformation which represents the identity
- transformation but allows to evaluate the expression on another element
- than the current element by polynomial extrapolation. It is used for
- stabilization term in fictitious domain applications. the array elt_cor
- should be a two entry array whose first line contains the elements
- concerned by the transformation and the second line the respective
- elements on which the extrapolation has to be made. If an element
- is not listed in elt_cor the evaluation is just made on the current
- element. @*/
- sub_command
- ("add element extrapolation transformation", 3, 3, 0, 0,
- std::string transname = in.pop().to_string();
- getfem::mesh *sm = extract_mesh_object(in.pop());
- iarray v = in.pop().to_iarray();
- if (v.getm() != 2 || v.getp() != 1 || v.getq() != 1)
- THROW_BADARG("Invalid format for the convex correspondence
list");
- elt_corr_cont elt_corr;
- for (size_type j=0; j < v.getn(); j++)
- elt_corr[v(0,j)-config::base_index()] = v(1,j)-config::base_index();
- getfem::add_element_extrapolation_transformation(*md, transname, *sm,
- elt_corr);
- );
-
- /*@SET ('add standard secondary domain', @str name, @tmim mim, @int region
= -1)
- Add a secondary domain to the model which can be used in a weak-form
language expression for integration on the product of two domains. `name` is
the name
- of the secondary domain, `mim` is an integration method on this domain
- and `region` the region on which the integration is to be performed. @*/
- sub_command
- ("add standard secondary domain", 3, 3, 0, 0,
- std::string name = in.pop().to_string();
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- size_type region = size_type(-1);
- if (in.remaining()) region = in.pop().to_integer();
- add_standard_secondary_domain(*md, name, *mim, region);
- );
-
-
- /*@SET ('set element extrapolation correspondence', @str transname, @mat
elt_corr)
- Change the correspondence map of an element extrapolation interpolate
- transformation. @*/
- sub_command
- ("set element extrapolation correspondence", 2, 2, 0, 0,
- std::string transname = in.pop().to_string();
- iarray v = in.pop().to_iarray();
- if (v.getm() != 2 || v.getp() != 1 || v.getq() != 1)
- THROW_BADARG("Invalid format for the convex correspondence
list");
- elt_corr_cont elt_corr;
- for (size_type j=0; j < v.getn(); j++)
- elt_corr[v(0,j)-config::base_index()] = v(1,j)-config::base_index();
- getfem::set_element_extrapolation_correspondence(*md, transname,
- elt_corr);
- );
-
- /*@SET ('add raytracing transformation', @str transname, @scalar
release_distance)
- Add a raytracing interpolate transformation called `transname` to a model
- to be used by the generic assembly bricks.
- CAUTION: For the moment, the derivative of the
- transformation is not taken into account in the model solve. @*/
- sub_command
- ("add raytracing transformation", 2, 2, 0, 0,
- std::string transname = in.pop().to_string();
- scalar_type d = in.pop().to_scalar();
- add_raytracing_transformation(*md, transname, d);
- );
-
- /*@SET ('add master contact boundary to raytracing transformation', @str
transname, @tmesh m, @str dispname, @int region)
- Add a master contact boundary with corresponding displacement variable
- `dispname` on a specific boundary `region` to an existing raytracing
- interpolate transformation called `transname`. @*/
- sub_command
- ("add master contact boundary to raytracing transformation", 4, 4, 0, 0,
- std::string transname = in.pop().to_string();
- getfem::mesh *sm = extract_mesh_object(in.pop());
- std::string dispname = in.pop().to_string();
- size_type region = in.pop().to_integer();
- add_master_contact_boundary_to_raytracing_transformation
- (*md, transname, *sm, dispname, region);
- );
-
- /*@SET ('add slave contact boundary to raytracing transformation', @str
transname, @tmesh m, @str dispname, @int region)
- Add a slave contact boundary with corresponding displacement variable
- `dispname` on a specific boundary `region` to an existing raytracing
- interpolate transformation called `transname`. @*/
- sub_command
- ("add slave contact boundary to raytracing transformation", 4, 4, 0, 0,
- std::string transname = in.pop().to_string();
- getfem::mesh *sm = extract_mesh_object(in.pop());
- std::string dispname = in.pop().to_string();
- size_type region = in.pop().to_integer();
- add_slave_contact_boundary_to_raytracing_transformation
- (*md, transname, *sm, dispname, region);
- );
-
- /*@SET ('add rigid obstacle to raytracing transformation', @str transname,
@str expr, @int N)
- Add a rigid obstacle whose geometry corresponds to the zero level-set
- of the high-level generic assembly expression `expr`
- to an existing raytracing interpolate transformation called `transname`.
- @*/
- sub_command
- ("add rigid obstacle to raytracing transformation", 3, 3, 0, 0,
- std::string transname = in.pop().to_string();
- std::string expr = in.pop().to_string();
- size_type N = in.pop().to_integer();
- add_rigid_obstacle_to_raytracing_transformation
- (*md, transname, expr, N);
- );
-/*@SET ('add projection transformation', @str transname, @scalar
release_distance)
- Add a projection interpolate transformation called `transname` to a model
- to be used by the generic assembly bricks.
- CAUTION: For the moment, the derivative of the
- transformation is not taken into account in the model solve. @*/
- sub_command
- ("add projection transformation", 2, 2, 0, 0,
- std::string transname = in.pop().to_string();
- scalar_type d = in.pop().to_scalar();
- add_projection_transformation(*md, transname, d);
- );
-
- /*@SET ('add master contact boundary to projection transformation', @str
transname, @tmesh m, @str dispname, @int region)
- Add a master contact boundary with corresponding displacement variable
- `dispname` on a specific boundary `region` to an existing projection
- interpolate transformation called `transname`. @*/
- sub_command
- ("add master contact boundary to projection transformation", 4, 4, 0, 0,
- std::string transname = in.pop().to_string();
- getfem::mesh *sm = extract_mesh_object(in.pop());
- std::string dispname = in.pop().to_string();
- size_type region = in.pop().to_integer();
- add_master_contact_boundary_to_projection_transformation
- (*md, transname, *sm, dispname, region);
- );
-
- /*@SET ('add slave contact boundary to projection transformation', @str
transname, @tmesh m, @str dispname, @int region)
- Add a slave contact boundary with corresponding displacement variable
- `dispname` on a specific boundary `region` to an existing projection
- interpolate transformation called `transname`. @*/
- sub_command
- ("add slave contact boundary to projection transformation", 4, 4, 0, 0,
- std::string transname = in.pop().to_string();
- getfem::mesh *sm = extract_mesh_object(in.pop());
- std::string dispname = in.pop().to_string();
- size_type region = in.pop().to_integer();
- add_slave_contact_boundary_to_projection_transformation
- (*md, transname, *sm, dispname, region);
- );
-
- /*@SET ('add rigid obstacle to projection transformation', @str transname,
@str expr, @int N)
- Add a rigid obstacle whose geometry corresponds to the zero level-set
- of the high-level generic assembly expression `expr`
- to an existing projection interpolate transformation called `transname`.
- @*/
- sub_command
- ("add rigid obstacle to projection transformation", 3, 3, 0, 0,
- std::string transname = in.pop().to_string();
- std::string expr = in.pop().to_string();
- size_type N = in.pop().to_integer();
- add_rigid_obstacle_to_projection_transformation
- (*md, transname, expr, N);
- );
-
- /*@SET ind = ('add linear term', @tmim mim, @str expression[, @int
region[, @int is_symmetric[, @int is_coercive]]])
- Adds a matrix term given by the assembly string `expr` which will
- be assembled in region `region` and with the integration method `mim`.
- Only the matrix term will be taken into account, assuming that it is
- linear.
- The advantage of declaring a term linear instead of nonlinear is that
- it will be assembled only once and no assembly is necessary for the
- residual.
- Take care that if the expression contains some variables and if the
- expression is a potential or of first order (i.e. describe the weak
- form, not the derivative of the weak form), the expression will be
- derivated with respect to all variables.
- You can specify if the term is symmetric, coercive or not.
- If you are not sure, the better is to declare the term not symmetric
- and not coercive. But some solvers (conjugate gradient for instance)
- are not allowed for non-coercive problems.
- `brickname` is an optional name for the brick.@*/
- sub_command
- ("add linear term", 2, 5, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string expr = in.pop().to_string();
- size_type region = size_type(-1);
- if (in.remaining()) region = in.pop().to_integer();
- int is_symmetric = 0;
- if (in.remaining()) is_symmetric = in.pop().to_integer();
- int is_coercive = 0;
- if (in.remaining()) is_coercive = in.pop().to_integer();
-
- size_type ind = getfem::add_linear_term
- (*md, *mim, expr, region, is_symmetric,
- is_coercive) + config::base_index();
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
- /*@SET ind = ('add linear twodomain term', @tmim mim, @str expression,
@int region, @str secondary_domain[, @int is_symmetric[, @int is_coercive]])
- Adds a linear term given by a weak form language expression like
- MODEL:SET('add linear term') but for an integration on a direct
- product of two domains, a first specfied by ``mim`` and ``region``
- and a second one by ``secondary_domain`` which has to be declared
- first into the model.@*/
- sub_command
- ("add linear twodomain term", 4, 6, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string expr = in.pop().to_string();
- size_type region = in.pop().to_integer();
- std::string secdom = in.pop().to_string();
- int is_symmetric = 0;
- if (in.remaining()) is_symmetric = in.pop().to_integer();
- int is_coercive = 0;
- if (in.remaining()) is_coercive = in.pop().to_integer();
-
- size_type ind = getfem::add_linear_twodomain_term
- (*md, *mim, expr, region, secdom, is_symmetric,
- is_coercive) + config::base_index();
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
- /*@SET ind = ('add linear generic assembly brick', @tmim mim, @str
expression[, @int region[, @int is_symmetric[, @int is_coercive]]])
- Deprecated. Use MODEL:SET('add linear term') instead. @*/
- sub_command
- ("add linear generic assembly brick", 2, 5, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string expr = in.pop().to_string();
- size_type region = size_type(-1);
- if (in.remaining()) region = in.pop().to_integer();
- int is_symmetric = 0;
- if (in.remaining()) is_symmetric = in.pop().to_integer();
- int is_coercive = 0;
- if (in.remaining()) is_coercive = in.pop().to_integer();
-
- size_type ind
- = getfem::add_linear_term
- (*md, *mim, expr, region, is_symmetric,
- is_coercive) + config::base_index();
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
- /*@SET ind = ('add nonlinear term', @tmim mim, @str expression[, @int
region[, @int is_symmetric[, @int is_coercive]]])
- Adds a nonlinear term given by the assembly string `expr` which will
- be assembled in region `region` and with the integration method `mim`.
- The expression can describe a potential or a weak form. Second order
- terms (i.e. containing second order test functions, Test2) are not
- allowed.
- You can specify if the term is symmetric, coercive or not.
- If you are not sure, the better is to declare the term not symmetric
- and not coercive. But some solvers (conjugate gradient for instance)
- are not allowed for non-coercive problems.
- `brickname` is an optional name for the brick.@*/
- sub_command
- ("add nonlinear term", 2, 5, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string expr = in.pop().to_string();
- size_type region = size_type(-1);
- if (in.remaining()) region = in.pop().to_integer();
- int is_symmetric = 0;
- if (in.remaining()) is_symmetric = in.pop().to_integer();
- int is_coercive = 0;
- if (in.remaining()) is_coercive = in.pop().to_integer();
-
- size_type ind
- = getfem::add_nonlinear_term
- (*md, *mim, expr, region, is_symmetric,
- is_coercive) + config::base_index();
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
- /*@SET ind = ('add nonlinear twodomain term', @tmim mim, @str expression,
@int region, @str secondary_domain[, @int is_symmetric[, @int is_coercive]])
- Adds a nonlinear term given by a weak form language expression like
- MODEL:SET('add nonlinear term') but for an integration on a direct
- product of two domains, a first specfied by ``mim`` and ``region``
- and a second one by ``secondary_domain`` which has to be declared
- first into the model.@*/
- sub_command
- ("add nonlinear twodomain term", 4, 6, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string expr = in.pop().to_string();
- size_type region = in.pop().to_integer();
- std::string secdom = in.pop().to_string();
- int is_symmetric = 0;
- if (in.remaining()) is_symmetric = in.pop().to_integer();
- int is_coercive = 0;
- if (in.remaining()) is_coercive = in.pop().to_integer();
-
- size_type ind
- = getfem::add_nonlinear_twodomain_term
- (*md, *mim, expr, region, secdom, is_symmetric,
- is_coercive) + config::base_index();
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
-
- /*@SET ind = ('add nonlinear generic assembly brick', @tmim mim, @str
expression[, @int region[, @int is_symmetric[, @int is_coercive]]])
- Deprecated. Use MODEL:SET('add nonlinear term') instead.@*/
- sub_command
- ("add nonlinear generic assembly brick", 2, 5, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string expr = in.pop().to_string();
- size_type region = size_type(-1);
- if (in.remaining()) region = in.pop().to_integer();
- int is_symmetric = 0;
- if (in.remaining()) is_symmetric = in.pop().to_integer();
- int is_coercive = 0;
- if (in.remaining()) is_coercive = in.pop().to_integer();
-
- size_type ind
- = getfem::add_nonlinear_term
- (*md, *mim, expr, region, is_symmetric,
- is_coercive) + config::base_index();
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
- /*@SET ind = ('add source term', @tmim mim, @str expression[, @int region])
- Adds a source term given by the assembly string `expr` which will
- be assembled in region `region` and with the integration method `mim`.
- Only the residual term will be taken into account.
- Take care that if the expression contains some variables and if the
- expression is a potential, the expression will be
- derivated with respect to all variables.
- `brickname` is an optional name for the brick.@*/
- sub_command
- ("add source term", 2, 3, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string expr = in.pop().to_string();
- size_type region = size_type(-1);
- if (in.remaining()) region = in.pop().to_integer();
-
- size_type ind
- = getfem::add_source_term
- (*md, *mim, expr, region) + config::base_index();
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
- /*@SET ind = ('add twodomain source term', @tmim mim, @str expression,
@int region, @str secondary_domain)
- Adds a source term given by a weak form language expression like
- MODEL:SET('add source term') but for an integration on a direct
- product of two domains, a first specfied by ``mim`` and ``region``
- and a second one by ``secondary_domain`` which has to be declared
- first into the model.@*/
- sub_command
- ("add twodomain source term", 4, 4, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string expr = in.pop().to_string();
- size_type region = in.pop().to_integer();
- std::string secdom = in.pop().to_string();
-
- size_type ind
- = getfem::add_twodomain_source_term
- (*md, *mim, expr, region, secdom) + config::base_index();
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
- /*@SET ind = ('add source term generic assembly brick', @tmim mim, @str
expression[, @int region])
- Deprecated. Use MODEL:SET('add source term') instead. @*/
- sub_command
- ("add source term generic assembly brick", 2, 3, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string expr = in.pop().to_string();
- size_type region = size_type(-1);
- if (in.remaining()) region = in.pop().to_integer();
-
- size_type ind
- = getfem::add_source_term_generic_assembly_brick
- (*md, *mim, expr, region) + config::base_index();
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
- /*@SET ('add assembly assignment', @str dataname, @str expression[, @int
region[, @int order[, @int before]]])
- Adds expression `expr` to be evaluated at assembly time and being
- assigned to the data `dataname` which has to be of im_data type.
- This allows for instance to store a sub-expression of an assembly
- computation to be used on an other assembly. It can be used for instance
- to store the plastic strain in plasticity models.
- `order` represents the order of assembly where this assignement has to be
- done (potential(0), weak form(1) or tangent system(2) or at each
- order(-1)). The default value is 1.
- If before = 1, the the assignement is perfromed before the computation
- of the other assembly terms, such that the data can be used in the
- remaining of the assembly as an intermediary result (be careful that it
is
- still considered as a data, no derivation of the expression is performed
- for the tangent system).
- If before = 0 (default), the assignement is done after the assembly
terms.
- @*/
- sub_command
- ("add assembly assignment", 2, 5, 0, 0,
- std::string dataname = in.pop().to_string();
- std::string expr = in.pop().to_string();
- size_type region = size_type(-1);
- if (in.remaining()) region = in.pop().to_integer();
- size_type order = 1;
- if (in.remaining()) order = in.pop().to_integer();
- bool before = false;
- if (in.remaining()) before = (in.pop().to_integer() != 0);
-
- md->add_assembly_assignments(dataname, expr, region, order, before);
- );
-
- /*@SET ('clear assembly assignment')
- Delete all added assembly assignments
- @*/
- sub_command
- ("clear assembly assignment", 0, 0, 0, 0,
- md->clear_assembly_assignments();
- );
-
- /*@SET ind = ('add Laplacian brick', @tmim mim, @str varname[, @int
region])
- Add a Laplacian term to the model relatively to the variable `varname`
- (in fact with a minus : :math:`-\text{div}(\nabla u)`).
- If this is a vector valued variable, the Laplacian term is added
- componentwise. `region` is an optional mesh region on which the term
- is added. If it is not specified, it is added on the whole mesh. Return
- the brick index in the model.@*/
- sub_command
- ("add Laplacian brick", 2, 3, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname = in.pop().to_string();
- size_type region = size_type(-1);
- if (in.remaining()) region = in.pop().to_integer();
- size_type ind
- = getfem::add_Laplacian_brick(*md, *mim, varname, region)
- + config::base_index();
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
-
- /*@SET ind = ('add generic elliptic brick', @tmim mim, @str varname, @str
dataname[, @int region])
- Add a generic elliptic term to the model relatively to the variable
`varname`.
- The shape of the elliptic term depends both on the variable and the data.
- This corresponds to a term
- :math:`-\text{div}(a\nabla u)`
- where :math:`a` is the data and :math:`u` the variable. The data can be
- a scalar,
- a matrix or an order four tensor. The variable can be vector valued or
- not. If the data is a scalar or a matrix and the variable is vector
- valued then the term is added componentwise. An order four tensor data
- is allowed for vector valued variable only. The data can be constant or
- describbed on a fem. Of course, when the data is a tensor describe on a
- finite element method (a tensor field) the data can be a huge vector.
- The components of the matrix/tensor have to be stored with the fortran
- order (columnwise) in the data vector (compatibility with blas). The
- symmetry of the given matrix/tensor is not verified (but assumed). If
- this is a vector valued variable, the elliptic term is added
- componentwise. `region` is an optional mesh region on which the term is
- added. If it is not specified, it is added on the whole mesh. Note that
- for the real
- version which uses the high-level generic assembly language, `dataname`
- can be any regular expression of the high-level generic assembly
- language (like "1", "sin(X(1))" or "Norm(u)" for instance) even
- depending on model variables. Return the
- brick index in the model.@*/
- sub_command
- ("add generic elliptic brick", 3, 4, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname = in.pop().to_string();
- std::string dataname = in.pop().to_string();
- size_type region = size_type(-1);
- if (in.remaining()) region = in.pop().to_integer();
- size_type ind
- = getfem::add_generic_elliptic_brick(*md, *mim,
- varname, dataname, region)
- + config::base_index();
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
-
- /*@SET ind = ('add source term brick', @tmim mim, @str varname, @str
dataexpr[, @int region[, @str directdataname]])
- Add a source term to the model relatively to the variable `varname`.
- The source term is
- represented by `dataexpr` which could be any regular expression of the
- high-level generic assembly language (except for the complex version
- where it has to be a declared data of the model).
- `region` is an optional mesh region
- on which the term is added. An additional optional data `directdataname`
- can be provided. The corresponding data vector will be directly added
- to the right hand side without assembly. Note that when region is a
- boundary, this brick allows to prescribe a nonzero Neumann boundary
- condition. Return the brick index in the model.@*/
- sub_command
- ("add source term brick", 3, 5, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname = in.pop().to_string();
- std::string dataname = in.pop().to_string();
- size_type region = size_type(-1);
- if (in.remaining()) region = in.pop().to_integer();
- std::string directdataname;
- if (in.remaining()) directdataname = in.pop().to_string();
- size_type ind
- = getfem::add_source_term_brick(*md, *mim,
- varname, dataname, region, directdataname)
- + config::base_index();
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
-
- /*@SET ind = ('add normal source term brick', @tmim mim, @str varname,
@str dataname, @int region)
- Add a source term on the variable `varname` on a boundary `region`.
- This region should be a boundary. The source term is
- represented by the data `dataepxpr` which could be any regular
- expression of the high-level generic assembly language (except
- for the complex version where it has to be a declared data of
- the model). A scalar
- product with the outward normal unit vector to the boundary is performed.
- The main aim of this brick is to represent a Neumann condition with a
- vector data without performing the scalar product with the normal as a
- pre-processing. Return the brick index in the model.@*/
- sub_command
- ("add normal source term brick", 4, 4, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname = in.pop().to_string();
- std::string dataname = in.pop().to_string();
- size_type region = in.pop().to_integer();
- size_type ind
- = getfem::add_normal_source_term_brick(*md, *mim,
- varname, dataname, region)
- + config::base_index();
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
-
- /*@SET ind = ('add Dirichlet condition with simplification', @str varname,
@int region[, @str dataname])
- Adds a (simple) Dirichlet condition on the variable `varname` and
- the mesh region `region`. The Dirichlet condition is prescribed by
- a simple post-treatment of the final linear system (tangent system
- for nonlinear problems) consisting of modifying the lines corresponding
- to the degree of freedom of the variable on `region` (0 outside the
- diagonal, 1 on the diagonal of the matrix and the expected value on
- the right hand side).
- The symmetry of the linear system is kept if all other bricks are
- symmetric.
- This brick is to be reserved for simple Dirichlet conditions (only dof
- declared on the corresponding boundary are prescribed). The application
- of this brick on reduced dof may be problematic. Intrinsic vectorial
- finite element method are not supported.
- `dataname` is the optional right hand side of the Dirichlet condition.
- It could be constant (but in that case, it can only be applied to
- Lagrange f.e.m.) or (important) described on the same finite
- element method as `varname`.
- Returns the brick index in the model. @*/
- sub_command
- ("add Dirichlet condition with simplification", 2, 3, 0, 1,
- std::string varname = in.pop().to_string();
- size_type region = in.pop().to_integer();
- std::string dataname;
- if (in.remaining()) dataname = in.pop().to_string();
-
- size_type ind = config::base_index();
- ind += getfem::add_Dirichlet_condition_with_simplification
- (*md, varname, region, dataname);
- out.pop().from_integer(int(ind));
- );
-
-
- /*@SET ind = ('add Dirichlet condition with multipliers', @tmim mim, @str
varname, mult_description, @int region[, @str dataname])
- Add a Dirichlet condition on the variable `varname` and the mesh
- region `region`. This region should be a boundary. The Dirichlet
- condition is prescribed with a multiplier variable described by
- `mult_description`. If `mult_description` is a string this is assumed
- to be the variable name corresponding to the multiplier (which should be
- first declared as a multiplier variable on the mesh region in the model).
- If it is a finite element method (mesh_fem object) then a multiplier
- variable will be added to the model and build on this finite element
- method (it will be restricted to the mesh region `region` and eventually
- some conflicting dofs with some other multiplier variables will be
- suppressed). If it is an integer, then a multiplier variable will be
- added to the model and build on a classical finite element of degree
- that integer. `dataname` is the optional right hand side of the
- Dirichlet condition. It could be constant or described on a fem; scalar
- or vector valued, depending on the variable on which the Dirichlet
- condition is prescribed. Return the brick index in the model.@*/
- sub_command
- ("add Dirichlet condition with multipliers", 4, 5, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname = in.pop().to_string();
- int version = 0;
- size_type degree = 0;
- std::string multname;
- getfem::mesh_fem *mf = 0;
- mexarg_in argin = in.pop();
- if (argin.is_integer()) {
- degree = argin.to_integer();
- version = 1;
- } else if (argin.is_string()) {
- multname = argin.to_string();
- version = 2;
- } else {
- mf = to_meshfem_object(argin);
- version = 3;
- }
- size_type region = in.pop().to_integer();
- std::string dataname;
- if (in.remaining()) dataname = in.pop().to_string();
-
- size_type ind = config::base_index();
- switch(version) {
- case 1: ind += getfem::add_Dirichlet_condition_with_multipliers
- (*md, *mim, varname, dim_type(degree), region, dataname);
- break;
- case 2: ind += getfem::add_Dirichlet_condition_with_multipliers
- (*md, *mim, varname, multname, region, dataname);
- break;
- case 3: ind += getfem::add_Dirichlet_condition_with_multipliers
- (*md, *mim, varname, *mf, region, dataname);
- workspace().set_dependence(md, mf);
- break;
- }
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
- /*@SET ind = ('add Dirichlet condition with Nitsche method', @tmim mim,
@str varname, @str Neumannterm, @str datagamma0, @int region[, @scalar theta][,
@str dataname])
- Add a Dirichlet condition on the variable `varname` and the mesh
- region `region`. This region should be a boundary. `Neumannterm`
- is the expression of the Neumann term (obtained by the Green formula)
- described as an expression of the high-level
- generic assembly language. This term can be obtained by
- MODEL:GET('Neumann term', varname, region) once all volumic bricks have
- been added to the model. The Dirichlet
- condition is prescribed with Nitsche's method. `datag` is the optional
- right hand side of the Dirichlet condition. `datagamma0` is the
- Nitsche's method parameter. `theta` is a scalar value which can be
- positive or negative. `theta = 1` corresponds to the standard symmetric
- method which is conditionally coercive for `gamma0` small.
- `theta = -1` corresponds to the skew-symmetric method which is
- inconditionally coercive. `theta = 0` (default) is the simplest method
- for which the second derivative of the Neumann term is not necessary
- even for nonlinear problems. Return the brick index in the model.
- @*/
- sub_command
- ("add Dirichlet condition with Nitsche method", 5, 7, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname = in.pop().to_string();
- std::string Neumannterm = in.pop().to_string();
- std::string gamma0name = in.pop().to_string();
- size_type region = in.pop().to_integer();
- scalar_type theta = scalar_type(0);
- std::string dataname;
- if (in.remaining()) {
- mexarg_in argin = in.pop();
- if (argin.is_string())
- dataname = argin.to_string();
- else
- theta = argin.to_scalar();
- }
- if (in.remaining()) dataname = in.pop().to_string();
-
- size_type ind = config::base_index();
- ind += getfem::add_Dirichlet_condition_with_Nitsche_method
- (*md, *mim, varname, Neumannterm,
- gamma0name, region, theta, dataname);
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
- /*@SET ind = ('add Dirichlet condition with penalization', @tmim mim, @str
varname, @scalar coeff, @int region[, @str dataname, @tmf mf_mult])
- Add a Dirichlet condition on the variable `varname` and the mesh
- region `region`. This region should be a boundary. The Dirichlet
- condition is prescribed with penalization. The penalization coefficient
- is initially `coeff` and will be added to the data of the model.
- `dataname` is the optional right hand side of the Dirichlet condition.
- It could be constant or described on a fem; scalar or vector valued,
- depending on the variable on which the Dirichlet condition is prescribed.
- `mf_mult` is an optional parameter which allows to weaken the
- Dirichlet condition specifying a multiplier space.
- Return the brick index in the model.@*/
- sub_command
- ("add Dirichlet condition with penalization", 4, 6, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname = in.pop().to_string();
- double coeff = in.pop().to_scalar();
- size_type region = in.pop().to_integer();
- std::string dataname;
- if (in.remaining()) dataname = in.pop().to_string();
- const getfem::mesh_fem *mf_mult = 0;
- if (in.remaining()) mf_mult = to_meshfem_object(in.pop());
- size_type ind = config::base_index();
- ind += getfem::add_Dirichlet_condition_with_penalization
- (*md, *mim, varname, coeff, region,
- dataname, mf_mult);
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
- /*@SET ind = ('add normal Dirichlet condition with multipliers', @tmim
mim, @str varname, mult_description, @int region[, @str dataname])
- Add a Dirichlet condition to the normal component of the vector
- (or tensor) valued variable `varname` and the mesh
- region `region`. This region should be a boundary. The Dirichlet
- condition is prescribed with a multiplier variable described by
- `mult_description`. If `mult_description` is a string this is assumed
- to be the variable name corresponding to the multiplier (which should be
- first declared as a multiplier variable on the mesh region in the model).
- If it is a finite element method (mesh_fem object) then a multiplier
- variable will be added to the model and build on this finite element
- method (it will be restricted to the mesh region `region` and eventually
- some conflicting dofs with some other multiplier variables will be
- suppressed). If it is an integer, then a multiplier variable will be
- added to the model and build on a classical finite element of degree
- that integer. `dataname` is the optional right hand side of the
- Dirichlet condition. It could be constant or described on a fem; scalar
- or vector valued, depending on the variable on which the Dirichlet
- condition is prescribed (scalar if the variable
- is vector valued, vector if the variable is tensor valued).
- Returns the brick index in the model.@*/
- sub_command
- ("add normal Dirichlet condition with multipliers", 4, 5, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname = in.pop().to_string();
- int version = 0;
- size_type degree = 0;
- std::string multname;
- getfem::mesh_fem *mf = 0;
- mexarg_in argin = in.pop();
- if (argin.is_integer()) {
- degree = argin.to_integer();
- version = 1;
- } else if (argin.is_string()) {
- multname = argin.to_string();
- version = 2;
- } else {
- mf = to_meshfem_object(argin);
- version = 3;
- }
- size_type region = in.pop().to_integer();
- std::string dataname;
- if (in.remaining()) dataname = in.pop().to_string();
-
- size_type ind = config::base_index();
- switch(version) {
- case 1: ind += getfem::add_normal_Dirichlet_condition_with_multipliers
- (*md, *mim, varname, dim_type(degree), region, dataname);
- break;
- case 2: ind += getfem::add_normal_Dirichlet_condition_with_multipliers
- (*md, *mim, varname, multname, region, dataname);
- break;
- case 3: ind += getfem::add_normal_Dirichlet_condition_with_multipliers
- (*md, *mim, varname, *mf, region, dataname);
- workspace().set_dependence(md, mf);
- break;
- }
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
-
- /*@SET ind = ('add normal Dirichlet condition with penalization', @tmim
mim, @str varname, @scalar coeff, @int region[, @str dataname, @tmf mf_mult])
- Add a Dirichlet condition to the normal component of the vector
- (or tensor) valued variable `varname` and the mesh
- region `region`. This region should be a boundary. The Dirichlet
- condition is prescribed with penalization. The penalization coefficient
- is initially `coeff` and will be added to the data of the model.
- `dataname` is the optional right hand side of the Dirichlet condition.
- It could be constant or described on a fem; scalar or vector valued,
- depending on the variable on which the Dirichlet condition is prescribed
- (scalar if the variable
- is vector valued, vector if the variable is tensor valued).
- `mf_mult` is an optional parameter which allows to weaken the
- Dirichlet condition specifying a multiplier space.
- Returns the brick index in the model.@*/
- sub_command
- ("add normal Dirichlet condition with penalization", 4, 6, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname = in.pop().to_string();
- double coeff = in.pop().to_scalar();
- size_type region = in.pop().to_integer();
- std::string dataname;
- if (in.remaining()) dataname = in.pop().to_string();
- const getfem::mesh_fem *mf_mult = 0;
- if (in.remaining()) mf_mult = to_meshfem_object(in.pop());
- size_type ind = config::base_index();
- ind += getfem::add_normal_Dirichlet_condition_with_penalization
- (*md, *mim, varname, coeff, region,
- dataname, mf_mult);
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
-
- /*@SET ind = ('add normal Dirichlet condition with Nitsche method', @tmim
mim, @str varname, @str Neumannterm, @str gamma0name, @int region[, @scalar
theta][, @str dataname])
- Add a Dirichlet condition to the normal component of the vector
- (or tensor) valued variable `varname` and the mesh region `region`.
- This region should be a boundary. `Neumannterm`
- is the expression of the Neumann term (obtained by the Green formula)
- described as an expression of the high-level
- generic assembly language. This term can be obtained by
- MODEL:GET('Neumann term', varname, region) once all volumic bricks have
- been added to the model. The Dirichlet
- condition is prescribed with Nitsche's method. `dataname` is the optional
- right hand side of the Dirichlet condition. It could be constant or
- described on a fem. `gamma0name` is the
- Nitsche's method parameter. `theta` is a scalar value which can be
- positive or negative. `theta = 1` corresponds to the standard symmetric
- method which is conditionally coercive for `gamma0` small.
- `theta = -1` corresponds to the skew-symmetric method which is
- inconditionally coercive. `theta = 0` is the simplest method
- for which the second derivative of the Neumann term is not necessary
- even for nonlinear problems.
- Returns the brick index in the model.
- (This brick is not fully tested)
- @*/
- sub_command
- ("add normal Dirichlet condition with Nitsche method", 5, 7, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname = in.pop().to_string();
- std::string Neumannterm = in.pop().to_string();
- std::string gamma0name = in.pop().to_string();
- size_type region = in.pop().to_integer();
- scalar_type theta = scalar_type(1);
- std::string dataname;
- if (in.remaining()) {
- mexarg_in argin = in.pop();
- if (argin.is_string())
- dataname = argin.to_string();
- else
- theta = argin.to_scalar();
- }
- if (in.remaining()) dataname = in.pop().to_string();
-
- size_type ind = config::base_index();
- ind += getfem::add_normal_Dirichlet_condition_with_Nitsche_method
- (*md, *mim, varname, Neumannterm,
- gamma0name, region, theta, dataname);
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
-
- /*@SET ind = ('add generalized Dirichlet condition with multipliers',
@tmim mim, @str varname, mult_description, @int region, @str dataname, @str
Hname)
- Add a Dirichlet condition on the variable `varname` and the mesh
- region `region`. This version is for vector field.
- It prescribes a condition :math:`Hu = r`
- where `H` is a matrix field. The region should be a boundary. The Dirichlet
- condition is prescribed with a multiplier variable described by
- `mult_description`. If `mult_description` is a string this is assumed
- to be the variable name corresponding to the multiplier (which should be
- first declared as a multiplier variable on the mesh region in the model).
- If it is a finite element method (mesh_fem object) then a multiplier
- variable will be added to the model and build on this finite element
- method (it will be restricted to the mesh region `region` and eventually
- some conflicting dofs with some other multiplier variables will be
- suppressed). If it is an integer, then a multiplier variable will be
- added to the model and build on a classical finite element of degree
- that integer. `dataname` is the right hand side of the
- Dirichlet condition. It could be constant or described on a fem; scalar
- or vector valued, depending on the variable on which the Dirichlet
- condition is prescribed. `Hname` is the data
- corresponding to the matrix field `H`.
- Returns the brick index in the model.@*/
- sub_command
- ("add generalized Dirichlet condition with multipliers", 6, 6, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname = in.pop().to_string();
- int version = 0;
- size_type degree = 0;
- std::string multname;
- getfem::mesh_fem *mf = 0;
- mexarg_in argin = in.pop();
- if (argin.is_integer()) {
- degree = argin.to_integer();
- version = 1;
- } else if (argin.is_string()) {
- multname = argin.to_string();
- version = 2;
- } else {
- mf = to_meshfem_object(argin);
- version = 3;
- }
- size_type region = in.pop().to_integer();
- std::string dataname = in.pop().to_string();
- std::string Hname = in.pop().to_string();
- size_type ind = config::base_index();
- switch(version) {
- case 1: ind +=
getfem::add_generalized_Dirichlet_condition_with_multipliers
- (*md, *mim, varname, dim_type(degree), region, dataname, Hname);
- break;
- case 2: ind +=
getfem::add_generalized_Dirichlet_condition_with_multipliers
- (*md, *mim, varname, multname, region, dataname, Hname);
- break;
- case 3: ind +=
getfem::add_generalized_Dirichlet_condition_with_multipliers
- (*md, *mim, varname, *mf, region, dataname, Hname);
- workspace().set_dependence(md, mf);
- break;
- }
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
-
- /*@SET ind = ('add generalized Dirichlet condition with penalization',
@tmim mim, @str varname, @scalar coeff, @int region, @str dataname, @str
Hname[, @tmf mf_mult])
- Add a Dirichlet condition on the variable `varname` and the mesh
- region `region`. This version is for vector field.
- It prescribes a condition :math:`Hu = r`
- where `H` is a matrix field.
- The region should be a boundary. The Dirichlet
- condition is prescribed with penalization. The penalization coefficient
- is intially `coeff` and will be added to the data of the model.
- `dataname` is the right hand side of the Dirichlet condition.
- It could be constant or described on a fem; scalar or vector valued,
- depending on the variable on which the Dirichlet condition is prescribed.
- `Hname` is the data
- corresponding to the matrix field `H`. It has to be a constant matrix
- or described on a scalar fem.
- `mf_mult` is an optional parameter which allows to weaken the
- Dirichlet condition specifying a multiplier space.
- Return the brick index in the model.@*/
- sub_command
- ("add generalized Dirichlet condition with penalization", 6, 7, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname = in.pop().to_string();
- double coeff = in.pop().to_scalar();
- size_type region = in.pop().to_integer();
- std::string dataname= in.pop().to_string();
- std::string Hname= in.pop().to_string();
- const getfem::mesh_fem *mf_mult = 0;
- if (in.remaining()) mf_mult = to_meshfem_object(in.pop());
- size_type ind = config::base_index();
- ind += getfem::add_generalized_Dirichlet_condition_with_penalization
- (*md, *mim, varname, coeff, region,
- dataname, Hname, mf_mult);
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
-
- /*@SET ind = ('add generalized Dirichlet condition with Nitsche method',
@tmim mim, @str varname, @str Neumannterm, @str gamma0name, @int region[,
@scalar theta], @str dataname, @str Hname)
- Add a Dirichlet condition on the variable `varname` and the mesh
- region `region`.
- This version is for vector field. It prescribes a condition
- @f$ Hu = r @f$ where `H` is a matrix field.
- CAUTION : the matrix H should have all eigenvalues equal to 1 or 0.
- The region should be a boundary. `Neumannterm`
- is the expression of the Neumann term (obtained by the Green formula)
- described as an expression of the high-level
- generic assembly language. This term can be obtained by
- MODEL:GET('Neumann term', varname, region) once all volumic bricks have
- been added to the model. The Dirichlet
- condition is prescribed with Nitsche's method. `dataname` is the optional
- right hand side of the Dirichlet condition. It could be constant or
- described on a fem. `gamma0name` is the
- Nitsche's method parameter. `theta` is a scalar value which can be
- positive or negative. `theta = 1` corresponds to the standard symmetric
- method which is conditionally coercive for `gamma0` small.
- `theta = -1` corresponds to the skew-symmetric method which is
- inconditionally coercive. `theta = 0` is the simplest method
- for which the second derivative of the Neumann term is not necessary
- even for nonlinear problems. `Hname` is the data
- corresponding to the matrix field `H`. It has to be a constant matrix
- or described on a scalar fem. Returns the brick index in the model.
- (This brick is not fully tested)
- @*/
- sub_command
- ("add generalized Dirichlet condition with Nitsche method", 7, 8, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname = in.pop().to_string();
- std::string Neumannterm = in.pop().to_string();
- std::string gamma0name = in.pop().to_string();
- size_type region = in.pop().to_integer();
- scalar_type theta = scalar_type(1);
- std::string dataname;
- if (in.remaining()) {
- mexarg_in argin = in.pop();
- if (argin.is_string())
- dataname = argin.to_string();
- else
- theta = argin.to_scalar();
- }
- dataname = in.pop().to_string();
- std::string Hname= in.pop().to_string();
-
- size_type ind = config::base_index();
- ind += getfem::add_generalized_Dirichlet_condition_with_Nitsche_method
- (*md, *mim, varname, Neumannterm,
- gamma0name, region, theta, dataname, Hname);
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
- /*@SET ind = ('add pointwise constraints with multipliers', @str varname,
@str dataname_pt[, @str dataname_unitv] [, @str dataname_val])
- Add some pointwise constraints on the variable `varname` using
- multiplier. The multiplier variable is automatically added to the model.
- The conditions are prescribed on a set of points given in the data
- `dataname_pt` whose dimension is the number of points times the dimension
- of the mesh.
- If the variable represents a vector field, one has to give the data
- `dataname_unitv` which represents a vector of dimension the number of
- points times the dimension of the vector field which should store some
- unit vectors. In that case the prescribed constraint is the scalar
- product of the variable at the corresponding point with the corresponding
- unit vector.
- The optional data `dataname_val` is the vector of values to be prescribed
- at the different points.
- This brick is specifically designed to kill rigid displacement
- in a Neumann problem.
- Returns the brick index in the model.@*/
- sub_command
- ("add pointwise constraints with multipliers", 2, 4, 0, 1,
- std::string varname = in.pop().to_string();
- std::string dataname_pt = in.pop().to_string();
- const getfem::mesh_fem *mf_u
- = &(md->mesh_fem_of_variable(varname));
- GMM_ASSERT1(mf_u, "The variable should depend on a mesh_fem");
- std::string dataname_unitv;
- if (mf_u->get_qdim() > 1)
- dataname_unitv = in.pop().to_string();
- std::string dataname_val;
- if (in.remaining()) dataname_val = in.pop().to_string();
-
- size_type ind = config::base_index();
- ind += getfem::add_pointwise_constraints_with_multipliers
- (*md, varname, dataname_pt, dataname_unitv, dataname_val);
- out.pop().from_integer(int(ind));
- );
-
- /*@SET ind = ('add pointwise constraints with given multipliers', @str
varname, @str multname, @str dataname_pt[, @str dataname_unitv] [, @str
dataname_val])
- Add some pointwise constraints on the variable `varname` using a given
- multiplier `multname`.
- The conditions are prescribed on a set of points given in the data
- `dataname_pt` whose dimension is the number of points times the dimension
- of the mesh.
- The multiplier variable should be a fixed size variable of size the
- number of points.
- If the variable represents a vector field, one has to give the data
- `dataname_unitv` which represents a vector of dimension the number of
- points times the dimension of the vector field which should store some
- unit vectors. In that case the prescribed constraint is the scalar
- product of the variable at the corresponding point with the corresponding
- unit vector.
- The optional data `dataname_val` is the vector of values to be prescribed
- at the different points.
- This brick is specifically designed to kill rigid displacement
- in a Neumann problem.
- Returns the brick index in the model.@*/
- sub_command
- ("add pointwise constraints with given multipliers", 3, 5, 0, 1,
- std::string varname = in.pop().to_string();
- std::string multname = in.pop().to_string();
- std::string dataname_pt = in.pop().to_string();
- const getfem::mesh_fem *mf_u
- = &(md->mesh_fem_of_variable(varname));
- GMM_ASSERT1(mf_u, "The variable should depend on a mesh_fem");
- std::string dataname_unitv;
- if (mf_u->get_qdim() > 1)
- dataname_unitv = in.pop().to_string();
- std::string dataname_val;
- if (in.remaining()) dataname_val = in.pop().to_string();
-
- size_type ind = config::base_index();
- ind += getfem::add_pointwise_constraints_with_given_multipliers
- (*md, varname, multname, dataname_pt, dataname_unitv,
- dataname_val);
- out.pop().from_integer(int(ind));
- );
-
-
- /*@SET ind = ('add pointwise constraints with penalization', @str varname,
@scalar coeff, @str dataname_pt[, @str dataname_unitv] [, @str dataname_val])
- Add some pointwise constraints on the variable `varname` thanks to
- a penalization. The penalization coefficient is initially
- `penalization_coeff` and will be added to the data of the model.
- The conditions are prescribed on a set of points given in the data
- `dataname_pt` whose dimension is the number of points times the dimension
- of the mesh.
- If the variable represents a vector field, one has to give the data
- `dataname_unitv` which represents a vector of dimension the number of
- points times the dimension of the vector field which should store some
- unit vectors. In that case the prescribed constraint is the scalar
- product of the variable at the corresponding point with the corresponding
- unit vector.
- The optional data `dataname_val` is the vector of values to be prescribed
- at the different points.
- This brick is specifically designed to kill rigid displacement
- in a Neumann problem.
- Returns the brick index in the model.@*/
- sub_command
- ("add pointwise constraints with penalization", 3, 5, 0, 1,
- std::string varname = in.pop().to_string();
- double coeff = in.pop().to_scalar();
- std::string dataname_pt = in.pop().to_string();
- const getfem::mesh_fem *mf_u
- = &(md->mesh_fem_of_variable(varname));
- GMM_ASSERT1(mf_u, "The variable should depend on a mesh_fem");
- std::string dataname_unitv;
- if (mf_u->get_qdim() > 1)
- dataname_unitv = in.pop().to_string();
- std::string dataname_val;
- if (in.remaining()) dataname_val = in.pop().to_string();
-
- size_type ind = config::base_index();
- ind += getfem::add_pointwise_constraints_with_penalization
- (*md, varname, coeff, dataname_pt, dataname_unitv,
- dataname_val);
- out.pop().from_integer(int(ind));
- );
-
-
- /*@SET ('change penalization coeff', @int ind_brick, @scalar coeff)
- Change the penalization coefficient of a Dirichlet condition with
- penalization brick. If the brick is not of this kind, this
- function has an undefined behavior.@*/
- sub_command
- ("change penalization coeff", 2, 2, 0, 0,
- size_type ind_brick = in.pop().to_integer() - config::base_index();
- double coeff = in.pop().to_scalar();
- getfem::change_penalization_coeff(*md, ind_brick, coeff);
- );
-
-
- /*@SET ind = ('add Helmholtz brick', @tmim mim, @str varname, @str
dataexpr[, @int region])
- Add a Helmholtz term to the model relatively to the variable `varname`.
- `dataexpr` is the wave number. `region` is an optional mesh
- region on which the term is added. If it is not specified, it is added
- on the whole mesh. Return the brick index in the model.@*/
- sub_command
- ("add Helmholtz brick", 3, 4, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname = in.pop().to_string();
- std::string dataname = in.pop().to_string();
- size_type region = size_type(-1);
- if (in.remaining()) region = in.pop().to_integer();
- size_type ind
- = getfem::add_Helmholtz_brick(*md, *mim,
- varname, dataname, region)
- + config::base_index();
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
-
- /*@SET ind = ('add Fourier Robin brick', @tmim mim, @str varname, @str
dataexpr, @int region)
- Add a Fourier-Robin term to the model relatively to the variable
- `varname`. This corresponds to a weak term of the form
- :math:`\int (qu).v`. `dataexpr` is the parameter :math:`q` of
- the Fourier-Robin condition. It can be an arbitrary valid expression
- of the high-level generic assembly language (except for the complex version
- for which it should be a data of the model). `region` is the mesh region
- on which the term is added. Return the brick index in the model.@*/
- sub_command
- ("add Fourier Robin brick", 4, 4, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname = in.pop().to_string();
- std::string dataname = in.pop().to_string();
- size_type region = size_type(-1);
- if (in.remaining()) region = in.pop().to_integer();
- size_type ind
- = getfem::add_Fourier_Robin_brick(*md, *mim,
- varname,dataname, region)
- + config::base_index();
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
- /*@SET ind = ('add constraint with multipliers', @str varname, @str
multname, @tspmat B, {@vec L | @str dataname})
- Add an additional explicit constraint on the variable `varname` thank to
- a multiplier `multname` peviously added to the model (should be a fixed
- size variable). The constraint is :math:`BU=L`
- with `B` being a rectangular sparse matrix. It is possible to change
- the constraint at any time with the methods MODEL:SET('set private matrix')
- and MODEL:SET('set private rhs'). If `dataname` is specified instead of
`L`,
- the vector `L` is defined in the model as data with the given name.
- Return the brick index in the model.@*/
- sub_command
- ("add constraint with multipliers", 4, 4, 0, 1,
- std::string varname = in.pop().to_string();
- std::string multname = in.pop().to_string();
- std::shared_ptr<gsparse> B = in.pop().to_sparse();
- if (B->is_complex() && !md->is_complex())
- THROW_BADARG("Complex constraint for a real model");
- if (!B->is_complex() && md->is_complex())
- THROW_BADARG("Real constraint for a complex model");
-
- size_type ind
- = getfem::add_constraint_with_multipliers(*md,varname,multname);
-
- if (md->is_complex()) {
- if (B->storage()==gsparse::CSCMAT)
- getfem::set_private_data_matrix(*md, ind, B->cplx_csc());
- else if (B->storage()==gsparse::WSCMAT)
- getfem::set_private_data_matrix(*md, ind, B->cplx_wsc());
- else
- THROW_BADARG("Constraint matrix should be a sparse matrix");
- } else {
- if (B->storage()==gsparse::CSCMAT)
- getfem::set_private_data_matrix(*md, ind, B->real_csc());
- else if (B->storage()==gsparse::WSCMAT)
- getfem::set_private_data_matrix(*md, ind, B->real_wsc());
- else
- THROW_BADARG("Constraint matrix should be a sparse matrix");
- }
-
- if (in.front().is_string()) {
- std::string dataname = in.pop().to_string();
- getfem::set_private_data_rhs(*md, ind, dataname);
- } else if (!md->is_complex()) {
- darray st = in.pop().to_darray();
- std::vector<double> V(st.begin(), st.end());
- getfem::set_private_data_rhs(*md, ind, V);
- } else {
- carray st = in.pop().to_carray();
- std::vector<std::complex<double> > V(st.begin(), st.end());
- getfem::set_private_data_rhs(*md, ind, V);
- }
-
- out.pop().from_integer(int(ind + config::base_index()));
- );
-
-
- /*@SET ind = ('add constraint with penalization', @str varname, @scalar
coeff, @tspmat B, {@vec L | @str dataname})
- Add an additional explicit penalized constraint on the variable `varname`.
- The constraint is :math`BU=L` with `B` being a rectangular sparse matrix.
- Be aware that `B` should not contain a plain row, otherwise the whole
- tangent matrix will be plain. It is possible to change the constraint
- at any time with the methods MODEL:SET('set private matrix')
- and MODEL:SET('set private rhs'). The method
- MODEL:SET('change penalization coeff') can be used.
- If `dataname` is specified instead of `L`, the vector `L` is defined
- in the model as data with the given name.
- Return the brick
- index in the model.@*/
- sub_command
- ("add constraint with penalization", 4, 4, 0, 1,
- std::string varname = in.pop().to_string();
- double coeff = in.pop().to_scalar();
- std::shared_ptr<gsparse> B = in.pop().to_sparse();
- if (B->is_complex() && !md->is_complex())
- THROW_BADARG("Complex constraint for a real model");
- if (!B->is_complex() && md->is_complex())
- THROW_BADARG("Real constraint for a complex model");
-
- size_type ind
- = getfem::add_constraint_with_penalization(*md, varname, coeff);
-
- if (md->is_complex()) {
- if (B->storage()==gsparse::CSCMAT)
- getfem::set_private_data_matrix(*md, ind, B->cplx_csc());
- else if (B->storage()==gsparse::WSCMAT)
- getfem::set_private_data_matrix(*md, ind, B->cplx_wsc());
- else
- THROW_BADARG("Constraint matrix should be a sparse matrix");
- } else {
- if (B->storage()==gsparse::CSCMAT)
- getfem::set_private_data_matrix(*md, ind, B->real_csc());
- else if (B->storage()==gsparse::WSCMAT)
- getfem::set_private_data_matrix(*md, ind, B->real_wsc());
- else
- THROW_BADARG("Constraint matrix should be a sparse matrix");
- }
-
- if (in.front().is_string()) {
- std::string dataname = in.pop().to_string();
- getfem::set_private_data_rhs(*md, ind, dataname);
- } else if (!md->is_complex()) {
- darray st = in.pop().to_darray();
- std::vector<double> V(st.begin(), st.end());
- getfem::set_private_data_rhs(*md, ind, V);
- } else {
- carray st = in.pop().to_carray();
- std::vector<std::complex<double> > V(st.begin(), st.end());
- getfem::set_private_data_rhs(*md, ind, V);
- }
-
- out.pop().from_integer(int(ind + config::base_index()));
- );
-
-
- /*@SET ind = ('add explicit matrix', @str varname1, @str varname2, @tspmat
B[, @int issymmetric[, @int iscoercive]])
- Add a brick representing an explicit matrix to be added to the tangent
- linear system relatively to the variables `varname1` and `varname2`.
- The given matrix should have has many rows as the dimension of
- `varname1` and as many columns as the dimension of `varname2`.
- If the two variables are different and if `issymmetric` is set to 1
- then the transpose of the matrix is also added to the tangent system
- (default is 0). Set `iscoercive` to 1 if the term does not affect the
- coercivity of the tangent system (default is 0). The matrix can be
- changed by the command MODEL:SET('set private matrix'). Return the
- brick index in the model.@*/
- sub_command
- ("add explicit matrix", 3, 5, 0, 1,
- std::string varname1 = in.pop().to_string();
- std::string varname2 = in.pop().to_string();
- std::shared_ptr<gsparse> B = in.pop().to_sparse();
- bool issymmetric = false;
- bool iscoercive = false;
- if (in.remaining()) issymmetric = (in.pop().to_integer(0,1) != 0);
- if (!issymmetric && in.remaining())
- iscoercive = (in.pop().to_integer(0,1) != 0);
-
- size_type ind
- = getfem::add_explicit_matrix(*md, varname1, varname2,
- issymmetric, iscoercive);
-
- if (B->is_complex() && !md->is_complex())
- THROW_BADARG("Complex constraint for a real model");
- if (!B->is_complex() && md->is_complex())
- THROW_BADARG("Real constraint for a complex model");
-
- if (md->is_complex()) {
- if (B->storage()==gsparse::CSCMAT)
- getfem::set_private_data_matrix(*md, ind, B->cplx_csc());
- else if (B->storage()==gsparse::WSCMAT)
- getfem::set_private_data_matrix(*md, ind, B->cplx_wsc());
- else
- THROW_BADARG("Constraint matrix should be a sparse matrix");
- } else {
- if (B->storage()==gsparse::CSCMAT)
- getfem::set_private_data_matrix(*md, ind, B->real_csc());
- else if (B->storage()==gsparse::WSCMAT)
- getfem::set_private_data_matrix(*md, ind, B->real_wsc());
- else
- THROW_BADARG("Constraint matrix should be a sparse matrix");
- }
-
- out.pop().from_integer(int(ind + config::base_index()));
- );
-
-
- /*@SET ind = ('add explicit rhs', @str varname, @vec L)
- Add a brick representing an explicit right hand side to be added to
- the right hand side of the tangent linear system relatively to the
- variable `varname`. The given rhs should have the same size than the
- dimension of `varname`. The rhs can be changed by the command
- MODEL:SET('set private rhs'). If `dataname` is specified instead of
- `L`, the vector `L` is defined in the model as data with the given name.
- Return the brick index in the model.@*/
- sub_command
- ("add explicit rhs", 2, 2, 0, 1,
- std::string varname = in.pop().to_string();
- size_type ind
- = getfem::add_explicit_rhs(*md, varname);
-
- if (in.front().is_string()) {
- std::string dataname = in.pop().to_string();
- getfem::set_private_data_rhs(*md, ind, dataname);
- } else if (!md->is_complex()) {
- darray st = in.pop().to_darray();
- std::vector<double> V(st.begin(), st.end());
- getfem::set_private_data_rhs(*md, ind, V);
- } else {
- carray st = in.pop().to_carray();
- std::vector<std::complex<double> > V(st.begin(), st.end());
- getfem::set_private_data_rhs(*md, ind, V);
- }
-
- out.pop().from_integer(int(ind + config::base_index()));
- );
-
-
- /*@SET ('set private matrix', @int indbrick, @tspmat B)
- For some specific bricks having an internal sparse matrix
- (explicit bricks: 'constraint brick' and 'explicit matrix brick'),
- set this matrix. @*/
- sub_command
- ("set private matrix", 2, 2, 0, 0,
- size_type ind = in.pop().to_integer() - config::base_index();
- std::shared_ptr<gsparse> B = in.pop().to_sparse();
-
- if (B->is_complex() && !md->is_complex())
- THROW_BADARG("Complex constraint for a real model");
- if (!B->is_complex() && md->is_complex())
- THROW_BADARG("Real constraint for a complex model");
-
- if (md->is_complex()) {
- if (B->storage()==gsparse::CSCMAT)
- getfem::set_private_data_matrix(*md, ind, B->cplx_csc());
- else if (B->storage()==gsparse::WSCMAT)
- getfem::set_private_data_matrix(*md, ind, B->cplx_wsc());
- else
- THROW_BADARG("Constraint matrix should be a sparse matrix");
- } else {
- if (B->storage()==gsparse::CSCMAT)
- getfem::set_private_data_matrix(*md, ind, B->real_csc());
- else if (B->storage()==gsparse::WSCMAT)
- getfem::set_private_data_matrix(*md, ind, B->real_wsc());
- else
- THROW_BADARG("Constraint matrix should be a sparse matrix");
- }
- );
-
-
- /*@SET ('set private rhs', @int indbrick, @vec B)
- For some specific bricks having an internal right hand side vector
- (explicit bricks: 'constraint brick' and 'explicit rhs brick'),
- set this rhs. @*/
- sub_command
- ("set private rhs", 2, 2, 0, 0,
- size_type ind = in.pop().to_integer() - config::base_index();
-
- if (!md->is_complex()) {
- darray st = in.pop().to_darray();
- std::vector<double> V(st.begin(), st.end());
- getfem::set_private_data_rhs(*md, ind, V);
- } else {
- carray st = in.pop().to_carray();
- std::vector<std::complex<double> > V(st.begin(), st.end());
- getfem::set_private_data_rhs(*md, ind, V);
- }
- );
-
-
- /*@SET ind = ('add isotropic linearized elasticity brick', @tmim mim, @str
varname, @str dataname_lambda, @str dataname_mu[, @int region])
- Add an isotropic linearized elasticity term to the model relatively to
- the variable `varname`. `dataname_lambda` and `dataname_mu` should
- contain the Lame coefficients. `region` is an optional mesh region
- on which the term is added. If it is not specified, it is added
- on the whole mesh. Return the brick index in the model.@*/
- sub_command
- ("add isotropic linearized elasticity brick", 4, 5, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname = in.pop().to_string();
- std::string dataname_lambda = in.pop().to_string();
- std::string dataname_mu = in.pop().to_string();
- size_type region = size_type(-1);
- if (in.remaining()) region = in.pop().to_integer();
- size_type ind
- = getfem::add_isotropic_linearized_elasticity_brick
- (*md, *mim, varname, dataname_lambda, dataname_mu, region)
- + config::base_index();
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
- /*@SET ind = ('add isotropic linearized elasticity brick pstrain', @tmim
mim, @str varname, @str data_E, @str data_nu[, @int region])
- Add an isotropic linearized elasticity term to the model relatively to
- the variable `varname`. `data_E` and `data_nu` should
- contain the Young modulus and Poisson ratio, respectively.
- `region` is an optional mesh region on which the term is added.
- If it is not specified, it is added
- on the whole mesh.
- On two-dimensional meshes, the term will correpsond to a plain strain
- approximation. On three-dimensional meshes, it will correspond to the
- standard model.
- Return the brick index in the model.@*/
- sub_command
- ("add isotropic linearized elasticity brick pstrain", 4, 5, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname = in.pop().to_string();
- std::string data_E = in.pop().to_string();
- std::string data_nu = in.pop().to_string();
- size_type region = size_type(-1);
- if (in.remaining()) region = in.pop().to_integer();
- size_type ind
- = getfem::add_isotropic_linearized_elasticity_brick_pstrain
- (*md, *mim, varname, data_E, data_nu, region)
- + config::base_index();
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
- /*@SET ind = ('add isotropic linearized elasticity brick pstress', @tmim
mim, @str varname, @str data_E, @str data_nu[, @int region])
- Add an isotropic linearized elasticity term to the model relatively to
- the variable `varname`. `data_E` and `data_nu` should
- contain the Young modulus and Poisson ratio, respectively.
- `region` is an optional mesh region on which the term is added.
- If it is not specified, it is added
- on the whole mesh.
- On two-dimensional meshes, the term will correpsond to a plain stress
- approximation. On three-dimensional meshes, it will correspond to the
- standard model.
- Return the brick index in the model.@*/
- sub_command
- ("add isotropic linearized elasticity brick pstress", 4, 5, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname = in.pop().to_string();
- std::string data_E = in.pop().to_string();
- std::string data_nu = in.pop().to_string();
- size_type region = size_type(-1);
- if (in.remaining()) region = in.pop().to_integer();
- size_type ind
- = getfem::add_isotropic_linearized_elasticity_brick_pstress
- (*md, *mim, varname, data_E, data_nu, region)
- + config::base_index();
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
-
- /*@SET ind = ('add linear incompressibility brick', @tmim mim, @str
varname, @str multname_pressure[, @int region[, @str dataexpr_coeff]])
- Add a linear incompressibility condition on `variable`. `multname_pressure`
- is a variable which represent the pressure. Be aware that an inf-sup
- condition between the finite element method describing the pressure and the
- primal variable has to be satisfied. `region` is an optional mesh region on
- which the term is added. If it is not specified, it is added on the whole
- mesh. `dataexpr_coeff` is an optional penalization coefficient for nearly
- incompressible elasticity for instance. In this case, it is the inverse
- of the Lame coefficient :math:`\lambda`. Return the brick index in the
- model.@*/
- sub_command
- ("add linear incompressibility brick", 3, 5, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname = in.pop().to_string();
- std::string multname = in.pop().to_string();
- size_type region = size_type(-1);
- if (in.remaining()) region = in.pop().to_integer();
- std::string dataname;
- if (in.remaining()) dataname = in.pop().to_string();
- size_type ind
- = getfem::add_linear_incompressibility
- (*md, *mim, varname, multname, region, dataname)
- + config::base_index();
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
-
- /*@SET ind = ('add nonlinear elasticity brick', @tmim mim, @str varname,
@str constitutive_law, @str dataname[, @int region])
- Add a nonlinear elasticity term to the model relatively to the
- variable `varname` (deprecated brick, use add_finite_strain_elaticity
- instead). `lawname` is the constitutive law which
- could be 'SaintVenant Kirchhoff', 'Mooney Rivlin', 'neo Hookean',
- 'Ciarlet Geymonat' or 'generalized Blatz Ko'.
- 'Mooney Rivlin' and 'neo Hookean' law names can be preceded with the word
- 'compressible' or 'incompressible' to force using the corresponding
version.
- The compressible version of these laws requires one additional material
- coefficient. By default, the incompressible version of 'Mooney Rivlin' law
- and the compressible one of the 'neo Hookean' law are considered. In
- general, 'neo Hookean' is a special case of the 'Mooney Rivlin' law that
- requires one coefficient less.
- IMPORTANT : if the variable is defined on a 2D mesh, the plane strain
- approximation is automatically used.
- `dataname` is a vector of parameters for the constitutive law. Its length
- depends on the law. It could be a short vector of constant values or a
- vector field described on a finite element method for variable
- coefficients. `region` is an optional mesh region on which the term
- is added. If it is not specified, it is added on the whole mesh.
- This brick use the low-level generic assembly.
- Returns the brick index in the model.@*/
- sub_command
- ("add nonlinear elasticity brick", 4, 5, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- size_type N = mim->linked_mesh().dim();
- std::string varname = in.pop().to_string();
- std::string lawname = in.pop().to_string();
- std::string dataname = in.pop().to_string();
- size_type region = size_type(-1);
- if (in.remaining()) region = in.pop().to_integer();
- size_type ind = config::base_index() +
- add_nonlinear_elasticity_brick
- (*md, *mim, varname,
- abstract_hyperelastic_law_from_name(lawname, N), dataname, region);
-
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
- /*@SET ind = ('add finite strain elasticity brick', @tmim mim, @str
constitutive_law, @str varname, @str params[, @int region])
- Add a nonlinear elasticity term to the model relatively to the
- variable `varname`. `lawname` is the constitutive law which
- could be 'SaintVenant Kirchhoff', 'Mooney Rivlin', 'Neo Hookean',
- 'Ciarlet Geymonat' or 'Generalized Blatz Ko'.
- 'Mooney Rivlin' and 'Neo Hookean' law names have to be preceeded with
- the word 'Compressible' or 'Incompressible' to force using the
- corresponding version.
- The compressible version of these laws requires one additional material
- coefficient.
-
- IMPORTANT : if the variable is defined on a 2D mesh, the plane strain
- approximation is automatically used.
- `params` is a vector of parameters for the constitutive law. Its length
- depends on the law. It could be a short vector of constant values or a
- vector field described on a finite element method for variable
- coefficients. `region` is an optional mesh region on which the term
- is added. If it is not specified, it is added on the whole mesh.
- This brick use the high-level generic assembly.
- Returns the brick index in the model.@*/
- sub_command
- ("add finite strain elasticity brick", 4, 5, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- // size_type N = *mim.linked_mesh().dim();
- std::string lawname = in.pop().to_string();
- std::string varname = in.pop().to_string();
- std::string params = in.pop().to_string();
- size_type region = size_type(-1);
- if (in.remaining()) region = in.pop().to_integer();
-
- std::string ln = varname; // tolerance for the compatibility with 5.0
- filter_lawname(ln);
- if (ln.compare("saintvenant_kirchhoff") == 0 ||
- ln.compare("saint_venant_kirchhoff") == 0 ||
- ln.compare("generalized_blatz_ko") == 0 ||
- ln.compare("ciarlet_geymonat") == 0 ||
- ln.compare("incompressible_mooney_rivlin") == 0 ||
- ln.compare("compressible_mooney_rivlin") == 0 ||
- ln.compare("incompressible_neo_hookean") == 0 ||
- ln.compare("compressible_neo_hookean") == 0 ||
- ln.compare("compressible_neo_hookean_bonet") == 0 ||
- ln.compare("compressible_neo_hookean_ciarlet") == 0) {
- std::swap(lawname, varname);
- }
-
- size_type ind = config::base_index() +
- add_finite_strain_elasticity_brick
- (*md, *mim, lawname, varname, params, region);
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
- /*@SET ind = ('add small strain elastoplasticity brick', @tmim mim, @str
lawname, @str unknowns_type [, @str varnames, ...] [, @str params, ...] [, @str
theta = '1' [, @str dt = 'timestep']] [, @int region = -1])
- Adds a small strain plasticity term to the model `M`. This is the
- main GetFEM++ brick for small strain plasticity. `lawname` is the name
- of an implemented plastic law, `unknowns_type` indicates the choice
- between a discretization where the plastic multiplier is an unknown of
- the problem or (return mapping approach) just a data of the model
- stored for the next iteration. Remember that in both cases, a multiplier
- is stored anyway. `varnames` is a set of variable and data names with
- length which may depend on the plastic law (at least the displacement,
- the plastic multiplier and the plastic strain). `params` is a list of
- expressions for the parameters (at least elastic coefficients and the
- yield stress). These expressions can be some data names (or even
- variable names) of the model but can also be any scalar valid expression
- of the high level assembly language (such as '1/2', '2+sin(X[0])',
- '1+Norm(v)' ...). The last two parameters optionally provided in
- `params` are the `theta` parameter of the `theta`-scheme (generalized
- trapezoidal rule) used for the plastic strain integration and the
- time-step`dt`. The default value for `theta` if omitted is 1, which
- corresponds to the classical Backward Euler scheme which is first order
- consistent. `theta=1/2` corresponds to the Crank-Nicolson scheme
- (trapezoidal rule) which is second order consistent. Any value
- between 1/2 and 1 should be a valid value. The default value of `dt` is
- 'timestep' which simply indicates the time step defined in the model
- (by md.set_time_step(dt)). Alternatively it can be any expression
- (data name, constant value ...). The time step can be altered from one
- iteration to the next one. `region` is a mesh region.
-
- The available plasticity laws are:
-
- - 'Prandtl Reuss' (or 'isotropic perfect plasticity').
- Isotropic elasto-plasticity with no hardening. The variables are the
- displacement, the plastic multiplier and the plastic strain.
- The displacement should be a variable and have a corresponding data
- having the same name preceded by 'Previous\_' corresponding to the
- displacement at the previous time step (typically 'u' and
'Previous_u').
- The plastic multiplier should also have two versions (typically 'xi'
- and 'Previous_xi') the first one being defined as data if
- `unknowns_type ` is 'DISPLACEMENT_ONLY' or the integer value 0, or as
- a variable if `unknowns_type` is DISPLACEMENT_AND_PLASTIC_MULTIPLIER
- or the integer value 1.
- The plastic strain should represent a n x n data tensor field stored
- on mesh_fem or (preferably) on an im_data (corresponding to `mim`).
- The data are the first Lame coefficient, the second one (shear modulus)
- and the uniaxial yield stress. A typical call is
- MODEL:GET('add small strain elastoplasticity brick', mim, 'Prandtl
Reuss', 0, 'u', 'xi', 'Previous_Ep', 'lambda', 'mu', 'sigma_y', '1',
'timestep');
- IMPORTANT: Note that this law implements
- the 3D expressions. If it is used in 2D, the expressions are just
- transposed to the 2D. For the plane strain approximation, see below.
- - "plane strain Prandtl Reuss"
- (or "plane strain isotropic perfect plasticity")
- The same law as the previous one but adapted to the plane strain
- approximation. Can only be used in 2D.
- - "Prandtl Reuss linear hardening"
- (or "isotropic plasticity linear hardening").
- Isotropic elasto-plasticity with linear isotropic and kinematic
- hardening. An additional variable compared to "Prandtl Reuss" law:
- the accumulated plastic strain. Similarly to the plastic strain, it
- is only stored at the end of the time step, so a simple data is
- required (preferably on an im_data).
- Two additional parameters: the kinematic hardening modulus and the
- isotropic one. 3D expressions only. A typical call is
- MODEL:GET('add small strain elastoplasticity brick', mim, 'Prandtl
Reuss linear hardening', 0, 'u', 'xi', 'Previous_Ep', 'Previous_alpha',
'lambda', 'mu', 'sigma_y', 'H_k', H_i', '1', 'timestep');
- - "plane strain Prandtl Reuss linear hardening"
- (or "plane strain isotropic plasticity linear hardening").
- The same law as the previous one but adapted to the plane strain
- approximation. Can only be used in 2D.
-
- See GetFEM++ user documentation for further explanations on the
- discretization of the plastic flow and on the implemented plastic laws.
- See also GetFEM++ user documentation on time integration strategy
- (integration of transient problems).
-
- IMPORTANT : remember that `small_strain_elastoplasticity_next_iter` has
- to be called at the end of each time step, before the next one
- (and before any post-treatment : this sets the value of the plastic
- strain and plastic multiplier).
- @*/
- sub_command
- ("add small strain elastoplasticity brick", 3, 15, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string lawname = in.pop().to_string();
- filter_lawname(lawname);
- size_type nb_var = 0; size_type nb_params = 0;
- if (lawname.compare("isotropic_perfect_plasticity") == 0 ||
- lawname.compare("prandtl_reuss") == 0 ||
- lawname.compare("plane_strain_isotropic_perfect_plasticity") == 0 ||
- lawname.compare("plane_strain_prandtl_reuss") == 0) {
- nb_var = nb_params = 3;
- } else if
- (lawname.compare("isotropic_plasticity_linear_hardening") == 0 ||
- lawname.compare("prandtl_reuss_linear_hardening") == 0 ||
-
lawname.compare("plane_strain_isotropic_plasticity_linear_hardening") == 0 ||
- lawname.compare("plane_strain_prandtl_reuss_linear_hardening") == 0)
{
- nb_var = 4; nb_params = 5;
- } else
- THROW_BADARG(lawname << " is not an implemented elastoplastic law");
-
- getfem::plasticity_unknowns_type
unknowns_type(getfem::DISPLACEMENT_ONLY);
- mexarg_in argin = in.pop();
- if (argin.is_string()) {
- std::string opt = argin.to_string();
- filter_lawname(opt);
- if (opt.compare("displacement_only") == 0)
- unknowns_type = getfem::DISPLACEMENT_ONLY;
- else if (opt.compare("displacement_and_plastic_multiplier") == 0)
- unknowns_type = getfem::DISPLACEMENT_AND_PLASTIC_MULTIPLIER;
- else
- THROW_BADARG("Wrong input");
- } else if (argin.is_integer())
- unknowns_type = static_cast<getfem::plasticity_unknowns_type>
- (argin.to_integer(0,1));
-
- std::vector<std::string> varnames;
- for (size_type i = 0; i < nb_var; ++i)
- varnames.push_back(in.pop().to_string());
-
- std::vector<std::string> params;
- for (size_type i = 0; i < nb_params; ++i)
- params.push_back(in.pop().to_string());
-
- std::string theta = "1";
- std::string dt = "timestep";
- size_type region = size_type(-1);
- for (size_type i=0; i < 3 && in.remaining(); ++i) {
- argin = in.pop();
- if (argin.is_string()) {
- if (i==0) theta = argin.to_string();
- else if (i==1) dt = argin.to_string();
- else THROW_BADARG("Wrong input");
- } else if (argin.is_integer()) {
- region = argin.to_integer();
- GMM_ASSERT1(!in.remaining(), "Wrong input");
- }
- }
- params.push_back(theta);
- params.push_back(dt);
-
- size_type ind = config::base_index() +
- getfem::add_small_strain_elastoplasticity_brick
- (*md, *mim, lawname, unknowns_type, varnames, params, region);
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
- /*@SET ind = ('add elastoplasticity brick', @tmim mim ,@str projname, @str
varname, @str previous_dep_name, @str datalambda, @str datamu, @str
datathreshold, @str datasigma[, @int region])
- Old (obsolete) brick which do not use the high level generic
- assembly. Add a nonlinear elastoplastic term to the model relatively
- to the variable `varname`, in small deformations, for an isotropic
- material and for a quasistatic model. `projname` is the type of
- projection that used: only the Von Mises projection is
- available with 'VM' or 'Von Mises'.
- `datasigma` is the variable representing the constraints on the material.
- `previous_dep_name` represents the displacement at the previous time
step.
- Moreover, the finite element method on which `varname` is described
- is an K ordered mesh_fem, the `datasigma` one have to be at least
- an K-1 ordered mesh_fem.
- `datalambda` and `datamu` are the Lame coefficients of the studied
- material.
- `datathreshold` is the plasticity threshold of the material.
- The three last variables could be constants or described on the
- same finite element method.
- `region` is an optional mesh region on which the term is added.
- If it is not specified, it is added on the whole mesh.
- Return the brick index in the model.@*/
- sub_command
- ("add elastoplasticity brick", 8, 9, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string projname = in.pop().to_string();
- std::string varname = in.pop().to_string();
- std::string previous_dep = in.pop().to_string();
- std::string datalambda = in.pop().to_string();
- std::string datamu = in.pop().to_string();
- std::string datathreshold = in.pop().to_string();
- std::string datasigma = in.pop().to_string();
- size_type region = size_type(-1);
-
- // getfem::VM_projection proj(0);
- if (in.remaining()) region = in.pop().to_integer();
- size_type ind = config::base_index() +
- add_elastoplasticity_brick
- (*md, *mim,
- abstract_constraints_projection_from_name(projname),
- varname, previous_dep, datalambda, datamu,
- datathreshold, datasigma,
- region);
-
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
-
- /*@SET ind = ('add finite strain elastoplasticity brick', @tmim mim , @str
lawname, @str unknowns_type [, @str varnames, ...] [, @str params, ...] [, @int
region = -1])
- Add a finite strain elastoplasticity brick to the model.
- For the moment there is only one supported law defined through
- `lawname` as "Simo_Miehe".
- This law supports to possibilities of unknown variables to solve for
- defined by means of `unknowns_type` set to either
- 'DISPLACEMENT_AND_PLASTIC_MULTIPLIER' (integer value 1) or
- 'DISPLACEMENT_AND_PLASTIC_MULTIPLIER_AND_PRESSURE' (integer value 3).
- The "Simo_Miehe" law expects as `varnames` a set of the
- following names that have to be defined as variables in the model:
-
- - the displacement variable which has to be defined as an unknown,
- - the plastic multiplier which has also defined as an unknown,
- - optionally the pressure variable for a mixed displacement-pressure
- formulation for 'DISPLACEMENT_AND_PLASTIC_MULTIPLIER_AND_PRESSURE'
- as `unknowns_type`,
- - the name of a (scalar) fem_data or im_data field that holds the
- plastic strain at the previous time step, and
- - the name of a fem_data or im_data field that holds all
- non-repeated components of the inverse of the plastic right
- Cauchy-Green tensor at the previous time step
- (it has to be a 4 element vector for plane strain 2D problems
- and a 6 element vector for 3D problems).
-
- The "Simo_Miehe" law also expects as `params` a set of the
- following three parameters:
-
- - an expression for the initial bulk modulus K,
- - an expression for the initial shear modulus G,
- - the name of a user predefined function that decribes
- the yield limit as a function of the hardening variable
- (both the yield limit and the hardening variable values are
- assumed to be Frobenius norms of appropriate stress and strain
- tensors, respectively).
-
- As usual, `region` is an optional mesh region on which the term is added.
- If it is not specified, it is added on the whole mesh.
- Return the brick index in the model.@*/
- sub_command
- ("add finite strain elastoplasticity brick", 10, 11, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string lawname = in.pop().to_string();
- filter_lawname(lawname);
- size_type nb_var = 0; size_type nb_params = 0;
- if (lawname.compare("simo_miehe") == 0 ||
- lawname.compare("eterovic_bathe") == 0) {
- nb_var = 4;
- nb_params = 3;
- } else
- THROW_BADARG(lawname << " is not an implemented finite strain"
- << " elastoplastic law");
-
- getfem::plasticity_unknowns_type
unknowns_type(getfem::DISPLACEMENT_ONLY);
- mexarg_in argin = in.pop();
- if (argin.is_string()) {
- std::string opt = argin.to_string();
- filter_lawname(opt);
- if (opt.compare("displacement_and_plastic_multiplier") == 0)
- unknowns_type = getfem::DISPLACEMENT_AND_PLASTIC_MULTIPLIER;
- else if (opt.compare("displacement_and_plastic_multiplier"
- "_and_pressure") == 0)
- unknowns_type =
getfem::DISPLACEMENT_AND_PLASTIC_MULTIPLIER_AND_PRESSURE;
- else
- THROW_BADARG("Wrong input");
- } else if (argin.is_integer()) {
- unknowns_type = static_cast<getfem::plasticity_unknowns_type>
- (argin.to_integer());
- GMM_ASSERT1
- (unknowns_type == getfem::DISPLACEMENT_AND_PLASTIC_MULTIPLIER ||
- unknowns_type ==
getfem::DISPLACEMENT_AND_PLASTIC_MULTIPLIER_AND_PRESSURE,
- "Not valid input for unknowns_type");
- }
- if (unknowns_type ==
getfem::DISPLACEMENT_AND_PLASTIC_MULTIPLIER_AND_PRESSURE)
- nb_var += 1;
-
- std::vector<std::string> varnames;
- for (size_type i = 0; i < nb_var; ++i)
- varnames.push_back(in.pop().to_string());
-
- std::vector<std::string> params;
- for (size_type i = 0; i < nb_params; ++i)
- params.push_back(in.pop().to_string());
-
- size_type region(-1);
- if (in.remaining()) {
- argin = in.pop();
- if (!argin.is_integer())
- THROW_BADARG("Last optional argument must be an integer");
- region = argin.to_integer();
- }
-
- size_type ind = config::base_index() +
- add_finite_strain_elastoplasticity_brick
- (*md, *mim, lawname, unknowns_type, varnames, params, region);
-
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
-
- /*@SET ind = ('add nonlinear incompressibility brick', @tmim mim, @str
varname, @str multname_pressure[, @int region])
- Add a nonlinear incompressibility condition on `variable` (for large
- strain elasticity). `multname_pressure`
- is a variable which represent the pressure. Be aware that an inf-sup
- condition between the finite element method describing the pressure and the
- primal variable has to be satisfied. `region` is an optional mesh region on
- which the term is added. If it is not specified, it is added on the
- whole mesh. Return the brick index in the model.@*/
- sub_command
- ("add nonlinear incompressibility brick", 3, 4, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname = in.pop().to_string();
- std::string multname = in.pop().to_string();
- size_type region = size_type(-1);
- if (in.remaining()) region = in.pop().to_integer();
- size_type ind
- = getfem::add_nonlinear_incompressibility_brick
- (*md, *mim, varname, multname, region)
- + config::base_index();
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
-
- /*@SET ind = ('add finite strain incompressibility brick', @tmim mim, @str
varname, @str multname_pressure[, @int region])
- Add a finite strain incompressibility condition on `variable` (for large
- strain elasticity). `multname_pressure`
- is a variable which represent the pressure. Be aware that an inf-sup
- condition between the finite element method describing the pressure and the
- primal variable has to be satisfied. `region` is an optional mesh region on
- which the term is added. If it is not specified, it is added on the
- whole mesh. Return the brick index in the model.
- This brick is equivalent to the ``nonlinear incompressibility brick`` but
- uses the high-level generic assembly adding the term
- ``p*(1-Det(Id(meshdim)+Grad_u))`` if ``p`` is the multiplier and
- ``u`` the variable which represent the displacement.@*/
- sub_command
- ("add finite strain incompressibility brick", 3, 4, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname = in.pop().to_string();
- std::string multname = in.pop().to_string();
- size_type region = size_type(-1);
- if (in.remaining()) region = in.pop().to_integer();
- size_type ind
- = getfem::add_finite_strain_incompressibility_brick
- (*md, *mim, varname, multname, region)
- + config::base_index();
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
- /*@SET ind = ('add bilaplacian brick', @tmim mim, @str varname, @str
dataname [, @int region])
- Add a bilaplacian brick on the variable
- `varname` and on the mesh region `region`.
- This represent a term :math:`\Delta(D \Delta u)`.
- where :math:`D(x)` is a coefficient determined by `dataname` which
- could be constant or described on a f.e.m. The corresponding weak form
- is :math:`\int D(x)\Delta u(x) \Delta v(x) dx`.
- Return the brick index in the model.@*/
- sub_command
- ("add bilaplacian brick", 3, 4, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname = in.pop().to_string();
- std::string dataname = in.pop().to_string();
- size_type region = size_type(-1);
- if (in.remaining()) region = in.pop().to_integer();
- size_type ind = config::base_index() +
- add_bilaplacian_brick(*md, *mim,
- varname, dataname, region);
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
- /*@SET ind = ('add Kirchhoff-Love plate brick', @tmim mim, @str varname,
@str dataname_D, @str dataname_nu [, @int region])
- Add a bilaplacian brick on the variable
- `varname` and on the mesh region `region`.
- This represent a term :math:`\Delta(D \Delta u)` where :math:`D(x)`
- is a the flexion modulus determined by `dataname_D`. The term is
- integrated by part following a Kirchhoff-Love plate model
- with `dataname_nu` the poisson ratio.
- Return the brick index in the model.@*/
- sub_command
- ("add Kirchhoff-Love plate brick", 4, 5, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname = in.pop().to_string();
- std::string dataname_D = in.pop().to_string();
- std::string dataname_nu = in.pop().to_string();
- size_type region = size_type(-1);
- if (in.remaining()) region = in.pop().to_integer();
- size_type ind = config::base_index() +
- add_bilaplacian_brick_KL(*md, *mim,
- varname, dataname_D, dataname_nu, region);
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
- /*@SET ind = ('add normal derivative source term brick', @tmim mim, @str
varname, @str dataname, @int region)
- Add a normal derivative source term brick
- :math:`F = \int b.\partial_n v` on the variable `varname` and the
- mesh region `region`.
-
- Update the right hand side of the linear system.
- `dataname` represents `b` and `varname` represents `v`.
- Return the brick index in the model.@*/
- sub_command
- ("add normal derivative source term brick", 4, 4, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname = in.pop().to_string();
- std::string dataname = in.pop().to_string();
- size_type region = in.pop().to_integer();
- size_type ind = config::base_index() +
- add_normal_derivative_source_term_brick(*md, *mim,
- varname, dataname, region);
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
- /*@SET ind = ('add Kirchhoff-Love Neumann term brick', @tmim mim, @str
varname, @str dataname_M, @str dataname_divM, @int region)
- Add a Neumann term brick for Kirchhoff-Love model
- on the variable `varname` and the mesh region `region`.
- `dataname_M` represents the bending moment tensor and `dataname_divM`
- its divergence.
- Return the brick index in the model.@*/
- sub_command
- ("add Kirchhoff-Love Neumann term brick", 5, 5, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname = in.pop().to_string();
- std::string dataname_M = in.pop().to_string();
- std::string dataname_divM = in.pop().to_string();
- size_type region = in.pop().to_integer();
- size_type ind = config::base_index() +
- add_Kirchhoff_Love_Neumann_term_brick(*md, *mim,
- varname, dataname_M, dataname_divM, region);
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
-
- /*@SET ind = ('add normal derivative Dirichlet condition with
multipliers', @tmim mim, @str varname, mult_description, @int region [, @str
dataname, @int R_must_be_derivated])
- Add a Dirichlet condition on the normal derivative of the variable
- `varname` and on the mesh region `region` (which should be a boundary).
- The general form is
- :math:`\int \partial_n u(x)v(x) = \int r(x)v(x) \forall v`
- where :math:`r(x)` is
- the right hand side for the Dirichlet condition (0 for
- homogeneous conditions) and :math:`v` is in a space of multipliers
- defined by `mult_description`.
- If `mult_description` is a string this is assumed
- to be the variable name corresponding to the multiplier (which should be
- first declared as a multiplier variable on the mesh region in the model).
- If it is a finite element method (mesh_fem object) then a multiplier
- variable will be added to the model and build on this finite element
- method (it will be restricted to the mesh region `region` and eventually
- some conflicting dofs with some other multiplier variables will be
- suppressed). If it is an integer, then a multiplier variable will be
- added to the model and build on a classical finite element of degree
- that integer. `dataname` is an optional parameter which represents
- the right hand side of the Dirichlet condition.
- If `R_must_be_derivated` is set to `true` then the normal
- derivative of `dataname` is considered.
- Return the brick index in the model.@*/
- sub_command
- ("add normal derivative Dirichlet condition with multipliers", 4, 6, 0,
1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname = in.pop().to_string();
- std::string multname;
- getfem::mesh_fem *mf = 0;
- size_type degree = 0;
- size_type version = 0;
- mexarg_in argin = in.pop();
- if (argin.is_integer()) {
- degree = argin.to_integer();
- version = 1;
- } else if (argin.is_string()) {
- multname = argin.to_string();
- version = 2;
- } else {
- mf = to_meshfem_object(argin);
- version = 3;
- }
- size_type region = in.pop().to_integer();
- std::string dataname;
- if (in.remaining()) dataname = in.pop().to_string();
- bool R_must_be_derivated = false;
- if (in.remaining())
- R_must_be_derivated = (in.pop().to_integer(0,1)) != 0;
- size_type ind = config::base_index();
- switch(version) {
- case 1: ind +=
- add_normal_derivative_Dirichlet_condition_with_multipliers
- (*md, *mim, varname, dim_type(degree), region,
- dataname, R_must_be_derivated ); break;
- case 2: ind +=
- add_normal_derivative_Dirichlet_condition_with_multipliers
- (*md, *mim, varname, multname, region,
- dataname, R_must_be_derivated ); break;
- case 3: ind +=
- add_normal_derivative_Dirichlet_condition_with_multipliers
- (*md, *mim, varname, *mf,
- region, dataname, R_must_be_derivated ); break;
- }
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
-
- /*@SET ind = ('add normal derivative Dirichlet condition with
penalization', @tmim mim, @str varname, @scalar coeff, @int region [, @str
dataname, @int R_must_be_derivated])
- Add a Dirichlet condition on the normal derivative of the variable
- `varname` and on the mesh region `region` (which should be a boundary).
- The general form is
- :math:`\int \partial_n u(x)v(x) = \int r(x)v(x) \forall v`
- where :math:`r(x)` is
- the right hand side for the Dirichlet condition (0 for
- homogeneous conditions).
- The penalization coefficient
- is initially `coeff` and will be added to the data of the model.
- It can be changed with the command MODEL:SET('change penalization
coeff').
- `dataname` is an optional parameter which represents
- the right hand side of the Dirichlet condition.
- If `R_must_be_derivated` is set to `true` then the normal
- derivative of `dataname` is considered.
- Return the brick index in the model.@*/
- sub_command
- ("add normal derivative Dirichlet condition with penalization", 4, 6, 0,
1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname = in.pop().to_string();
- double coeff = in.pop().to_scalar();
- size_type region = in.pop().to_integer();
- std::string dataname;
- if (in.remaining()) dataname = in.pop().to_string();
- bool R_must_be_derivated = false;
- if (in.remaining())
- R_must_be_derivated = (in.pop().to_integer(0,1)) != 0;
- size_type ind = config::base_index() +
- add_normal_derivative_Dirichlet_condition_with_penalization
- (*md, *mim, varname, coeff, region,
- dataname, R_must_be_derivated );
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
-
- /*@SET ind = ('add Mindlin Reissner plate brick', @tmim mim, @tmim
mim_reduced, @str varname_u3, @str varname_theta , @str param_E, @str param_nu,
@str param_epsilon, @str param_kappa [,@int variant [, @int region]])
- Add a term corresponding to the classical Reissner-Mindlin plate
- model for which `varname_u3` is the transverse displacement,
- `varname_theta` the rotation of
- fibers normal to the midplane, 'param_E' the Young Modulus,
- `param_nu` the poisson ratio,
- `param_epsilon` the plate thickness,
- `param_kappa` the shear correction factor. Note that since this brick
- uses the high level generic assembly language, the parameter can
- be regular expression of this language.
- There are three variants.
- `variant = 0` corresponds to the an
- unreduced formulation and in that case only the integration
- method `mim` is used. Practically this variant is not usable since
- it is subject to a strong locking phenomenon.
- `variant = 1` corresponds to a reduced integration where `mim` is
- used for the rotation term and `mim_reduced` for the transverse
- shear term. `variant = 2` (default) corresponds to the projection onto
- a rotated RT0 element of the transverse shear term. For the moment, this
- is adapted to quadrilateral only (because it is not sufficient to
- remove the locking phenomenon on triangle elements). Note also that if
- you use high order elements, the projection on RT0 will reduce the order
- of the approximation.
- Returns the brick index in the model.
- @*/
- sub_command
- ("add Mindlin Reissner plate brick", 7, 9, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- getfem::mesh_im *mim_reduced = to_meshim_object(in.pop());
- std::string varname_U = in.pop().to_string();
- std::string varname_theta = in.pop().to_string();
- std::string param_E = in.pop().to_string();
- std::string param_nu = in.pop().to_string();
- std::string param_epsilon = in.pop().to_string();
- std::string param_kapa = in.pop().to_string();
- size_type variant = size_type(2);
- if (in.remaining()) variant = in.pop().to_integer();
- size_type region = size_type(-1);
- if (in.remaining()) region = in.pop().to_integer();
- size_type ind = add_Mindlin_Reissner_plate_brick
- (*md, *mim, *mim_reduced,
- varname_U, varname_theta, param_E, param_nu, param_epsilon,
- param_kapa, variant, region);
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
-
- /*@SET ind = ('add enriched Mindlin Reissner plate brick', @tmim mim,
@tmim mim_reduced1, @tmim mim_reduced2, @str varname_ua, @str
varname_theta,@str varname_u3, @str varname_theta3 , @str param_E, @str
param_nu, @str param_epsilon [,@int variant [, @int region]])
- Add a term corresponding to the enriched Reissner-Mindlin plate
- model for which `varname_ua` is the membrane displacements,
- `varname_u3` is the transverse displacement,
- `varname_theta` the rotation of
- fibers normal to the midplane,
- `varname_theta3` the pinching,
- 'param_E' the Young Modulus,
- `param_nu` the poisson ratio,
- `param_epsilon` the plate thickness. Note that since this brick
- uses the high level generic assembly language, the parameter can
- be regular expression of this language.
- There are four variants.
- `variant = 0` corresponds to the an
- unreduced formulation and in that case only the integration
- method `mim` is used. Practically this variant is not usable since
- it is subject to a strong locking phenomenon.
- `variant = 1` corresponds to a reduced integration where `mim` is
- used for the rotation term and `mim_reduced1` for the transverse
- shear term and `mim_reduced2` for the pinching term.
- `variant = 2` (default) corresponds to the projection onto
- a rotated RT0 element of the transverse shear term and a reduced
integration for the pinching term.
- For the moment, this is adapted to quadrilateral only (because it is not
sufficient to
- remove the locking phenomenon on triangle elements). Note also that if
- you use high order elements, the projection on RT0 will reduce the order
- of the approximation.
- `variant = 3` corresponds to the projection onto
- a rotated RT0 element of the transverse shear term and the projection onto
P0 element of the pinching term.
- For the moment, this is adapted to quadrilateral only (because it is not
sufficient to
- remove the locking phenomenon on triangle elements). Note also that if
- you use high order elements, the projection on RT0 will reduce the order
- of the approximation.
- Returns the brick index in the model.
- @*/
- sub_command
- ("add enriched Mindlin Reissner plate brick", 10, 12, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- getfem::mesh_im *mim_reduced1 = to_meshim_object(in.pop());
- getfem::mesh_im *mim_reduced2 = to_meshim_object(in.pop());
- std::string varname_Ua = in.pop().to_string();
- std::string varname_theta = in.pop().to_string();
- std::string varname_U3 = in.pop().to_string();
- std::string varname_theta3 = in.pop().to_string();
- std::string param_E = in.pop().to_string();
- std::string param_nu = in.pop().to_string();
- std::string param_epsilon = in.pop().to_string();
- size_type variant = size_type(3);//2
- if (in.remaining()) variant = in.pop().to_integer();
- size_type region = size_type(-1);
- if (in.remaining()) region = in.pop().to_integer();
- size_type ind = add_enriched_Mindlin_Reissner_plate_brick
- (*md, *mim, *mim_reduced1,*mim_reduced2,
- varname_Ua, varname_theta, varname_U3, varname_theta3,
- param_E, param_nu, param_epsilon, variant, region);
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
-
- /*@SET ind = ('add mass brick', @tmim mim, @str varname[, @str
dataexpr_rho[, @int region]])
- Add mass term to the model relatively to the variable `varname`.
- If specified, the data `dataexpr_rho` is the
- density (1 if omitted). `region` is an optional mesh region on
- which the term is added. If it is not specified, it
- is added on the whole mesh. Return the brick index in the model.@*/
- sub_command
- ("add mass brick", 2, 4, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname = in.pop().to_string();
- std::string dataname_rho;
- if (in.remaining()) dataname_rho = in.pop().to_string();
- size_type region = size_type(-1);
- if (in.remaining()) region = in.pop().to_integer();
- size_type ind
- = getfem::add_mass_brick
- (*md, *mim, varname, dataname_rho, region)
- + config::base_index();
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
-
- /*@SET ('shift variables for time integration')
- Function used to shift the variables of a model to the data
- corresponding of ther value on the previous time step for time
- integration schemes. For each variable for which a time integration
- scheme has been declared, the scheme is called to perform the shift.
- This function has to be called between two time steps. @*/
- sub_command
- ("shift variables for time integration", 0, 0, 0, 0,
- md->shift_variables_for_time_integration();
- );
-
- /*@SET ('perform init time derivative', @scalar ddt)
- By calling this function, indicates that the next solve will compute
- the solution for a (very) small time step `ddt` in order to initalize
- the data corresponding to the derivatives needed by time integration
- schemes (mainly the initial time derivative for order one in time
- problems and the second order time derivative for second order in time
- problems). The next solve will not change the value of the variables. @*/
- sub_command
- ("perform init time derivative", 1, 1, 0, 0,
- double ddt = in.pop().to_scalar();
- md->perform_init_time_derivative(ddt);
- );
-
- /*@SET ('set time step', @scalar dt)
- Set the value of the time step to `dt`. This value can be change
- from a step to another for all one-step schemes (i.e. for the moment
- to all proposed time integration schemes). @*/
- sub_command
- ("set time step", 1, 1, 0, 0,
- double dt = in.pop().to_scalar();
- md->set_time_step(dt);
- );
-
- /*@SET ('set time', @scalar t)
- Set the value of the data `t` corresponding to the current time to `t`.
- @*/
- sub_command
- ("set time", 1, 1, 0, 0,
- double t = in.pop().to_scalar();
- md->set_time(t);
- );
-
-
- /*@SET ('add theta method for first order', @str varname, @scalar theta)
- Attach a theta method for the time discretization of the variable
- `varname`. Valid only if there is at most first order time derivative
- of the variable. @*/
- sub_command
- ("add theta method for first order", 2, 2, 0, 0,
- std::string varname = in.pop().to_string();
- double theta = in.pop().to_scalar();
- getfem::add_theta_method_for_first_order(*md, varname, theta);
- );
-
- /*@SET ('add theta method for second order', @str varname, @scalar theta)
- Attach a theta method for the time discretization of the variable
- `varname`. Valid only if there is at most second order time derivative
- of the variable. @*/
- sub_command
- ("add theta method for second order", 2, 2, 0, 0,
- std::string varname = in.pop().to_string();
- double theta = in.pop().to_scalar();
- getfem::add_theta_method_for_second_order(*md, varname, theta);
- );
-
- /*@SET ('add Newmark scheme', @str varname, @scalar beta, @scalar gamma)
- Attach a theta method for the time discretization of the variable
- `varname`. Valid only if there is at most second order time derivative
- of the variable. @*/
- sub_command
- ("add Newmark scheme", 3, 3, 0, 0,
- std::string varname = in.pop().to_string();
- double beta = in.pop().to_scalar();
- double gamma = in.pop().to_scalar();
- getfem::add_Newmark_scheme(*md, varname, beta, gamma);
- );
-
- /*@SET ('add_Houbolt_scheme', @str varname)
- Attach a Houbolt method for the time discretization of the variable
- `varname`. Valid only if there is at most second order time derivative
- of the variable @*/
- sub_command
- ("add Houbolt scheme", 1, 1, 0, 0,
- std::string varname = in.pop().to_string();
- getfem::add_Houbolt_scheme(*md, varname);
- );
-
- /*@SET ('disable bricks', @ivec bricks_indices)
- Disable a brick (the brick will no longer participate to the
- building of the tangent linear system).@*/
- sub_command
- ("disable bricks", 1, 1, 0, 0,
- dal::bit_vector bv = in.pop().to_bit_vector();
- for (dal::bv_visitor ii(bv); !ii.finished(); ++ii)
- md->disable_brick(ii);
- );
-
-
- /*@SET ('enable bricks', @ivec bricks_indices)
- Enable a disabled brick. @*/
- sub_command
- ("enable bricks", 1, 1, 0, 0,
- dal::bit_vector bv = in.pop().to_bit_vector();
- for (dal::bv_visitor ii(bv); !ii.finished(); ++ii)
- md->enable_brick(ii);
- );
-
- /*@SET ('disable variable', @str varname)
- Disable a variable for a solve (and its attached multipliers).
- The next solve will operate only on
- the remaining variables. This allows to solve separately different
- parts of a model. If there is a strong coupling of the variables,
- a fixed point strategy can the be used. @*/
- sub_command
- ("disable variable", 1, 1, 0, 0,
- std::string varname = in.pop().to_string();
- md->disable_variable(varname);
- );
-
-
- /*@SET ('enable variable', @str varname)
- Enable a disabled variable (and its attached multipliers). @*/
- sub_command
- ("enable variable", 1, 1, 0, 0,
- std::string varname = in.pop().to_string();
- md->enable_variable(varname);
- );
-
-
- /*@SET ('first iter')
- To be executed before the first iteration of a time integration
- scheme. @*/
- sub_command
- ("first iter", 0, 0, 0, 0,
- md->first_iter();
- );
-
-
- /*@SET ('next iter')
- To be executed at the end of each iteration of a time
- integration scheme. @*/
- sub_command
- ("next iter", 0, 0, 0, 0,
- md->next_iter();
- );
-
-
- /*@SET ind = ('add basic contact brick', @str varname_u, @str
multname_n[, @str multname_t], @str dataname_r, @tspmat BN[, @tspmat BT, @str
dataname_friction_coeff][, @str dataname_gap[, @str dataname_alpha[, @int
augmented_version[, @str dataname_gamma, @str dataname_wt]]])
-
- Add a contact with or without friction brick to the model.
- If U is the vector
- of degrees of freedom on which the unilateral constraint is applied,
- the matrix `BN` have to be such that this constraint is defined by
- :math:`B_N U \le 0`. A friction condition can be considered by adding
- the three parameters `multname_t`, `BT` and `dataname_friction_coeff`.
- In this case, the tangential displacement is :math:`B_T U` and
- the matrix `BT` should have as many rows as `BN` multiplied by
- :math:`d-1` where :math:`d` is the domain dimension.
- In this case also, `dataname_friction_coeff` is a data which represents
- the coefficient of friction. It can be a scalar or a vector representing a
- value on each contact condition. The unilateral constraint is prescribed
- thank to a multiplier
- `multname_n` whose dimension should be equal to the number of rows of
- `BN`. If a friction condition is added, it is prescribed with a
- multiplier `multname_t` whose dimension should be equal to the number
- of rows of `BT`. The augmentation parameter `r` should be chosen in
- a range of
- acceptabe values (see Getfem user documentation). `dataname_gap` is an
- optional parameter representing the initial gap. It can be a single value
- or a vector of value. `dataname_alpha` is an optional homogenization
- parameter for the augmentation parameter
- (see Getfem user documentation). The parameter `augmented_version`
- indicates the augmentation strategy : 1 for the non-symmetric
- Alart-Curnier augmented Lagrangian, 2 for the symmetric one (except for
- the coupling between contact and Coulomb friction), 3 for the
- unsymmetric method with augmented multipliers, 4 for the unsymmetric
- method with augmented multipliers and De Saxce projection. @*/
- sub_command
- ("add basic contact brick", 4, 12, 0, 1,
-
- bool friction = false;
-
- std::string varname_u = in.pop().to_string();
- std::string multname_n = in.pop().to_string();
- std::string dataname_r = in.pop().to_string();
- std::string multname_t; std::string friction_coeff;
-
- mexarg_in argin = in.pop();
- if (argin.is_string()) {
- friction = true;
- multname_t = dataname_r;
- dataname_r = argin.to_string();
- argin = in.pop();
- }
-
- std::shared_ptr<gsparse> BN = argin.to_sparse();
- if (BN->is_complex()) THROW_BADARG("Complex matrix not allowed");
- std::shared_ptr<gsparse> BT;
- if (friction) {
- BT = in.pop().to_sparse();
- if (BT->is_complex()) THROW_BADARG("Complex matrix not allowed");
- friction_coeff = in.pop().to_string();
- }
-
- std::string dataname_gap;
- dataname_gap = in.pop().to_string();
- std::string dataname_alpha;
- if (in.remaining()) dataname_alpha = in.pop().to_string();
- int augmented_version = 1;
- if (in.remaining()) augmented_version = in.pop().to_integer(1,4);
-
- std::string dataname_gamma;
- std::string dataname_wt;
- if (in.remaining()) {
- GMM_ASSERT1(friction,
- "gamma and wt parameters are for the frictional brick
only");
- dataname_gamma = in.pop().to_string();
- dataname_wt = in.pop().to_string();
- }
-
- getfem::CONTACT_B_MATRIX BBN;
- getfem::CONTACT_B_MATRIX BBT;
- if (BN->storage()==gsparse::CSCMAT) {
- gmm::resize(BBN, gmm::mat_nrows(BN->real_csc()),
- gmm::mat_ncols(BN->real_csc()));
- gmm::copy(BN->real_csc(), BBN);
- }
- else if (BN->storage()==gsparse::WSCMAT) {
- gmm::resize(BBN, gmm::mat_nrows(BN->real_wsc()),
- gmm::mat_ncols(BN->real_wsc()));
- gmm::copy(BN->real_wsc(), BBN);
- }
- else THROW_BADARG("Matrix BN should be a sparse matrix");
-
- if (friction) {
- if (BT->storage()==gsparse::CSCMAT) {
- gmm::resize(BBT, gmm::mat_nrows(BT->real_csc()),
- gmm::mat_ncols(BT->real_csc()));
- gmm::copy(BT->real_csc(), BBT);
- }
- else if (BT->storage()==gsparse::WSCMAT) {
- gmm::resize(BBT, gmm::mat_nrows(BT->real_wsc()),
- gmm::mat_ncols(BT->real_wsc()));
- gmm::copy(BT->real_wsc(), BBT);
- }
- else THROW_BADARG("Matrix BT should be a sparse matrix");
- }
-
- size_type ind;
- if (friction) {
- ind = getfem::add_basic_contact_brick
- (*md, varname_u, multname_n, multname_t, dataname_r, BBN, BBT,
- friction_coeff, dataname_gap, dataname_alpha, augmented_version,
- false, "", dataname_gamma, dataname_wt);
- } else {
- ind = getfem::add_basic_contact_brick
- (*md, varname_u, multname_n, dataname_r, BBN, dataname_gap,
- dataname_alpha, augmented_version);
- }
-
- out.pop().from_integer(int(ind + config::base_index()));
- );
-
-
- /*@SET ind = ('add basic contact brick two deformable bodies', @str
varname_u1, @str varname_u2, @str multname_n, @str dataname_r, @tspmat BN1,
@tspmat BN2[, @str dataname_gap[, @str dataname_alpha[, @int
augmented_version]]])
-
- Add a frictionless contact condition to the model between two deformable
- bodies. If U1, U2 are the vector
- of degrees of freedom on which the unilateral constraint is applied,
- the matrices `BN1` and `BN2` have to be such that this condition
- is defined by
- $B_{N1} U_1 B_{N2} U_2 + \le gap$. The constraint is prescribed thank
- to a multiplier
- `multname_n` whose dimension should be equal to the number of lines of
- `BN`. The augmentation parameter `r` should be chosen in a range of
- acceptabe values (see Getfem user documentation). `dataname_gap` is an
- optional parameter representing the initial gap. It can be a single value
- or a vector of value. `dataname_alpha` is an optional homogenization
- parameter for the augmentation parameter
- (see Getfem user documentation). The parameter `aug_version` indicates
- the augmentation strategy : 1 for the non-symmetric Alart-Curnier
- augmented Lagrangian, 2 for the symmetric one, 3 for the unsymmetric
- method with augmented multiplier. @*/
- sub_command
- ("add basic contact brick two deformable bodies", 6, 9, 0, 1,
-
- std::string varname_u1 = in.pop().to_string();
- std::string varname_u2 = in.pop().to_string();
- std::string multname_n = in.pop().to_string();
- std::string dataname_r = in.pop().to_string();
-
- std::shared_ptr<gsparse> BN1 = in.pop().to_sparse();
- std::shared_ptr<gsparse> BN2 = in.pop().to_sparse();
- if (BN1->is_complex()) THROW_BADARG("Complex matrix not allowed");
- if (BN2->is_complex()) THROW_BADARG("Complex matrix not allowed");
-
- std::string dataname_gap;
- if (in.remaining()) dataname_gap = in.pop().to_string();
- std::string dataname_alpha;
- if (in.remaining()) dataname_alpha = in.pop().to_string();
- int augmented_version = 1;
- if (in.remaining()) augmented_version = in.pop().to_integer(1,4);
-
- getfem::CONTACT_B_MATRIX BBN1; getfem::CONTACT_B_MATRIX BBN2;
- if (BN1->storage()==gsparse::CSCMAT) {
- gmm::resize(BBN1, gmm::mat_nrows(BN1->real_csc()),
- gmm::mat_ncols(BN1->real_csc()));
- gmm::copy(BN1->real_csc(), BBN1);
- }
- else if (BN1->storage()==gsparse::WSCMAT) {
- gmm::resize(BBN1, gmm::mat_nrows(BN1->real_wsc()),
- gmm::mat_ncols(BN1->real_wsc()));
- gmm::copy(BN1->real_wsc(), BBN1);
- }
- else THROW_BADARG("Matrix BN1 should be a sparse matrix");
-
- if (BN2->storage()==gsparse::CSCMAT) {
- gmm::resize(BBN2, gmm::mat_nrows(BN2->real_csc()),
- gmm::mat_ncols(BN2->real_csc()));
- gmm::copy(BN2->real_csc(), BBN2);
- }
- else if (BN2->storage()==gsparse::WSCMAT) {
- gmm::resize(BBN2, gmm::mat_nrows(BN2->real_wsc()),
- gmm::mat_ncols(BN2->real_wsc()));
- gmm::copy(BN2->real_wsc(), BBN2);
- }
- else THROW_BADARG("Matrix BN2 should be a sparse matrix");
-
- size_type ind;
- ind = getfem::add_basic_contact_brick_two_deformable_bodies
- (*md, varname_u1, varname_u2, multname_n, dataname_r, BBN1, BBN2,
- dataname_gap, dataname_alpha, augmented_version);
-
- out.pop().from_integer(int(ind + config::base_index()));
- );
-
- /*@SET ('contact brick set BN', @int indbrick, @tspmat BN)
- Can be used to set the BN matrix of a basic contact/friction brick. @*/
- sub_command
- ("contact brick set BN", 2, 2, 0, 0,
- size_type ind = in.pop().to_integer() - config::base_index();
- std::shared_ptr<gsparse> B = in.pop().to_sparse();
-
- if (B->is_complex())
- THROW_BADARG("BN should be a real matrix");
-
- if (B->storage()==gsparse::CSCMAT)
- gmm::copy(B->real_csc(),
- getfem::contact_brick_set_BN(*md, ind));
- else if (B->storage()==gsparse::WSCMAT)
- gmm::copy(B->real_wsc(),
- getfem::contact_brick_set_BN(*md, ind));
- else
- THROW_BADARG("BN should be a sparse matrix");
- );
-
-
- /*@SET ('contact brick set BT', @int indbrick, @tspmat BT)
- Can be used to set the BT matrix of a basic contact with
- friction brick. @*/
- sub_command
- ("contact brick set BT", 2, 2, 0, 0,
- size_type ind = in.pop().to_integer() - config::base_index();
- std::shared_ptr<gsparse> B = in.pop().to_sparse();
-
- if (B->is_complex())
- THROW_BADARG("BT should be a real matrix");
-
- if (B->storage()==gsparse::CSCMAT)
- gmm::copy(B->real_csc(), getfem::contact_brick_set_BT(*md, ind));
- else if (B->storage()==gsparse::WSCMAT)
- gmm::copy(B->real_wsc(), getfem::contact_brick_set_BT(*md, ind));
- else
- THROW_BADARG("BT should be a sparse matrix");
- );
-
-
- // CONTACT WITH RIGID OBSTACLE
-
-
- /*@SET ind = ('add nodal contact with rigid obstacle brick', @tmim mim,
@str varname_u, @str multname_n[, @str multname_t], @str dataname_r[, @str
dataname_friction_coeff], @int region, @str obstacle[, @int augmented_version])
-
- Add a contact with or without friction condition with a rigid obstacle
- to the model. The condition is applied on the variable `varname_u`
- on the boundary corresponding to `region`. The rigid obstacle should
- be described with the string `obstacle` being a signed distance to
- the obstacle. This string should be an expression where the coordinates
- are 'x', 'y' in 2D and 'x', 'y', 'z' in 3D. For instance, if the rigid
- obstacle correspond to :math:`z \le 0`, the corresponding signed distance
- will be simply "z". `multname_n` should be a fixed size variable whose size
- is the number of degrees of freedom on boundary `region`. It represents the
- contact equivalent nodal forces. In order to add a friction condition
- one has to add the `multname_t` and `dataname_friction_coeff` parameters.
- `multname_t` should be a fixed size variable whose size is
- the number of degrees of freedom on boundary `region` multiplied by
- :math:`d-1` where :math:`d` is the domain dimension. It represents
- the friction equivalent nodal forces.
- The augmentation parameter `r` should be chosen in a
- range of acceptabe values (close to the Young modulus of the elastic
- body, see Getfem user documentation). `dataname_friction_coeff` is
- the friction coefficient. It could be a scalar or a vector of values
- representing the friction coefficient on each contact node.
- The parameter `augmented_version`
- indicates the augmentation strategy : 1 for the non-symmetric
- Alart-Curnier augmented Lagrangian, 2 for the symmetric one (except for
- the coupling between contact and Coulomb friction),
- 3 for the new unsymmetric method.
- Basically, this brick compute the matrix BN
- and the vectors gap and alpha and calls the basic contact brick. @*/
- sub_command
- ("add nodal contact with rigid obstacle brick", 6, 9, 0, 1,
-
- bool friction = false;
-
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname_u = in.pop().to_string();
- std::string multname_n = in.pop().to_string();
- std::string dataname_r = in.pop().to_string();
- std::string multname_t; std::string dataname_fr;
-
- mexarg_in argin = in.pop();
- if (argin.is_string()) {
- friction = true;
- multname_t = dataname_r;
- dataname_r = argin.to_string();
- dataname_fr = in.pop().to_string();
- argin = in.pop();
- }
-
- size_type region = argin.to_integer();
- std::string obstacle = in.pop().to_string();
- int augmented_version = 1;
- if (in.remaining()) augmented_version = in.pop().to_integer(1,4);
-
- size_type ind;
-
- if (friction)
- ind = getfem::add_nodal_contact_with_rigid_obstacle_brick
- (*md, *mim, varname_u, multname_n,
- multname_t, dataname_r, dataname_fr, region, obstacle,
- augmented_version);
- else
- ind = getfem::add_nodal_contact_with_rigid_obstacle_brick
- (*md, *mim, varname_u, multname_n,
- dataname_r, region, obstacle, augmented_version);
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind + config::base_index()));
- );
-
- /*@SET ind = ('add contact with rigid obstacle brick', @tmim mim, @str
varname_u, @str multname_n[, @str multname_t], @str dataname_r[, @str
dataname_friction_coeff], @int region, @str obstacle[, @int augmented_version])
- DEPRECATED FUNCTION. Use 'add nodal contact with rigid obstacle brick'
instead.@*/
- sub_command
- ("add contact with rigid obstacle brick", 6, 9, 0, 1,
- infomsg() << "WARNING : gf_mesh_fem_get('add contact with rigid
obstacle "
- << "brick', ...) is a deprecated command.\n Use
gf_mesh_fem_get("
- << "'add nodal contact with rigid obstacle brick', ...) instead." <<
endl;
- SUBC_TAB::iterator it = subc_tab.find("add nodal contact with rigid
obstacle brick");
- if (it != subc_tab.end())
- it->second->run(in, out, md);
- );
-
- /*@SET ind = ('add integral contact with rigid obstacle brick', @tmim
mim, @str varname_u, @str multname, @str dataname_obstacle, @str dataname_r [,
@str dataname_friction_coeff], @int region [, @int option [, @str
dataname_alpha [, @str dataname_wt [, @str dataname_gamma [, @str
dataname_vt]]]]])
-
- Add a contact with or without friction condition with a rigid obstacle
- to the model. This brick adds a contact which is defined
- in an integral way. It is the direct approximation of an augmented
- Lagrangian formulation (see Getfem user documentation) defined at the
- continuous level. The advantage is a better scalability: the number of
- Newton iterations should be more or less independent of the mesh size.
- The contact condition is applied on the variable `varname_u`
- on the boundary corresponding to `region`. The rigid obstacle should
- be described with the data `dataname_obstacle` being a signed distance to
- the obstacle (interpolated on a finite element method).
- `multname` should be a fem variable representing the contact stress.
- An inf-sup condition beetween `multname` and `varname_u` is required.
- The augmentation parameter `dataname_r` should be chosen in a
- range of acceptabe values.
- The optional parameter `dataname_friction_coeff` is the friction
- coefficient which could be constant or defined on a finite element method.
- Possible values for `option` is 1 for the non-symmetric Alart-Curnier
- augmented Lagrangian method, 2 for the symmetric one, 3 for the
- non-symmetric Alart-Curnier method with an additional augmentation
- and 4 for a new unsymmetric method. The default value is 1.
- In case of contact with friction, `dataname_alpha` and `dataname_wt`
- are optional parameters to solve evolutionary friction problems.
- `dataname_gamma` and `dataname_vt` represent optional data for adding
- a parameter-dependent sliding velocity to the friction condition.
- @*/
- sub_command
- ("add integral contact with rigid obstacle brick", 6, 12, 0, 1,
-
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname_u = in.pop().to_string();
- std::string multname = in.pop().to_string();
- std::string dataname_obs = in.pop().to_string();
- std::string dataname_r = in.pop().to_string();
-
- size_type ind;
- int option = 1;
- mexarg_in argin = in.pop();
- if (argin.is_integer()) { // without friction
- size_type region = argin.to_integer();
- if (in.remaining()) option = in.pop().to_integer();
-
- ind = getfem::add_integral_contact_with_rigid_obstacle_brick
- (*md, *mim, varname_u, multname,
- dataname_obs, dataname_r, region, option);
- } else { // with friction
- std::string dataname_coeff = argin.to_string();
- size_type region = in.pop().to_integer();
- if (in.remaining()) option = in.pop().to_integer();
- std::string dataname_alpha = "";
- if (in.remaining()) dataname_alpha = in.pop().to_string();
- std::string dataname_wt = "";
- if (in.remaining()) dataname_wt = in.pop().to_string();
- std::string dataname_gamma = "";
- if (in.remaining()) dataname_gamma = in.pop().to_string();
- std::string dataname_vt = "";
- if (in.remaining()) dataname_vt = in.pop().to_string();
-
- ind = getfem::add_integral_contact_with_rigid_obstacle_brick
- (*md, *mim, varname_u, multname,
- dataname_obs, dataname_r, dataname_coeff, region, option,
- dataname_alpha, dataname_wt, dataname_gamma, dataname_vt);
- }
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind + config::base_index()));
- );
-
- /*@SET ind = ('add penalized contact with rigid obstacle brick', @tmim
mim, @str varname_u, @str dataname_obstacle, @str dataname_r [, @str
dataname_coeff], @int region [, @int option, @str dataname_lambda, [, @str
dataname_alpha [, @str dataname_wt]]])
-
- Add a penalized contact with or without friction condition with a
- rigid obstacle to the model.
- The condition is applied on the variable `varname_u`
- on the boundary corresponding to `region`. The rigid obstacle should
- be described with the data `dataname_obstacle` being a signed distance to
- the obstacle (interpolated on a finite element method).
- The penalization parameter `dataname_r` should be chosen
- large enough to prescribe approximate non-penetration and friction
- conditions but not too large not to deteriorate too much the
- conditionning of the tangent system.
- `dataname_lambda` is an optional parameter used if option
- is 2. In that case, the penalization term is shifted by lambda (this
- allows the use of an Uzawa algorithm on the corresponding augmented
- Lagrangian formulation)
- @*/
- sub_command
- ("add penalized contact with rigid obstacle brick", 5, 10, 0, 1,
-
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname_u = in.pop().to_string();
- std::string dataname_obs = in.pop().to_string();
- std::string dataname_r = in.pop().to_string();
-
- size_type ind;
- int option = 1;
- mexarg_in argin = in.pop();
- if (argin.is_integer()) { // without friction
- size_type region = argin.to_integer();
- if (in.remaining()) option = in.pop().to_integer();
- std::string dataname_n = "";
- if (in.remaining()) dataname_n = in.pop().to_string();
-
- ind = getfem::add_penalized_contact_with_rigid_obstacle_brick
- (*md, *mim, varname_u,
- dataname_obs, dataname_r, region, option, dataname_n);
- } else { // with friction
- std::string dataname_coeff = argin.to_string();
- size_type region = in.pop().to_integer();
- if (in.remaining()) option = in.pop().to_integer();
- std::string dataname_lambda = "";
- if (in.remaining()) dataname_lambda = in.pop().to_string();
- std::string dataname_alpha = "";
- if (in.remaining()) dataname_alpha = in.pop().to_string();
- std::string dataname_wt = "";
- if (in.remaining()) dataname_wt = in.pop().to_string();
-
- ind = getfem::add_penalized_contact_with_rigid_obstacle_brick
- (*md, *mim, varname_u,
- dataname_obs, dataname_r, dataname_coeff, region, option,
- dataname_lambda, dataname_alpha, dataname_wt);
- }
-
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind + config::base_index()));
- );
-
-
- /*@SET ind = ('add Nitsche contact with rigid obstacle brick', @tmim mim,
@str varname, @str Neumannterm, @str dataname_obstacle, @str gamma0name, @int
region[, @scalar theta[, @str dataname_friction_coeff[, @str dataname_alpha,
@str dataname_wt]]])
- Adds a contact condition with or without Coulomb friction on the variable
- `varname` and the mesh boundary `region`. The contact condition
- is prescribed with Nitsche's method. The rigid obstacle should
- be described with the data `dataname_obstacle` being a signed distance to
- the obstacle (interpolated on a finite element method).
- `gamma0name` is the Nitsche's method parameter.
- `theta` is a scalar value which can be
- positive or negative. `theta = 1` corresponds to the standard symmetric
- method which is conditionally coercive for `gamma0` small.
- `theta = -1` corresponds to the skew-symmetric method which is
- inconditionally coercive. `theta = 0` is the simplest method
- for which the second derivative of the Neumann term is not necessary.
- The optional parameter `dataname_friction_coeff` is the friction
- coefficient which could be constant or defined on a finite element
- method.
- CAUTION: This brick has to be added in the model after all the bricks
- corresponding to partial differential terms having a Neumann term.
- Moreover, This brick can only be applied to bricks declaring their
- Neumann terms. Returns the brick index in the model.
- @*/
- sub_command
- ("add Nitsche contact with rigid obstacle brick", 6, 10, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname = in.pop().to_string();
- std::string Neumannterm = in.pop().to_string();
- std::string dataname_obs = in.pop().to_string();
- std::string gamma0name = in.pop().to_string();
- size_type region = in.pop().to_integer();
-
- scalar_type theta = scalar_type(1);
- std::string dataname_fr;
- if (in.remaining()) {
- mexarg_in argin = in.pop();
- if (argin.is_string())
- dataname_fr = argin.to_string();
- else
- theta = argin.to_scalar();
- }
- if (in.remaining()) dataname_fr = in.pop().to_string();
- std::string dataname_alpha;
- if (in.remaining()) dataname_alpha = in.pop().to_string();
- std::string dataname_wt;
- if (in.remaining()) dataname_wt = in.pop().to_string();
-
- size_type ind = config::base_index();
- ind += getfem::add_Nitsche_contact_with_rigid_obstacle_brick
- (*md, *mim, varname, Neumannterm, dataname_obs,
- gamma0name, theta,
- dataname_fr, dataname_alpha, dataname_wt, region);
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
-#ifdef EXPERIMENTAL_PURPOSE_ONLY
-
- /*@SET ind = ('add Nitsche midpoint contact with rigid obstacle brick',
@tmim mim, @str varname, @str Neumannterm, @str Neumannterm_wt, @str
dataname_obstacle, @str gamma0name, @int region, @scalar theta, @str
dataname_friction_coeff, @str dataname_alpha, @str dataname_wt)
- EXPERIMENTAL BRICK: for midpoint scheme only !!
- Adds a contact condition with or without Coulomb friction on the variable
- `varname` and the mesh boundary `region`. The contact condition
- is prescribed with Nitsche's method. The rigid obstacle should
- be described with the data `dataname_obstacle` being a signed distance to
- the obstacle (interpolated on a finite element method).
- `gamma0name` is the Nitsche's method parameter.
- `theta` is a scalar value which can be
- positive or negative. `theta = 1` corresponds to the standard symmetric
- method which is conditionally coercive for `gamma0` small.
- `theta = -1` corresponds to the skew-symmetric method which is
- inconditionally coercive. `theta = 0` is the simplest method
- for which the second derivative of the Neumann term is not necessary.
- The optional parameter `dataname_friction_coeff` is the friction
- coefficient which could be constant or defined on a finite element
- method.
- Returns the brick index in the model.
-
- @*/
- sub_command
- ("add Nitsche midpoint contact with rigid obstacle brick", 11, 11, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname = in.pop().to_string();
- std::string Neumannterm = in.pop().to_string();
- std::string Neumannterm_wt = in.pop().to_string();
- std::string dataname_obs = in.pop().to_string();
- std::string gamma0name = in.pop().to_string();
- size_type region = in.pop().to_integer();
-
- scalar_type theta = scalar_type(1);
- std::string dataname_fr;
- mexarg_in argin = in.pop();
- if (argin.is_string())
- dataname_fr = argin.to_string();
- else
- theta = argin.to_scalar();
- dataname_fr = in.pop().to_string();
- std::string dataname_alpha = in.pop().to_string();
- std::string dataname_wt = in.pop().to_string();
-
- size_type ind = config::base_index();
- ind +=
getfem::add_Nitsche_contact_with_rigid_obstacle_brick_modified_midpoint
- (*md, *mim, varname, Neumannterm, Neumannterm_wt,
- dataname_obs,
- gamma0name, theta,
- dataname_fr, dataname_alpha, dataname_wt, region);
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
-#endif
-
-#if (0) // Deprecated brick : uses the old Neumann terms
-
- /*@SET ind = ('add Nitsche fictitious domain contact brick', @tmim mim,
@str varname1, @str varname2, @str dataname_d1, @str dataname_d2, @str
gamma0name [, @scalar theta[, @str dataname_friction_coeff[, @str
dataname_alpha, @str dataname_wt1,@str dataname_wt2]]])
- Adds a contact condition with or without Coulomb friction between
- two bodies in a fictitious domain. The contact condition is applied on
- the variable `varname_u1` corresponds with the first and slave body
- with Nitsche's method and on the variable `varname_u2` corresponds
- with the second and master body with Nitsche's method.
- The contact condition is evaluated on the fictitious slave boundary.
- The first body should be described by the level-set `dataname_d1`
- and the second body should be described by the level-set `dataname_d2`.
- `gamma0name` is the Nitsche's method parameter.
- `theta` is a scalar value which can be positive or negative.
- `theta = 1` corresponds to the standard symmetric method which is
- conditionally coercive for `gamma0` small.
- `theta = -1` corresponds to the skew-symmetric method which is
inconditionally coercive.
- `theta = 0` is the simplest method for which the second derivative of
- the Neumann term is not necessary. The optional parameter
`dataname_friction_coeff`
- is the friction coefficient which could be constant or defined on a
finite element method.
- CAUTION: This brick has to be added in the model after all the bricks
- corresponding to partial differential terms having a Neumann term.
- Moreover, This brick can only be applied to bricks declaring their
- Neumann terms. Returns the brick index in the model.
- @*/
- sub_command
- ("add Nitsche fictitious domain contact brick", 6, 11, 0, 1,
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname1 = in.pop().to_string();
- std::string varname2 = in.pop().to_string();
- std::string dataname_d1 = in.pop().to_string();
- std::string dataname_d2 = in.pop().to_string();
- std::string gamma0name = in.pop().to_string();
-
- scalar_type theta = scalar_type(1);
- std::string dataname_fr;
- if (in.remaining()) {
- mexarg_in argin = in.pop();
- if (argin.is_string())
- dataname_fr = argin.to_string();
- else
- theta = argin.to_scalar();
- }
- if (in.remaining()) dataname_fr = in.pop().to_string();
- std::string dataname_alpha;
- if (in.remaining()) dataname_alpha = in.pop().to_string();
- std::string dataname_wt1;
- if (in.remaining()) dataname_wt1 = in.pop().to_string();
- std::string dataname_wt2;
- if (in.remaining()) dataname_wt2 = in.pop().to_string();
-
- size_type ind = config::base_index();
- ind += getfem::add_Nitsche_fictitious_domain_contact_brick
- (*md, *mim, varname1, varname2, dataname_d1,
- dataname_d2, gamma0name, theta,
- dataname_fr, dataname_alpha, dataname_wt1, dataname_wt2);
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind));
- );
-
-#endif
-
- // CONTACT BETWEEN NON-MATCHING MESHES
-
-
- /*@SET ind = ('add nodal contact between nonmatching meshes brick', @tmim
mim1[, @tmim mim2], @str varname_u1[, @str varname_u2], @str multname_n[, @str
multname_t], @str dataname_r[, @str dataname_fr], @int rg1, @int rg2[, @int
slave1, @int slave2, @int augmented_version])
-
- Add a contact with or without friction condition between two faces of
- one or two elastic bodies. The condition is applied on the variable
- `varname_u1` or the variables `varname_u1` and `varname_u2` depending
- if a single or two distinct displacement fields are given. Integers
- `rg1` and `rg2` represent the regions expected to come in contact with
- each other. In the single displacement variable case the regions defined
- in both `rg1` and `rg2` refer to the variable `varname_u1`. In the case
- of two displacement variables, `rg1` refers to `varname_u1` and `rg2`
- refers to `varname_u2`. `multname_n` should be a fixed size variable
- whose size is the number of degrees of freedom on those regions among
- the ones defined in `rg1` and `rg2` which are characterized as "slaves".
- It represents the contact equivalent nodal normal forces. `multname_t`
- should be a fixed size variable whose size corresponds to the size of
- `multname_n` multiplied by qdim - 1 . It represents the contact
- equivalent nodal tangent (frictional) forces. The augmentation parameter
- `r` should be chosen in a range of acceptabe values (close to the Young
- modulus of the elastic body, see Getfem user documentation). The
- friction coefficient stored in the parameter `fr` is either a single
- value or a vector of the same size as `multname_n`. The optional
- parameters `slave1` and `slave2` declare if the regions defined in `rg1`
- and `rg2` are correspondingly considered as "slaves". By default
- `slave1` is true and `slave2` is false, i.e. `rg1` contains the slave
- surfaces, while 'rg2' the master surfaces. Preferrably only one of
- `slave1` and `slave2` is set to true. The parameter `augmented_version`
- indicates the augmentation strategy : 1 for the non-symmetric
- Alart-Curnier augmented Lagrangian, 2 for the symmetric one (except for
- the coupling between contact and Coulomb friction),
- 3 for the new unsymmetric method.
- Basically, this brick computes the matrices BN and BT and the vectors
- gap and alpha and calls the basic contact brick. @*/
- sub_command
- ("add nodal contact between nonmatching meshes brick", 6, 13, 0, 1,
-
- bool two_variables = true;
- bool friction = false;
-
- getfem::mesh_im *mim1 = 0;
- getfem::mesh_im *mim2 = 0;
- std::string varname_u1;
- std::string varname_u2;
- bool slave1=true; bool slave2=false;
- int augmented_version = 1;
-
- mim1 = to_meshim_object(in.pop());
- mexarg_in argin = in.pop();
- if (argin.is_string()) {
- two_variables = false;
- mim2 = mim1;
- varname_u1 = argin.to_string();
- varname_u2 = varname_u1;
- } else {
- mim2 = to_meshim_object(argin);
- varname_u1 = in.pop().to_string();
- varname_u2 = in.pop().to_string();
- cout << "ok here" << endl;
- }
- std::string multname_n = in.pop().to_string();
- std::string multname_t;
- std::string dataname_r = in.pop().to_string();
- std::string dataname_fr;
- argin = in.pop();
- if (!argin.is_integer()) {
- friction = true;
- multname_t = dataname_r;
- dataname_r = in.pop().to_string();
- dataname_fr = in.pop().to_string();
- argin = in.pop();
- }
- std::vector<size_type> vrg1(1,argin.to_integer());
- std::vector<size_type> vrg2(1,in.pop().to_integer());
- if (in.remaining()) slave1 = (in.pop().to_integer(0,1)) != 0;
- if (in.remaining()) slave2 = (in.pop().to_integer(0,1)) != 0;
- if (in.remaining()) augmented_version = in.pop().to_integer(1,4);
-
- size_type ind;
- if (!friction)
- ind = getfem::add_nodal_contact_between_nonmatching_meshes_brick
- (*md, *mim1, *mim2,
- varname_u1, varname_u2, multname_n, dataname_r,
- vrg1, vrg2, slave1, slave2, augmented_version);
- else
- ind = getfem::add_nodal_contact_between_nonmatching_meshes_brick
- (*md, *mim1, *mim2,
- varname_u1, varname_u2, multname_n, multname_t,
- dataname_r, dataname_fr,
- vrg1, vrg2, slave1, slave2, augmented_version);
- workspace().set_dependence(md, mim1);
- // if (two_variables)
- // workspace().set_dependence(md, mim2);
- out.pop().from_integer(int(ind + config::base_index()));
- );
-
- /*@SET ind = ('add nonmatching meshes contact brick', @tmim mim1[, @tmim
mim2], @str varname_u1[, @str varname_u2], @str multname_n[, @str multname_t],
@str dataname_r[, @str dataname_fr], @int rg1, @int rg2[, @int slave1, @int
slave2, @int augmented_version])
- DEPRECATED FUNCTION. Use 'add nodal contact between nonmatching meshes
brick' instead.@*/
- sub_command
- ("add nonmatching meshes contact brick", 6, 13, 0, 1,
- infomsg() << "WARNING : gf_mesh_fem_get('add nonmatching meshes "
- << "contact brick', ...) is a deprecated command.\n Use "
- << "gf_mesh_fem_get('add nodal contact between nonmatching meshes "
- << "brick', ...) instead." << endl;
- SUBC_TAB::iterator it = subc_tab.find("add nodal contact between
nonmatching meshes brick");
- if (it != subc_tab.end())
- it->second->run(in, out, md);
- );
-
- /*@SET ind = ('add integral contact between nonmatching meshes brick',
@tmim mim, @str varname_u1, @str varname_u2, @str multname, @str dataname_r [,
@str dataname_friction_coeff], @int region1, @int region2 [, @int option [,
@str dataname_alpha [, @str dataname_wt1 , @str dataname_wt2]]])
-
- Add a contact with or without friction condition between nonmatching
- meshes to the model. This brick adds a contact which is defined
- in an integral way. It is the direct approximation of an augmented
- agrangian formulation (see Getfem user documentation) defined at the
- continuous level. The advantage should be a better scalability:
- the number of Newton iterations should be more or less independent
- of the mesh size.
- The condition is applied on the variables `varname_u1` and `varname_u2`
- on the boundaries corresponding to `region1` and `region2`.
- `multname` should be a fem variable representing the contact stress
- for the frictionless case and the contact and friction stress for the
- case with friction. An inf-sup condition between `multname` and
- `varname_u1` and `varname_u2` is required.
- The augmentation parameter `dataname_r` should be chosen in a
- range of acceptable values.
- The optional parameter `dataname_friction_coeff` is the friction
- coefficient which could be constant or defined on a finite element
- method on the same mesh as `varname_u1`.
- Possible values for `option` is 1 for the non-symmetric Alart-Curnier
- augmented Lagrangian method, 2 for the symmetric one, 3 for the
- non-symmetric Alart-Curnier method with an additional augmentation
- and 4 for a new unsymmetric method. The default value is 1.
- In case of contact with friction, `dataname_alpha`, `dataname_wt1` and
- `dataname_wt2` are optional parameters to solve evolutionary friction
- problems.
- @*/
- sub_command
- ("add integral contact between nonmatching meshes brick", 7, 12, 0, 1,
-
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname_u1 = in.pop().to_string();
- std::string varname_u2 = in.pop().to_string();
- std::string multname = in.pop().to_string();
- std::string dataname_r = in.pop().to_string();
-
- size_type ind;
- int option = 1;
- mexarg_in argin = in.pop();
- if (argin.is_integer()) { // without friction
- size_type region1 = argin.to_integer();
- size_type region2 = in.pop().to_integer();
- if (in.remaining()) option = in.pop().to_integer();
-
- ind = getfem::add_integral_contact_between_nonmatching_meshes_brick
- (*md, *mim, varname_u1, varname_u2,
- multname, dataname_r, region1, region2, option);
- } else { // with friction
- std::string dataname_coeff = argin.to_string();
- size_type region1 = in.pop().to_integer();
- size_type region2 = in.pop().to_integer();
- if (in.remaining()) option = in.pop().to_integer();
- std::string dataname_alpha = "";
- if (in.remaining()) dataname_alpha = in.pop().to_string();
- std::string dataname_wt1 = "";
- if (in.remaining()) dataname_wt1 = in.pop().to_string();
- std::string dataname_wt2 = "";
- if (in.remaining()) dataname_wt2 = in.pop().to_string();
-
- ind = getfem::add_integral_contact_between_nonmatching_meshes_brick
- (*md, *mim, varname_u1, varname_u2,
- multname, dataname_r, dataname_coeff, region1, region2,
- option, dataname_alpha, dataname_wt1, dataname_wt2);
- }
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind + config::base_index()));
- );
-
- /*@SET ind = ('add penalized contact between nonmatching meshes brick',
@tmim mim, @str varname_u1, @str varname_u2, @str dataname_r [, @str
dataname_coeff], @int region1, @int region2 [, @int option [, @str
dataname_lambda, [, @str dataname_alpha [, @str dataname_wt1, @str
dataname_wt2]]]])
-
- Add a penalized contact condition with or without friction between
- nonmatching meshes to the model.
- The condition is applied on the variables `varname_u1` and `varname_u2`
- on the boundaries corresponding to `region1` and `region2`.
- The penalization parameter `dataname_r` should be chosen
- large enough to prescribe approximate non-penetration and friction
- conditions but not too large not to deteriorate too much the
- conditionning of the tangent system.
- The optional parameter `dataname_friction_coeff` is the friction
- coefficient which could be constant or defined on a finite element
- method on the same mesh as `varname_u1`.
- `dataname_lambda` is an optional parameter used if option
- is 2. In that case, the penalization term is shifted by lambda (this
- allows the use of an Uzawa algorithm on the corresponding augmented
- Lagrangian formulation)
- In case of contact with friction, `dataname_alpha`, `dataname_wt1` and
- `dataname_wt2` are optional parameters to solve evolutionary friction
- problems.
- @*/
- sub_command
- ("add penalized contact between nonmatching meshes brick", 6, 12, 0, 1,
-
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- std::string varname_u1 = in.pop().to_string();
- std::string varname_u2 = in.pop().to_string();
- std::string dataname_r = in.pop().to_string();
-
- size_type ind;
- int option = 1;
- mexarg_in argin = in.pop();
- if (argin.is_integer()) { // without friction
- size_type region1 = argin.to_integer();
- size_type region2 = in.pop().to_integer();
- if (in.remaining()) option = in.pop().to_integer();
- std::string dataname_n = "";
- if (in.remaining()) dataname_n = in.pop().to_string();
-
- ind =
getfem::add_penalized_contact_between_nonmatching_meshes_brick
- (*md, *mim, varname_u1, varname_u2,
- dataname_r, region1, region2, option, dataname_n);
- } else { // with friction
- std::string dataname_coeff = argin.to_string();
- size_type region1 = in.pop().to_integer();
- size_type region2 = in.pop().to_integer();
- if (in.remaining()) option = in.pop().to_integer();
- std::string dataname_lambda = "";
- if (in.remaining()) dataname_lambda = in.pop().to_string();
- std::string dataname_alpha = "";
- if (in.remaining()) dataname_alpha = in.pop().to_string();
- std::string dataname_wt1 = "";
- if (in.remaining()) dataname_wt1 = in.pop().to_string();
- std::string dataname_wt2 = "";
- if (in.remaining()) dataname_wt2 = in.pop().to_string();
-
- ind =
getfem::add_penalized_contact_between_nonmatching_meshes_brick
- (*md, *mim, varname_u1, varname_u2,
- dataname_r, dataname_coeff, region1, region2, option,
- dataname_lambda, dataname_alpha, dataname_wt1,
dataname_wt2);
- }
-
- workspace().set_dependence(md, mim);
- out.pop().from_integer(int(ind + config::base_index()));
- );
-
- /*@SET ind = ('add integral large sliding contact brick raytracing', @str
dataname_r, @scalar release_distance, [, @str dataname_fr[, @str
dataname_alpha[, @int version]]])
- Adds a large sliding contact with friction brick to the model.
- This brick is able to deal with self-contact, contact between
- several deformable bodies and contact with rigid obstacles.
- It uses the high-level generic assembly. It adds to the model
- a raytracing_interpolate_transformation object.
- For each slave boundary a multiplier variable should be defined.
- The release distance should be determined with care
- (generally a few times a mean element size, and less than the
- thickness of the body). Initially, the brick is added with no contact
- boundaries. The contact boundaries and rigid bodies are added with
- special functions. `version` is 0 (the default value) for the
- non-symmetric version and 1 for the more symmetric one
- (not fully symmetric even without friction). @*/
-
- sub_command
- ("add integral large sliding contact brick raytracing", 2, 6, 0, 1,
-
- std::string dataname_r = in.pop().to_string();
- scalar_type d = in.pop().to_scalar();
- std::string dataname_fr = "0";
- if (in.remaining()) dataname_fr = in.pop().to_string();
- if (dataname_fr.size() == 0) dataname_fr = "0";
- std::string dataname_alpha = "1";
- if (in.remaining()) dataname_alpha = in.pop().to_string();
- if (dataname_alpha.size() == 0) dataname_alpha = "1";
- bool sym_v = false;
- if (in.remaining()) sym_v = (in.pop().to_integer() != 0);
- bool frame_indifferent = false;
- if (in.remaining()) frame_indifferent = (in.pop().to_integer() != 0);
-
- size_type ind
- = getfem::add_integral_large_sliding_contact_brick_raytracing
- (*md, dataname_r, d, dataname_fr, dataname_alpha, sym_v,
- frame_indifferent);
- out.pop().from_integer(int(ind + config::base_index()));
- );
-
- /*@SET ('add rigid obstacle to large sliding contact brick', @int
indbrick, @str expr, @int N)
- Adds a rigid obstacle to an existing large sliding contact
- with friction brick. `expr` is an expression using the high-level
- generic assembly language (where `x` is the current point n the mesh)
- which should be a signed distance to the obstacle.
- `N` is the mesh dimension. @*/
- sub_command
- ("add rigid obstacle to large sliding contact brick", 3, 3, 0, 0,
- size_type ind = in.pop().to_integer() - config::base_index();
- std::string expr = in.pop().to_string();
- size_type N = in.pop().to_integer();
-
- add_rigid_obstacle_to_large_sliding_contact_brick
- (*md, ind, expr, N);
- );
-
- /*@SET ('add master contact boundary to large sliding contact brick',
@int indbrick, @tmim mim, @int region, @str dispname[, @str wname])
- Adds a master contact boundary to an existing large sliding contact
- with friction brick. @*/
- sub_command
- ("add master contact boundary to large sliding contact brick", 4, 5, 0,0,
- size_type ind = in.pop().to_integer() - config::base_index();
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- size_type region = in.pop().to_integer();
- std::string dispname = in.pop().to_string();
- std::string wname;
- if (in.remaining()) wname = in.pop().to_string();
-
- add_contact_boundary_to_large_sliding_contact_brick
- (*md, ind, *mim, region, true, false,
- dispname, "", wname);
- );
-
-
- /*@SET ('add slave contact boundary to large sliding contact brick', @int
indbrick, @tmim mim, @int region, @str dispname, @str lambdaname[, @str wname])
- Adds a slave contact boundary to an existing large sliding contact
- with friction brick. @*/
- sub_command
- ("add slave contact boundary to large sliding contact brick", 5, 6, 0,0,
- size_type ind = in.pop().to_integer() - config::base_index();
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- size_type region = in.pop().to_integer();
- std::string dispname = in.pop().to_string();
- std::string lambda = in.pop().to_string();
- std::string wname;
- if (in.remaining()) wname = in.pop().to_string();
-
- add_contact_boundary_to_large_sliding_contact_brick
- (*md, ind, *mim, region, false, true,
- dispname, lambda, wname);
- );
-
- /*@SET ('add master slave contact boundary to large sliding contact
brick', @int indbrick, @tmim mim, @int region, @str dispname, @str lambdaname[,
@str wname])
- Adds a contact boundary to an existing large sliding contact
- with friction brick which is both master and slave
- (allowing the self-contact). @*/
- sub_command
- ("add master slave contact boundary to large sliding contact brick",
- 5, 6, 0, 0,
- size_type ind = in.pop().to_integer() - config::base_index();
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- size_type region = in.pop().to_integer();
- std::string dispname = in.pop().to_string();
- std::string lambda = in.pop().to_string();
- std::string wname;
- if (in.remaining()) wname = in.pop().to_string();
-
- add_contact_boundary_to_large_sliding_contact_brick
- (*md, ind, *mim, region, true, true,
- dispname, lambda, wname);
- );
-
- /*@SET ind = ('add Nitsche large sliding contact brick raytracing',
@bool unbiased_version, @str dataname_r, @scalar release_distance[, @str
dataname_fr[, @str dataname_alpha[, @int version]]])
- Adds a large sliding contact with friction brick to the model based on
the Nitsche's method.
- This brick is able to deal with self-contact, contact between
- several deformable bodies and contact with rigid obstacles.
- It uses the high-level generic assembly. It adds to the model
- a raytracing_interpolate_transformation object. "unbiased_version"
refers to the version of Nische's method to be used.
- (unbiased or biased one).
- For each slave boundary a material law should be defined as a function
of the dispacement variable on this boundary.
- The release distance should be determined with care
- (generally a few times a mean element size, and less than the
- thickness of the body). Initially, the brick is added with no contact
- boundaries. The contact boundaries and rigid bodies are added with
- special functions. `version` is 0 (the default value) for the
- non-symmetric version and 1 for the more symmetric one
- (not fully symmetric even without friction). @*/
-
- sub_command
- ("add Nitsche large sliding contact brick raytracing", 2, 6, 0, 1,
-
- bool unbiased=(in.pop().to_integer() != 0);
- std::string dataname_r = in.pop().to_string();
- scalar_type d = in.pop().to_scalar();
- std::string dataname_fr = "0";
- if (in.remaining()) dataname_fr = in.pop().to_string();
- if (dataname_fr.size() == 0) dataname_fr = "0";
- std::string dataname_alpha = "1";
- if (in.remaining()) dataname_alpha = in.pop().to_string();
- if (dataname_alpha.size() == 0) dataname_alpha = "1";
- bool sym_v = false;
- if (in.remaining()) sym_v = (in.pop().to_integer() != 0);
- bool frame_indifferent = false;
- if (in.remaining()) frame_indifferent = (in.pop().to_integer() != 0);
-
- size_type ind
- = getfem::add_Nitsche_large_sliding_contact_brick_raytracing
- (*md, unbiased, dataname_r, d, dataname_fr, dataname_alpha, sym_v,
- frame_indifferent);
- out.pop().from_integer(int(ind + config::base_index()));
- );
-
- /*@SET ('add rigid obstacle to Nitsche large sliding contact brick', @int
indbrick, @str expr, @int N)
- Adds a rigid obstacle to an existing large sliding contact
- with friction brick. `expr` is an expression using the high-level
- generic assembly language (where `x` is the current point n the mesh)
- which should be a signed distance to the obstacle.
- `N` is the mesh dimension. @*/
- sub_command
- ("add rigid obstacle to Nitsche large sliding contact brick", 3, 3, 0, 0,
- size_type ind = in.pop().to_integer() - config::base_index();
- std::string expr = in.pop().to_string();
- size_type N = in.pop().to_integer();
-
- add_rigid_obstacle_to_Nitsche_large_sliding_contact_brick
- (*md, ind, expr, N);
- );
-
- /*@SET ('add master contact boundary to biased Nitsche large sliding
contact brick', @int indbrick, @tmim mim, @int region, @str dispname[, @str
wname])
- Adds a master contact boundary to an existing biased Nitsche's large
sliding contact
- with friction brick. @*/
- sub_command
- ("add master contact boundary to biased Nitsche large sliding contact
brick", 4, 5, 0,0,
- size_type ind = in.pop().to_integer() - config::base_index();
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- size_type region = in.pop().to_integer();
- std::string dispname = in.pop().to_string();
- std::string wname;
- if (in.remaining()) wname = in.pop().to_string();
-
- add_contact_boundary_to_Nitsche_large_sliding_contact_brick
- (*md, ind, *mim, region, true, false, false,
- dispname, "", wname);
- );
-
-
- /*@SET ('add slave contact boundary to biased Nitsche large sliding
contact brick', @int indbrick, @tmim mim, @int region, @str dispname, @str
lambdaname[, @str wname])
- Adds a slave contact boundary to an existing biased Nitsche's large
sliding contact
- with friction brick. @*/
- sub_command
- ("add slave contact boundary to biased Nitsche large sliding contact
brick", 5, 6, 0,0,
- size_type ind = in.pop().to_integer() - config::base_index();
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- size_type region = in.pop().to_integer();
- std::string dispname = in.pop().to_string();
- std::string sigma = in.pop().to_string();
- std::string wname;
- if (in.remaining()) wname = in.pop().to_string();
-
- add_contact_boundary_to_Nitsche_large_sliding_contact_brick
- (*md, ind, *mim, region, false, true, false,
- dispname, sigma, wname);
- );
-
- /*@SET ('add contact boundary to unbiased Nitsche large sliding contact
brick', @int indbrick, @tmim mim, @int region, @str dispname, @str lambdaname[,
@str wname])
- Adds a contact boundary to an existing unbiased Nitschelarge sliding
contact
- with friction brick which is both master and slave. @*/
- sub_command
- ("add contact boundary to unbiased Nitsche large sliding contact brick",
- 5, 6, 0, 0,
- size_type ind = in.pop().to_integer() - config::base_index();
- getfem::mesh_im *mim = to_meshim_object(in.pop());
- size_type region = in.pop().to_integer();
- std::string dispname = in.pop().to_string();
- std::string sigma = in.pop().to_string();
- std::string wname;
- if (in.remaining()) wname = in.pop().to_string();
-
- add_contact_boundary_to_Nitsche_large_sliding_contact_brick
- (*md, ind, *mim, region, true, true, true,
- dispname, sigma, wname);
- );
- }
-
- if (m_in.narg() < 2) THROW_BADARG( "Wrong number of input arguments");
-
- getfem::model *md = to_model_object(m_in.pop());
- std::string init_cmd = m_in.pop().to_string();
- std::string cmd = cmd_normalize(init_cmd);
-
-
- SUBC_TAB::iterator it = subc_tab.find(cmd);
- if (it != subc_tab.end()) {
- check_cmd(cmd, it->first.c_str(), m_in, m_out, it->second->arg_in_min,
- it->second->arg_in_max, it->second->arg_out_min,
- it->second->arg_out_max);
- it->second->run(m_in, m_out, md);
- }
- else bad_cmd(init_cmd);
-
-}
diff --git a/interface/src/.#gf_model_set.cc b/interface/src/.#gf_model_set.cc
deleted file mode 120000
index a3609df..0000000
--- a/interface/src/.#gf_model_set.cc
+++ /dev/null
@@ -1 +0,0 @@
-yrenard@icj-cl-insa10.3041:1583744985
\ No newline at end of file
diff --git a/interface/src/gf_model_set.cc b/interface/src/gf_model_set.cc
index 91c2445..535f635 100644
--- a/interface/src/gf_model_set.cc
+++ b/interface/src/gf_model_set.cc
@@ -299,7 +299,7 @@ void gf_model_set(getfemint::mexargs_in& m_in,
Define a new macro for the high generic assembly language.
The name include the parameters. For instance name='sp(a,b)', expr='a.b'
is a valid definition. Macro without parameter can also be defined.
- For instance name='x1', expr='X[1]' is valid. Teh form name='grad(u)',
+ For instance name='x1', expr='X[1]' is valid. The form name='grad(u)',
expr='Grad_u' is also allowed but in that case, the parameter 'u' will
only be allowed to be a variable name when using the macro. Note that
macros can be directly defined inside the assembly strings with the