#proc-macro #define #finite-element #traits #spring #procedural #formal

finiteelement_macros

一个库,用于创建定义实现FiniteElement类型的进程宏

1个不稳定版本

0.1.0 2019年7月15日

#12#formal


finiteelement 中使用

MIT/Apache

34KB
746

此库用于定义实现 FiniteElement 特性的类型

这些类型由进程宏定义。要创建一个新类型,必须首先定义一个类似于单元的结构体,并为它实现 AutoImplementable 特性。一旦实现了 AutoImplementable 特性,就可以定义一个进程宏,该宏将生成新类型的定义以及该类型的 FiniteElement 特性的实现。

创建新宏

要创建一个新宏,必须首先定义一个零大小的结构体,并为它实现 AutoImplementable 特性。例如,如果我们想要创建表示弹簧的元素,我们首先创建一个零大小的结构体:struct _Spring{},并为它实现 Autotimplementable 特性。

实现了特例 AutoImplementable 的类型可以作为参数传递给函数 macro_def<F: Float, T: AutoImplementable<F>>() -> TokenStream。此函数可用于定义一个过程宏,该宏将生成定义相应结构和其特例 FiniteElement 实现的代码。完整示例(从 spring.rs 复制粘贴)


use crate::formal::{Formal, FormalVector, FormalPoint, Float};
use crate::autoimplementable::AutoImplementable;

use std::collections::HashMap;

// A `Spring` likes it when `a` and `b` are at distance `l`, and
// exerts a force of `k.(|ab| - l)` to achieve this.
pub struct _Spring{}

impl<F: Float> AutoImplementable<F> for _Spring {
   fn struct_name() -> String {
       String::from("Spring")
   }

   fn elt_list() -> Vec<String> {
       vec![String::from("a"), String::from("b")]
   }

   fn cst_list() -> Vec<String> {
       vec![String::from("l"), String::from("k")]
   }

   fn formal_map() -> HashMap<String, FormalVector<F>> {
   //Create a `Formal` for each element coordiate and each constants
       let point_a = FormalPoint {
           x: Formal::new_var(0),
           y: Formal::new_var(1),
           z: Formal::new_var(2)
       };

       let point_b = FormalPoint {
           x: Formal::new_var(3),
           y: Formal::new_var(4),
           z: Formal::new_var(5)
       };

       let cst_l = Formal::new_var(6);
       let cst_k = Formal::new_var(7);

       // The force applied on point a is k(|ab| - l) * ab/|ab|
       let ab = point_b - point_a;
       let force_a: FormalVector<F> = (ab.clone().norm() - cst_l.clone()) * ab.clone()/ab.clone().norm() * cst_k.clone();

       // The force applied on point b is k(|ba| - l) * ba/|ba|
       let force_b = (ab.clone().norm() - cst_l.clone()) * ab.clone()/ab.clone().norm() * cst_k.clone() * Formal::new_cst(F::one().neg());
       let mut ret = HashMap::new();
       ret.insert(String::from("a"), force_a);
       ret.insert(String::from("b"), force_b);
       ret
   }

}

// Once the trait is implemented, we can write a procedural macro
#[proc_macro]
pub fn auto_impl_spring(_item: TokenStream) -> TokenStream {
   macro_def::<f32, _Spring>()
}

依赖项

~1–1.4MB
~29K SLoC