我正在设计一个用于解决PDE系统的Fortran代码.
它现在的设计方式是我有一个Variable具有多个属性的类型,其中最重要的是val存储值的数组.
现在我还有一个solver类,它将对a执行计算variable.我认为将整个传递variable给求解器并且variable%val每次我想要运行它(在exectution期间数千次)都是低效的,所以我决定在solver类中定义指针字段以将求解器绑定到适当的变量.例如
program example
use variable
use solvers
type(Variable) T
type(Solver) solver_temperature
!Contructors
call T%create()
call solver_temperature%create(T)
call solver_temperature%solve()
end program example
Run Code Online (Sandbox Code Playgroud)
和解算器模块
module solvers
type Solver
real*8, pointer :: T(:,:)
contains
procedure :: create
procedure :: solve
end type
contains
subroutine create(this,T)
type(Solver) :: this
type(Variable) :: T
this%T => T%val
end subroutine
end module
Run Code Online (Sandbox Code Playgroud)
在我的程序中,我按照上面显示的方式为不同的物理属性定义了不同的变量,并为这些变量定义了不同的求解器.
我是OOP的新手,所以我的问题是,如果这是一个体面的设计?特别是从性能的角度来看.这与T仅仅制作一个数组并将其传递给子程序solve的速度相比如何?有没有一些常规的方法来做到这一点?
我有一系列功能依赖,看起来像这样.
y = 0.1222*x**0.8628
我想使用sympy将x作为y的函数.在网上搜索我看到solve可以用于此.所以我试过了
x = Symbol('x', real=True, positive=True)
y = Symbol('y', real=True, positive=True)
solve(y - 0.1222*x**0.8628, x)
Run Code Online (Sandbox Code Playgroud)
但是,这不起作用,因为20分钟后内核仍然很忙.我注意到,如果我用0.8628交换更简单的功率,比如0.8或甚至0.86,那么计算工作得非常快.
我想在加快这方面提供一些帮助,或者可能有更好的方法?
我从 Metcalf 等人的“Fortran 95/2003 解释”中举了一个例子,因为我自己的代码针对同样的事情。
type, abstract :: my_numeric_type
contains
private
procedure(op2), deferred :: add
generic, public :: operator(+) => add
end type
abstract interface
function op2(a,b) result (r)
import :: my_numeric_type
class(my_numeric type), intent(in) :: a,b
class(my_numeric type), allocatable :: r
end function op2
end interface
type, extends(my_numeric_type) :: my_integer
integer, private :: value
contains
procedure :: add => add_my_integer
end type
Run Code Online (Sandbox Code Playgroud)
现在,我的问题是如何正确实现该add_my_integer功能。似乎我被迫强制转换第一个参数,my_integer因为它是一个类型绑定过程,但第二个参数my_numeric_type必须符合抽象接口。至于结果,我应该分配r给my_integer?这是我到目前为止想到的,它确实可以编译,但是一直检查类型似乎很奇怪,并且会导致分段错误(不过可能是由于我的代码存在其他问题)。
function add_my_integer(a,b) result(r)
class(my_integer), intent(in) :: …Run Code Online (Sandbox Code Playgroud)