Commit adcfb495 authored by Taddeüs Kroes's avatar Taddeüs Kroes

ModSim ass4 taddeus: Added sequential vibrating string program (untested).

parent 8ca8c52e
CC=mpicc CC=mpicc
CFLAGS=-Wall -Wextra -pedantic -std=c99 -O2 CFLAGS=-Wall -Wextra -pedantic -std=c99 -O0
all: test ring all: test ring
test: ring_test.o test: ring_test.o
......
CC=mpicc CC=gcc
CFLAGS=-Wall -Wextra -pedantic -std=c99 -O2 CFLAGS=-Wall -Wextra -pedantic -std=c99 -O0 -D_GNU_SOURCE
LDFLAGS=-lm
all: vibstring all: seq
vibstring: main.o seq: seq.o
clean: clean:
rm -vf *.o vibstring rm -vf *.o vibstring
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <math.h>
//#define DEBUG #define DEBUG
#define LOOP 100 /*
#define STRIDE 10000 *
#define REPEAT 7 */
double **init_sinus(double l, double dx, double n, int *steps) {
double **y;
int i;
*steps = (int)ceil(l / dx);
y = (double**)malloc(3 * *steps * sizeof(double));
const int data_size = LOOP * STRIDE; for( i = 0; i < *steps; i++ )
y[i][0] = sin(n * M_PI * i * dx / l);
return y;
}
/* /*
* The master task measures the time between the sending and receiving of data. *
*/ */
void (int tasks, int rank) { double **init_plucked(double l, double dx, double xp, int *steps) {
double *data = malloc(data_size * sizeof(double)); double **y, x;
MPI_Status status; int i;
int size, measurement,
source = (rank - 1 + tasks) % tasks, target = (rank + 1) % tasks; *steps = (int)ceil(l / dx);
y = (double**)malloc(3 * *steps * sizeof(double));
// Increase the message length with a fixed STRIDE
for( size = STRIDE; size <= data_size; size += STRIDE ) { for( i = 0; i < *steps; i++ ) {
// Repeat the measurement x = i * dx;
for( measurement = 1; measurement <= REPEAT; measurement++ ) { y[i][0] = x < xp ? x / xp : (l - x) / (l - xp);
MPI_Recv(data, size, MPI_DOUBLE, source, MPI_ANY_TAG,
MPI_COMM_WORLD, &status);
MPI_Send(data, size, MPI_DOUBLE, target, 0, MPI_COMM_WORLD);
}
} }
free(data); // The string is attached at both ends
y[0][2] = y[0][1] = y[0][0];
y[*steps - 1][2] = y[*steps - 1][1] = y[*steps - 1][0];
return y;
} }
int main(int argc, char **argv) { void iterate(double **y, int steps, double dx, double T) {
int tasks, rank, error; double x;
int i, prev = 0, current = 1, next = 2;
if( (error = MPI_Init(&argc, &argv)) != MPI_SUCCESS ) { // Calculate the position over the entire string at time dt using the
printf("MPI_init failed (error %d)\n", error); // position at t = 0 and the information that y(x, -dt) == y(x, dt)
MPI_Abort(MPI_COMM_WORLD, error); for( i = 2; i < steps; i++ ) {
return EXIT_FAILURE; x = i * dx;
y[i][1] = y[i][0] + .5 * T * T * (y[i-1][0] - 2 * y[i][0] + y[i-1][0]);
} }
MPI_Comm_size(MPI_COMM_WORLD, &tasks); // Iterate over the length of the string
MPI_Comm_rank(MPI_COMM_WORLD, &rank); for( i = 1; i < steps - 1; i++ ) {
y[i][next] = 2 * y[i][current] - y[i][prev]
+ T * T * (y[i-1][current] - 2 * y[i][current] + y[i+1][current]);
if( !rank ) prev = current;
master(tasks); current = next;
else next = (next + 1) % 3;
slave(tasks, rank); }
free(y);
}
int main(int argc, const char **argv) {
int steps;
double **(*method)(double, double, double, int*);
if( argc < 5 ) {
printf("Usage: %s INIT_METHOD L DX T N|XP\n", argv[0]);
return EXIT_FAILURE;
}
if( !strcmp(argv[1], "sinus") ) {
method = init_sinus;
} else if( !strcmp(argv[1], "plucked") ) {
method = init_plucked;
} else {
printf("Unknown method '%s'.\n", argv[1]);
return EXIT_FAILURE;
}
MPI_Finalize(); iterate((*method)(atof(argv[2]), atof(argv[3]), atof(argv[5]), &steps),
steps, atof(argv[3]), atof(argv[4]));
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment