PolyFEM
Loading...
Searching...
No Matches
VarFormFactory.cpp
Go to the documentation of this file.
2
13
14namespace polyfem::varform
15{
16 namespace
17 {
18 bool has_entries(const json &args, const json::json_pointer &path)
19 {
20 return args.contains(path) && !args.at(path).empty();
21 }
22
23 bool has_two_mesh_fsi_material(const json &args)
24 {
25 if (!args.contains("materials") || args["materials"].is_null())
26 return false;
27
28 const auto has_solid_fields = [](const json &material) {
29 return material.contains("fluid_geometry_id")
30 && material.contains("solid_geometry_id")
31 && material.contains("displacement_space_id")
32 && material.contains("solid_material");
33 };
34
35 const json &materials = args["materials"];
36 if (!materials.is_array())
37 return has_solid_fields(materials);
38 if (materials.empty())
39 return false;
40
41 for (const json &material : materials)
42 if (!has_solid_fields(material))
43 return false;
44 return true;
45 }
46 } // namespace
47
48 std::string formulation_from_args(const json &args)
49 {
50 if (!args.contains("materials") || args["materials"].is_null())
51 return "";
52
53 if (args["materials"].is_array())
54 {
55 std::string current;
56 for (const auto &m : args["materials"])
57 {
58 const std::string tmp = m["type"];
59 if (current.empty())
60 current = tmp;
61 else if (current != tmp)
62 {
65 {
66 current = "MultiModels";
67 }
68 else
69 {
70 return "";
71 }
72 }
73 }
74
75 return current;
76 }
77
78 return args["materials"].value("type", "");
79 }
80
82 {
84 const std::string formulation = formulation_from_args(args);
85 return !formulation.empty() && VarFormFactory::create(formulation, args) != nullptr;
86 }
87
88 bool VarFormFactory::supports(const std::string &formulation, const json &args)
89 {
90 if (args.value("/space/remesh/enabled"_json_pointer, false))
91 return false;
92
93 if (args.value("/contact/periodic"_json_pointer, false))
94 return false;
95
96 if (args.contains("/constraints/macro_displacement_gradient"_json_pointer))
97 return false;
98
99 if (formulation == "OperatorSplitting")
100 return args.contains("time") && !args["time"].is_null();
101
102 if (formulation == "ThermoElasticity")
103 return true;
104 if (formulation == "NavierStokesFSI")
105 return args.contains("time") && !args["time"].is_null();
106
107 const auto assembler = assembler::AssemblerUtils::make_assembler(formulation);
108 if (!assembler)
109 return false;
110
111 if (!assembler::AssemblerUtils::other_assembler_name(formulation).empty())
112 return formulation == "Stokes"
113 || formulation == "NavierStokes"
114 || formulation == "IncompressibleLinearElasticity"
115 || formulation == "Bilaplacian";
116
117 if (assembler->is_fluid())
118 return false;
119
120 return assembler->is_tensor() || assembler->is_linear();
121 }
122
123 std::shared_ptr<VarForm> VarFormFactory::create(const std::string &formulation, const json &args)
124 {
125 if (!supports(formulation, args))
126 return nullptr;
127
128 const bool has_contact = args.value("/contact/enabled"_json_pointer, false);
129 const bool has_pressure = has_entries(args, "/boundary_conditions/pressure_boundary"_json_pointer)
130 || has_entries(args, "/boundary_conditions/pressure_cavity"_json_pointer);
131 const bool has_file_constraints =
132 has_entries(args, "/constraints/hard"_json_pointer)
133 || has_entries(args, "/constraints/soft"_json_pointer);
134 const bool has_periodic_constraints =
135 has_entries(args, "/boundary_conditions/periodic"_json_pointer);
136 const json zero_mean = args.contains("/constraints/zero_mean"_json_pointer)
137 ? args.at("/constraints/zero_mean"_json_pointer)
138 : json(false);
139 const bool has_zero_mean_constraints =
140 (zero_mean.is_boolean() && zero_mean.get<bool>())
141 || (zero_mean.is_array() && !zero_mean.empty());
142 const bool has_constraints =
143 has_file_constraints || has_periodic_constraints || has_zero_mean_constraints;
144
145 if (formulation == "ThermoElasticity")
146 return (!has_pressure && !has_constraints) ? std::make_shared<ThermoElasticVarForm>() : nullptr;
147
148 const auto assembler = assembler::AssemblerUtils::make_assembler(formulation);
149
150 if (formulation == "Stokes")
151 return (!has_contact && !has_constraints) ? std::make_shared<StokesVarForm>() : nullptr;
152 if (formulation == "NavierStokes")
153 return (!has_contact && !has_constraints) ? std::make_shared<NavierStokesVarForm>() : nullptr;
154 if (formulation == "NavierStokesFSI")
155 return ((!has_contact || has_two_mesh_fsi_material(args)) && !has_constraints)
156 ? std::make_shared<NavierStokesFSIVarForm>()
157 : nullptr;
158 if (formulation == "OperatorSplitting")
159 return (!has_contact && !has_constraints) ? std::make_shared<OperatorSplittingVarForm>() : nullptr;
160 if (formulation == "IncompressibleLinearElasticity")
161 return (!has_contact && !has_pressure && !has_constraints) ? std::make_shared<IncompressibleElasticVarForm>() : nullptr;
162 if (formulation == "Bilaplacian")
163 return (!has_contact && !has_constraints) ? std::make_shared<BilaplacianVarForm>() : nullptr;
164
165 if (!assembler->is_tensor())
166 return (!has_contact && !has_pressure && !has_file_constraints) ? std::make_shared<ScalarVarForm>() : nullptr;
167
168 if (assembler->is_linear() && !has_contact && !has_pressure && !has_constraints)
169 return std::make_shared<LinearElasticVarForm>();
170
171 if (args.contains("time") && !args["time"].is_null())
172 return std::make_shared<NonlinearElasticTransientVarForm>();
173
174 return std::make_shared<NonlinearElasticStaticVarForm>();
175 }
176} // namespace polyfem::varform
static std::string other_assembler_name(const std::string &formulation)
static bool is_elastic_material(const std::string &material)
utility to check if material is one of the elastic materials
static std::shared_ptr< Assembler > make_assembler(const std::string &formulation)
static std::shared_ptr< VarForm > create(const std::string &formulation, const json &args)
static bool supports(const std::string &formulation, const json &args)
void apply_common_params(json &args)
Definition JSONUtils.cpp:14
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