LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
vector_calculus_surfaces.cpp
浏览该文件的文档.
4#include "integration.hpp"
5#include <stdexcept>
6
7namespace LMCAS {
8
9using namespace vector_calculus_detail;
10
13 const std::string& u, const std::string& v,
14 detail::RewriteBudget& transform_budget)
15{
16 VectorField r_u;
17 r_u.reserve(3);
18 for (size_t i = 0; i < 3; ++i) {
20 r_u.push_back(deriv ? detail::make_expression_ptr(detail::normalize_node(detail::node(deriv), transform_budget)) : SymbolicExpr::number(0));
21 }
22
23 VectorField r_v;
24 r_v.reserve(3);
25 for (size_t i = 0; i < 3; ++i) {
27 r_v.push_back(deriv ? detail::make_expression_ptr(detail::normalize_node(detail::node(deriv), transform_budget)) : SymbolicExpr::number(0));
28 }
29
30 VectorField result;
31 result.reserve(3);
32 for (std::size_t index = 0; index < 3; ++index) {
33 result.push_back(
35 }
36 return result;
37}
38
40 const std::shared_ptr<SymbolicExpr>& f, const VectorField& parametrization,
41 const std::string& u, const std::string& v,
42 const std::shared_ptr<SymbolicExpr>& u_lower, const std::shared_ptr<SymbolicExpr>& u_upper,
43 const std::shared_ptr<SymbolicExpr>& v_lower, const std::shared_ptr<SymbolicExpr>& v_upper,
45{
46 detail::RewriteBudget transform_budget(context, context.limits().max_recursion_depth,
47 context.limits().max_ast_nodes, "surface_integral_scalar");
48 const std::string operation = "surface_integral_scalar";
51 context, operation);
52 if (!valid) {
53 return VectorCalculusExprResult::failure(valid.error());
54 }
55
56 auto step = context.consume_steps(parametrization.size() * 6 + 8, operation);
57 if (!step) {
58 return VectorCalculusExprResult::failure(step.error());
59 }
60
61 try {
63 context, operation, transform_budget);
64 } catch (const CasError& error) {
66 } catch (const std::bad_alloc&) {
68 "surface integral allocation failed",
69 operation);
70 } catch (const std::length_error& error) {
71 return VectorCalculusExprResult::failure(CasErrc::ResourceLimit, error.what(), operation);
72 } catch (const std::exception& e) {
74 }
75}
76
78 const std::shared_ptr<SymbolicExpr>& f, const VectorField& parametrization,
79 const std::string& u, const std::string& v,
80 const std::shared_ptr<SymbolicExpr>& u_lower, const std::shared_ptr<SymbolicExpr>& u_upper,
81 const std::shared_ptr<SymbolicExpr>& v_lower, const std::shared_ptr<SymbolicExpr>& v_upper)
82{
86}
87
88std::shared_ptr<SymbolicExpr> surface_integral_scalar(
89 const std::shared_ptr<SymbolicExpr>& f, const VectorField& parametrization,
90 const std::string& u, const std::string& v,
91 const std::shared_ptr<SymbolicExpr>& u_lower, const std::shared_ptr<SymbolicExpr>& u_upper,
92 const std::shared_ptr<SymbolicExpr>& v_lower, const std::shared_ptr<SymbolicExpr>& v_upper)
93{
95 detail::RewriteBudget transform_budget(context, (context).limits().max_recursion_depth,
96 (context).limits().max_ast_nodes, "transform");
97 if (!f) {
98 throw std::invalid_argument("surface_integral_scalar: f must not be null");
99 }
100 if (parametrization.size() != 3) {
101 throw std::invalid_argument(
102 "surface_integral_scalar: parametrization must have 3 components");
103 }
104 if (!u_lower || !u_upper || !v_lower || !v_upper) {
105 throw std::invalid_argument("surface_integral_scalar: bounds must not be null");
106 }
107
108 std::vector<std::string> coord_vars = {"x", "y", "z"};
109
110 auto f_composed = f;
111 for (size_t i = 0; i < 3; ++i) {
112 f_composed = detail::make_expression_ptr(detail::substitute_node(detail::node(f_composed), coord_vars[i], detail::node(parametrization[i]), transform_budget));
113 }
114 f_composed = detail::make_expression_ptr(detail::normalize_node(detail::node(f_composed), transform_budget));
115
116 auto cross = vector_calculus_cross_product_partials(parametrization, u, v, transform_budget);
117
118 std::shared_ptr<SymbolicExpr> mag_sq = nullptr;
119 for (size_t i = 0; i < 3; ++i) {
120 auto sq = SymbolicExpr::power(cross[i], SymbolicExpr::number(2));
122 if (!mag_sq) {
123 mag_sq = sq;
124 } else {
125 mag_sq = SymbolicExpr::add(mag_sq, sq);
126 mag_sq = detail::make_expression_ptr(detail::normalize_node(detail::node(mag_sq), transform_budget));
127 }
128 }
129
130 auto magnitude = SymbolicExpr::sqrt(mag_sq);
131 magnitude = detail::make_expression_ptr(detail::normalize_node(detail::node(magnitude), transform_budget));
132
133 auto integrand = SymbolicExpr::multiply(f_composed, magnitude);
134 integrand = detail::make_expression_ptr(detail::normalize_node(detail::node(integrand), transform_budget));
135
136 Integrator integrator;
137
138 std::vector<IntegrationStep> steps = {
139 {v, v_lower, v_upper},
140 {u, u_lower, u_upper},
141 };
142 auto result = integrate_multiple_checked(*integrand, steps, integrator, context);
143 if (!result) throw result.error();
144 return LMCAS::detail::make_expression_ptr(result.value());
145}
146
147
149 const VectorField& F, const VectorField& parametrization,
150 const std::string& u, const std::string& v,
151 const std::shared_ptr<SymbolicExpr>& u_lower, const std::shared_ptr<SymbolicExpr>& u_upper,
152 const std::shared_ptr<SymbolicExpr>& v_lower, const std::shared_ptr<SymbolicExpr>& v_upper,
154{
155 detail::RewriteBudget transform_budget(context, context.limits().max_recursion_depth,
156 context.limits().max_ast_nodes, "surface_integral_vector");
157 const std::string operation = "surface_integral_vector";
160 context, operation);
161 if (!valid) {
162 return VectorCalculusExprResult::failure(valid.error());
163 }
164
165 auto step = context.consume_steps(F.size() * parametrization.size() +
166 parametrization.size() * 6 + 8,
167 operation);
168 if (!step) {
169 return VectorCalculusExprResult::failure(step.error());
170 }
171
172 try {
174 context, operation, transform_budget);
175 } catch (const CasError& error) {
177 } catch (const std::bad_alloc&) {
179 "surface integral allocation failed",
180 operation);
181 } catch (const std::length_error& error) {
182 return VectorCalculusExprResult::failure(CasErrc::ResourceLimit, error.what(), operation);
183 } catch (const std::exception& e) {
185 }
186}
187
189 const VectorField& F, const VectorField& parametrization,
190 const std::string& u, const std::string& v,
191 const std::shared_ptr<SymbolicExpr>& u_lower, const std::shared_ptr<SymbolicExpr>& u_upper,
192 const std::shared_ptr<SymbolicExpr>& v_lower, const std::shared_ptr<SymbolicExpr>& v_upper)
193{
197}
198
199std::shared_ptr<SymbolicExpr> surface_integral_vector(
200 const VectorField& F, const VectorField& parametrization,
201 const std::string& u, const std::string& v,
202 const std::shared_ptr<SymbolicExpr>& u_lower, const std::shared_ptr<SymbolicExpr>& u_upper,
203 const std::shared_ptr<SymbolicExpr>& v_lower, const std::shared_ptr<SymbolicExpr>& v_upper)
204{
206 detail::RewriteBudget transform_budget(context, (context).limits().max_recursion_depth,
207 (context).limits().max_ast_nodes, "transform");
208 if (F.size() != 3) {
209 throw std::invalid_argument(
210 "surface_integral_vector: F must have 3 components");
211 }
212 if (parametrization.size() != 3) {
213 throw std::invalid_argument(
214 "surface_integral_vector: parametrization must have 3 components");
215 }
216 if (!u_lower || !u_upper || !v_lower || !v_upper) {
217 throw std::invalid_argument("surface_integral_vector: bounds must not be null");
218 }
219
220 std::vector<std::string> coord_vars = {"x", "y", "z"};
221
222 auto cross = vector_calculus_cross_product_partials(parametrization, u, v, transform_budget);
223
224 std::shared_ptr<SymbolicExpr> dot_product = nullptr;
225 for (size_t i = 0; i < 3; ++i) {
226 if (!F[i]) {
227 continue;
228 }
229
230 auto Fi_composed = F[i];
231 for (size_t j = 0; j < 3; ++j) {
232 Fi_composed = detail::make_expression_ptr(detail::substitute_node(detail::node(Fi_composed), coord_vars[j], detail::node(parametrization[j]), transform_budget));
233 }
234 Fi_composed = detail::make_expression_ptr(detail::normalize_node(detail::node(Fi_composed), transform_budget));
235
236 auto term = SymbolicExpr::multiply(Fi_composed, cross[i]);
237 term = detail::make_expression_ptr(detail::normalize_node(detail::node(term), transform_budget));
238
239 if (!dot_product) {
240 dot_product = term;
241 } else {
242 dot_product = SymbolicExpr::add(dot_product, term);
244 }
245 }
246
247 if (!dot_product) {
248 return SymbolicExpr::number(0);
249 }
250
251 Integrator integrator;
252
253 std::vector<IntegrationStep> steps = {
254 {v, v_lower, v_upper},
255 {u, u_lower, u_upper},
256 };
258 if (!result) throw result.error();
259 return LMCAS::detail::make_expression_ptr(result.value());
260}
261
262}
static Result failure(CasErrc code, std::string message, std::string operation={})
Symbolic integration APIs.
SymbolicNodePtr differentiate_node(const SymbolicNodePtr &node, const std::string &variable, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
SymbolicNodePtr normalize_node(const SymbolicNodePtr &node, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
SymbolicNodePtr substitute_node(const SymbolicNodePtr &node, const std::string &variable, const SymbolicNodePtr &replacement, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
VectorField vector_calculus_cross_product_partials(const VectorField &parametrization, const std::string &u, const std::string &v, detail::RewriteBudget &transform_budget)
VectorCalculusExprResult surface_integral_scalar_strict(const std::shared_ptr< SymbolicExpr > &function, const VectorField &parametrization, const std::string &u, const std::string &v, const std::shared_ptr< SymbolicExpr > &u_lower, const std::shared_ptr< SymbolicExpr > &u_upper, const std::shared_ptr< SymbolicExpr > &v_lower, const std::shared_ptr< SymbolicExpr > &v_upper, ComputationContext &context, const std::string &operation, detail::RewriteBudget &transform_budget)
Result< void > vector_calculus_validate_surface_vector_inputs(const VectorField &F, const VectorField &parametrization, const std::string &u, const std::string &v, const std::shared_ptr< SymbolicExpr > &u_lower, const std::shared_ptr< SymbolicExpr > &u_upper, const std::shared_ptr< SymbolicExpr > &v_lower, const std::shared_ptr< SymbolicExpr > &v_upper, ComputationContext &context, const std::string &operation)
Result< void > vector_calculus_validate_surface_scalar_inputs(const std::shared_ptr< SymbolicExpr > &f, const VectorField &parametrization, const std::string &u, const std::string &v, const std::shared_ptr< SymbolicExpr > &u_lower, const std::shared_ptr< SymbolicExpr > &u_upper, const std::shared_ptr< SymbolicExpr > &v_lower, const std::shared_ptr< SymbolicExpr > &v_upper, ComputationContext &context, const std::string &operation)
VectorCalculusExprResult surface_integral_vector_strict(const VectorField &field, const VectorField &parametrization, const std::string &u, const std::string &v, const std::shared_ptr< SymbolicExpr > &u_lower, const std::shared_ptr< SymbolicExpr > &u_upper, const std::shared_ptr< SymbolicExpr > &v_lower, const std::shared_ptr< SymbolicExpr > &v_upper, ComputationContext &context, const std::string &operation, detail::RewriteBudget &transform_budget)
std::shared_ptr< SymbolicExpr > vector_calculus_cross_component(const VectorField &left, const VectorField &right, std::size_t index)
ExprResult e()
__attribute__((visibility("default"))) VectorCalculusExprResult surface_integral_scalar_checked(const std __attribute__((visibility("default"))) VectorCalculusExprResult surface_integral_scalar_checked(const std __attribute__((visibility("default"))) std const VectorField const std::string const std::string & v
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
VectorCalculusExprResult surface_integral_scalar_checked(const std::shared_ptr< SymbolicExpr > &f, const VectorField &parametrization, const std::string &u, const std::string &v, const std::shared_ptr< SymbolicExpr > &u_lower, const std::shared_ptr< SymbolicExpr > &u_upper, const std::shared_ptr< SymbolicExpr > &v_lower, const std::shared_ptr< SymbolicExpr > &v_upper, ComputationContext &context)
__attribute__((visibility("default"))) VectorCalculusExprResult surface_integral_scalar_checked(const std __attribute__((visibility("default"))) VectorCalculusExprResult surface_integral_scalar_checked(const std __attribute__((visibility("default"))) std const VectorField const std::string const std::string const std::shared_ptr< SymbolicExpr > const std::shared_ptr< SymbolicExpr > const std::shared_ptr< SymbolicExpr > & v_lower
__attribute__((visibility("default"))) VectorCalculusExprResult surface_integral_scalar_checked(const std __attribute__((visibility("default"))) VectorCalculusExprResult surface_integral_scalar_checked(const std __attribute__((visibility("default"))) std const VectorField const std::string const std::string const std::shared_ptr< SymbolicExpr > & u_lower
VectorCalculusExprResult surface_integral_vector_checked(const VectorField &F, const VectorField &parametrization, const std::string &u, const std::string &v, const std::shared_ptr< SymbolicExpr > &u_lower, const std::shared_ptr< SymbolicExpr > &u_upper, const std::shared_ptr< SymbolicExpr > &v_lower, const std::shared_ptr< SymbolicExpr > &v_upper, ComputationContext &context)
__attribute__((visibility("default"))) VectorCalculusExprResult surface_integral_scalar_checked(const std __attribute__((visibility("default"))) VectorCalculusExprResult surface_integral_scalar_checked(const std __attribute__((visibility("default"))) std const VectorField const std::string const std::string const std::shared_ptr< SymbolicExpr > const std::shared_ptr< SymbolicExpr > const std::shared_ptr< SymbolicExpr > const std::shared_ptr< SymbolicExpr > & v_upper
std::vector< std::shared_ptr< SymbolicExpr > > VectorField
向量场由标量表达式组成。
std::shared_ptr< SymbolicExpr > surface_integral_scalar(const std::shared_ptr< SymbolicExpr > &f, const VectorField &parametrization, const std::string &u, const std::string &v, const std::shared_ptr< SymbolicExpr > &u_lower, const std::shared_ptr< SymbolicExpr > &u_upper, const std::shared_ptr< SymbolicExpr > &v_lower, const std::shared_ptr< SymbolicExpr > &v_upper)
__attribute__((visibility("default"))) VectorCalculusExprResult curve_integral_scalar_checked(const std __attribute__((visibility("default"))) VectorCalculusExprResult curve_integral_scalar_checked(const std __attribute__((visibility("default"))) std const VectorField & parametrization
Result< SymbolicExpr > integrate_multiple_checked(const SymbolicExpr &integrand, const std::vector< IntegrationStep > &steps, Integrator &integrator, ComputationContext &context)
Result< std::shared_ptr< SymbolicExpr > > VectorCalculusExprResult
__attribute__((visibility("default"))) VectorCalculusExprResult surface_integral_scalar_checked(const std __attribute__((visibility("default"))) VectorCalculusExprResult surface_integral_scalar_checked(const std __attribute__((visibility("default"))) std const VectorField const std::string const std::string const std::shared_ptr< SymbolicExpr > const std::shared_ptr< SymbolicExpr > & u_upper
const std::vector< IntegrationStep > Integrator & integrator
std::shared_ptr< SymbolicExpr > surface_integral_vector(const VectorField &F, const VectorField &parametrization, const std::string &u, const std::string &v, const std::shared_ptr< SymbolicExpr > &u_lower, const std::shared_ptr< SymbolicExpr > &u_upper, const std::shared_ptr< SymbolicExpr > &v_lower, const std::shared_ptr< SymbolicExpr > &v_upper)
VectorCalculusExprResult dot_product(const VectorField &a, const VectorField &b)
__attribute__((visibility("default"))) VectorCalculusExprResult surface_integral_scalar_checked(const std __attribute__((visibility("default"))) VectorCalculusExprResult surface_integral_scalar_checked(const std __attribute__((visibility("default"))) std const VectorField const std::string & u