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