For simplicity we only describe the implementation of an Amandus surface using the local Weierstrass representation formula (if you want to use the global version and need help please send a mail to grape@iam.uni-bonn.de). As an example we use the Riemann Step surface, a plane which is punctured at to grow one upward and one downward catenoid end. See [Kar2] and http://numod.ins.uni-bonn.de/grape/EXAMPLES/AMANDUS/amandus.html for more information and pictures.
The Amandus description files with extension *.am start with the Time-Object data for task, frame and parameter, followed by the domain data of the surface. The domain data format is identical to that one used for Explicit surfaces (see section 8.2.5.1), but for Amandus surfaces more than one domain part is allowed. Finally the type of the Weierstrass representation formula to be used has to be specified, KARL (Weierstrass) for the local and HERMANN (Amandus Schwarz) for the global version. The description file for the Riemann Step example is called riem_step.am:
# # Riemann Step Surface: plane with two catenoid ends # GEOMETRY; # task 0; 1; # frame / number of frames 0; 2; # number of int / double parameter # double parameter 1.0; # rho 0.8555996772; # r = (-rho^2 + (4 rho^2 - 1)^(1/2))^(1/2) for closed period 2; 2; # part / number of parts # part 1 0; 8; 10; 0; 1; # flag / number of u- and v-lines / u- and v-sub 3; 0; 0; pi; # umin / vmin / umax / vmax # part 2 0; 6; 10; 0; 1; # flag / number of u- and v-lines / u- and v-sub 0; 0; -2; pi; # umin / vmin / umax / vmax KARL; # type: local Weierstrass representation
The (rectangular) domain parts of an Amandus surface are transformed in the same way as the domain of an Explicit surface, the "set-compute-arg" method which sets a compute_arg function has to be replaced (a detailed description can be found in section 8.2.5.2). In this example we have two domain parts which are mapped to a quarter sphere but circles around (catenoid end) and (planar end), see figure 8.19:
static COMPLEX transform_domain(AMANDUS *amandus, int part, double u, double v) { if(!strcmp(amandus->name, "riem_step")) { double rho = amandus->time_parm->double_parm[0]; switch(np) { case 0: return g_crmul(g_csqrt(g_cadd(g_cexp(g_cmplx(u / rho, v)), g_CE)), rho); break; case 1: return g_crmul(g_csqrt(g_cadd(g_cexp(g_cmplx(u * rho, v)), g_CE)), rho); break; } } return g_cmplx(u, v); } AMANDUS *amandus_set_compute_arg() { AMANDUS *self; self = (AMANDUS *)START_METHOD(G_INSTANCE); ASSURE(self, "", END_METHOD(NULL)); self->compute_arg = transform_domain; END_METHOD(self); }
Figure 8.19: Fundamental domain of the Riemann Step surface (right picture)
computed by integration of the Weierstrass data along the parameter lines
in the domain (left picture). The straight boundary lines of the domain
are mapped to straight/planar boundary lines of the surface, reflection
of the fundamental piece on these lines gives the complete surface.
For the local version of the Weierstrass representation formula we have to define the two complex functions g(z) (the Gauß map) and f(z), the differential dg of g is not needed for computing the surface but there are other methods like "gausscurv-disp" which use it therefore we define it:
/* * riem_step * * g = z^2 - r^2 * f = - rho^2 / r^2 / (z^2 - rho^2)^2 * dg = 2 z */ static double *riem_step_rho, *riem_step_r; static COMPLEX riem_step_g(COMPLEX z) { return g_csub(g_cmul(z, z), g_cmplx(*riem_step_r * *riem_step_r, 0.0)); } static COMPLEX riem_step_f(COMPLEX z) { double rhosqr = *riem_step_rho * *riem_step_rho; return g_crmul(g_cpower(g_csub(g_cmul(z, z), g_cmplx(rhosqr, 0.0)), -2), -rhosqr / (*riem_step_r * *riem_step_r)); } static COMPLEX riem_step_dg(COMPLEX z) { return g_crmul(z, 2.0); } AMANDUS *amandus_set_weier_f() { AMANDUS *self; self = (AMANDUS *)START_METHOD(G_INSTANCE); ASSURE(self, "", END_METHOD(NULL)); if(!strcmp(self->name, "riem_step")) { riem_step_rho = &self->time_parm->double_parm[0]; riem_step_r = &self->time_parm->double_parm[1]; self->weier_f.g = riem_step_g; self->weier_f.dh = riem_step_f; self->weier_f.dg = riem_step_dg; } else fprintf(stderr, "set-weier-f: surface \"%s\" unknown\n", self->name); END_METHOD(self); }
The Weierstrass functions are added by replacing the empty default "set-weier-f" method, again the name of the Amandus instance is used to determine which functions should be used to initialize weier_f. If the (time-dependent) parameter are needed for the Weierstrass functions they have to be copied to local variables in "set-weier-f" since they cannot be accessed directly in the weier_f functions.
Copyright © by the Sonderforschungsbereich 256 at the Institut für Angewandte Mathematik, Universität Bonn.