PolyFEM
Loading...
Searching...
No Matches
VarFormFactory.cpp
Go to the documentation of this file.
2
16
17namespace polyfem::varform
18{
19 namespace
20 {
21 bool is_scalar_formulation(const std::string &formulation)
22 {
23 return formulation == "Helmholtz"
24 || formulation == "Laplacian"
25 || formulation == "Electrostatics";
26 }
27
28 bool is_linear_elastic_formulation(const std::string &formulation)
29 {
30 return formulation == "LinearElasticity"
31 || formulation == "HookeLinearElasticity";
32 }
33
34 bool is_nonlinear_elastic_formulation(const std::string &formulation)
35 {
36 return formulation == "SaintVenant"
37 || formulation == "NeoHookean"
38 || formulation == "IsochoricNeoHookean"
39 || formulation == "MooneyRivlin"
40 || formulation == "MooneyRivlin3Param"
41 || formulation == "MooneyRivlin3ParamSymbolic"
42 || formulation == "MultiModels"
43 || formulation == "MaterialSum"
44 || formulation == "UnconstrainedOgden"
45 || formulation == "IncompressibleOgden"
46 || formulation == "VolumePenalty"
47 || formulation == "InversionBarrier"
48 || formulation == "HGOFiber"
49 || formulation == "HGODispersion"
50 || formulation == "ActiveFiber"
51 || formulation == "AMIPS"
52 || formulation == "FixedCorotational";
53 }
54
55 bool is_elastic_formulation(const std::string &formulation)
56 {
57 return is_linear_elastic_formulation(formulation)
58 || is_nonlinear_elastic_formulation(formulation);
59 }
60
61 bool has_non_empty_entries(const json &args, const json::json_pointer &path)
62 {
63 return args.contains(path) && !args.at(path).empty();
64 }
65
66 bool has_two_mesh_fsi_material(const json &args)
67 {
68 if (!args.contains("materials") || args["materials"].is_null())
69 return false;
70
71 const auto has_solid_fields = [](const json &material) {
72 return material.contains("fluid_geometry_id")
73 && material.contains("solid_geometry_id")
74 && material.contains("displacement_space_id")
75 && material.contains("solid_material");
76 };
77
78 const json &materials = args["materials"];
79 if (!materials.is_array())
80 return has_solid_fields(materials);
81 if (materials.empty())
82 return false;
83
84 for (const json &material : materials)
85 if (!has_solid_fields(material))
86 return false;
87 return true;
88 }
89 } // namespace
90
91 std::string formulation_from_args(const json &args)
92 {
93 if (!args.contains("materials") || args["materials"].is_null())
94 return "";
95
96 if (args["materials"].is_array())
97 {
98 std::string current;
99 for (const auto &m : args["materials"])
100 {
101 const std::string tmp = m["type"];
102 if (current.empty())
103 current = tmp;
104 else if (current != tmp)
105 {
108 {
109 current = "MultiModels";
110 }
111 else
112 {
113 return "";
114 }
115 }
116 }
117
118 return current;
119 }
120
121 return args["materials"].value("type", "");
122 }
123
125 {
127 const std::string formulation = formulation_from_args(args);
128 return !formulation.empty() && VarFormFactory::supports(formulation, args);
129 }
130
132 const std::string &formulation,
133 const json &args,
134 const bool is_optimization)
135 {
136 if (args.value("/space/remesh/enabled"_json_pointer, false))
137 return false;
138
139 const bool homogenization = args.contains("/constraints/macro_displacement_gradient"_json_pointer);
140 const bool has_contact = args.value("/contact/enabled"_json_pointer, false);
141 const bool has_periodic_constraints =
142 has_non_empty_entries(args, "/boundary_conditions/periodic"_json_pointer);
143 const bool periodic_contact = args.value("/contact/periodic"_json_pointer, false);
144 if (periodic_contact)
145 {
146 if (!homogenization)
147 return false;
148 if (!has_contact)
149 return false;
150 if (!has_periodic_constraints)
151 return false;
152 }
153
154 if (homogenization && !is_optimization)
155 return false;
156 if (homogenization && args.contains("time") && !args["time"].is_null())
157 return false;
158
159 const bool has_pressure = has_non_empty_entries(args, "/boundary_conditions/pressure_boundary"_json_pointer)
160 || has_non_empty_entries(args, "/boundary_conditions/pressure_cavity"_json_pointer);
161 const bool has_file_constraints =
162 has_non_empty_entries(args, "/constraints/hard"_json_pointer)
163 || has_non_empty_entries(args, "/constraints/soft"_json_pointer);
164 const json zero_mean = args.contains("/constraints/zero_mean"_json_pointer)
165 ? args.at("/constraints/zero_mean"_json_pointer)
166 : json(false);
167 const bool has_zero_mean_constraints =
168 (zero_mean.is_boolean() && zero_mean.get<bool>())
169 || (zero_mean.is_array() && !zero_mean.empty());
170 const bool has_constraints =
171 has_file_constraints || has_periodic_constraints || has_zero_mean_constraints;
172
173 if (formulation == "ThermoElasticity")
174 return !is_optimization && !has_pressure && !has_constraints;
175
176 if (formulation == "Stokes")
177 return !is_optimization && !has_contact && !has_constraints;
178 if (formulation == "NavierStokes")
179 return !is_optimization && !has_contact && !has_constraints;
180 if (formulation == "NavierStokesFSI")
181 return !is_optimization
182 && args.contains("time") && !args["time"].is_null()
183 && (!has_contact || has_two_mesh_fsi_material(args)) && !has_constraints;
184 if (formulation == "OperatorSplitting")
185 return !is_optimization
186 && args.contains("time") && !args["time"].is_null()
187 && !has_contact && !has_constraints;
188 if (formulation == "IncompressibleLinearElasticity")
189 return !is_optimization && !has_contact && !has_pressure && !has_constraints;
190 if (formulation == "Bilaplacian")
191 return !is_optimization && !has_contact && !has_constraints;
192
193 if (is_scalar_formulation(formulation))
194 {
195 return !homogenization && !has_contact && !has_pressure && !has_file_constraints;
196 }
197
198 return is_elastic_formulation(formulation);
199 }
200
201 std::shared_ptr<VarForm> VarFormFactory::create(
202 const std::string &formulation,
203 const json &args,
204 const bool is_optimization)
205 {
206 if (!supports(formulation, args, is_optimization))
207 return nullptr;
208
209 if (formulation == "ThermoElasticity")
210 return std::make_shared<ThermoElasticVarForm>();
211 if (formulation == "Stokes")
212 return std::make_shared<StokesVarForm>();
213 if (formulation == "NavierStokes")
214 return std::make_shared<NavierStokesVarForm>();
215 if (formulation == "NavierStokesFSI")
216 return std::make_shared<NavierStokesFSIVarForm>();
217 if (formulation == "OperatorSplitting")
218 return std::make_shared<OperatorSplittingVarForm>();
219 if (formulation == "IncompressibleLinearElasticity")
220 return std::make_shared<IncompressibleElasticVarForm>();
221 if (formulation == "Bilaplacian")
222 return std::make_shared<BilaplacianVarForm>();
223
224 if (is_scalar_formulation(formulation))
225 return is_optimization
226 ? std::static_pointer_cast<VarForm>(std::make_shared<DifferentiableScalarVarForm>())
227 : std::make_shared<ScalarVarForm>();
228
229 const bool homogenization = args.contains("/constraints/macro_displacement_gradient"_json_pointer);
230
231 if (homogenization)
232 return std::make_shared<DifferentiableNonlinearElasticStaticVarForm>();
233
234 const bool has_contact = args.value("/contact/enabled"_json_pointer, false);
235 const bool has_pressure = has_non_empty_entries(args, "/boundary_conditions/pressure_boundary"_json_pointer)
236 || has_non_empty_entries(args, "/boundary_conditions/pressure_cavity"_json_pointer);
237 const bool has_file_constraints =
238 has_non_empty_entries(args, "/constraints/hard"_json_pointer)
239 || has_non_empty_entries(args, "/constraints/soft"_json_pointer);
240 const bool has_periodic_constraints =
241 has_non_empty_entries(args, "/boundary_conditions/periodic"_json_pointer);
242 const json zero_mean = args.contains("/constraints/zero_mean"_json_pointer)
243 ? args.at("/constraints/zero_mean"_json_pointer)
244 : json(false);
245 const bool has_zero_mean_constraints =
246 (zero_mean.is_boolean() && zero_mean.get<bool>())
247 || (zero_mean.is_array() && !zero_mean.empty());
248 const bool has_constraints =
249 has_file_constraints || has_periodic_constraints || has_zero_mean_constraints;
250
251 if (is_linear_elastic_formulation(formulation)
252 && !has_contact && !has_pressure && !has_constraints)
253 {
254 return is_optimization
255 ? std::static_pointer_cast<VarForm>(std::make_shared<DifferentiableLinearElasticVarForm>())
256 : std::make_shared<LinearElasticVarForm>();
257 }
258
259 if (args.contains("time") && !args["time"].is_null())
260 {
261 return is_optimization
262 ? std::static_pointer_cast<VarForm>(std::make_shared<DifferentiableNonlinearElasticTransientVarForm>())
263 : std::make_shared<NonlinearElasticTransientVarForm>();
264 }
265
266 return is_optimization
267 ? std::static_pointer_cast<VarForm>(std::make_shared<DifferentiableNonlinearElasticStaticVarForm>())
268 : std::make_shared<NonlinearElasticStaticVarForm>();
269 }
270} // namespace polyfem::varform
static bool is_elastic_material(const std::string &material)
utility to check if material is one of the elastic materials
static std::shared_ptr< VarForm > create(const std::string &formulation, const json &args, bool is_optimization=false)
static bool supports(const std::string &formulation, const json &args, bool is_optimization=false)
void apply_common_params(json &args)
Definition JSONUtils.cpp:17
std::string formulation_from_args(const json &args)
Extracts the formulation type from the given JSON arguments.
bool uses_varform_state(json args)
Checks if the given JSON arguments use a VarForm state.
nlohmann::json json
Definition Common.hpp:9