I'm going to assume since you mention electrodynamics that you're interested in PDEs.
You've already mentioned FEniCS in your comment. FEniCS offers a domain-specific language (DSL) called UFL.
This language makes it simple to express the weak form of a PDE for discretization via the finite element method.
There's another package called Firedrake*, which also uses UFL to express PDEs.
Firedrake has built-in support for extruded meshes, where you take a 2D domain and lift it into 3D.
I develop applications in the geophysical sciences, and this feature is absolutely indispensable for me.
On the other hand, the FEniCS developers are much more heavily invested in biological problems and consequently have worked a lot on solving mixed-dimensional problems (see this paper).
You mentioned wanting to use the finite difference method, so you should also be aware of Devito.
Like FEniCS and Firedrake, Devito also uses an embedded DSL to describe PDEs.
For an example, you can see this sample code for a seismic wave propagation problem.
With each of these libraries, you should be freed from the burden of writing the low-level kernel code to form the linear or nonlinear system corresponding to the discretization of your problem.
This is possible because they either call out to skeletonized low-level kernels and inject code for your particular problem, or they completely generate the low-level kernels on the spot.
In other words, the library automates the translation from your PDE to a discretized linear or nonlinear system.
The library does not automate away the process of deciding how to solve that linear or nonlinear system once it has been formed.
Firedrake, for example, is very tightly integrated with PETSc.
You can make choices about methods by passing options to PETSc's linear solvers, for example to use LU, GMRES, or CG to solve linear systems.
Opinions of whether these libraries are A Good Thing among computational scientists vary.
On the one hand, they provide you with a convenient way to set up and solve physics problems without having to write a mess of low-level code, so they are great for prototyping.
Some have argued that they are ultimately a hindrance if you want to do real work because (1) there are insufficient escape hatches for when you need to do weird or unusual things and (2) you give up all control over how your problem is formed.
Personally, I am happy to give up this control and I avoid doing weird or unusual things, but this is a choice you have to make for yourself.
*I'm an occasional contributor to Firedrake and I have grant funding to develop software built on it.