00001 #include <string.h>
00002 #include "nonlinman.h"
00003
00004
00005
00006 nonlinman::nonlinman (void)
00007 {
00008
00009
00010 tnlinsol = (nonlinsolvertype) 0;
00011
00012 displnorm = (displacementnorm) 0;
00013
00014 nial = 0;
00015 niilal = 0;
00016 erral = 0.0;
00017 dlal = 0.0;
00018 dlmaxal = 0.0;
00019 psial = 0.0;
00020 nsnal=0;
00021 selnodal=NULL;
00022 hdbackupal=0;
00023 nsdofal=0;
00024 seldofal=NULL;
00025
00026 dlam=nodetermination;
00027
00028 ninr = 0;
00029 niilnr = 0;
00030 errnr = 0.0;
00031 incrnr = 0.0;
00032 minincrnr = 0.0;
00033
00034 nienr = 0;
00035 hdbr = 0;
00036 hdbid = 0;
00037 backupfname[0] = 0;
00038
00039
00040 stmat = initial_stiff;
00041
00042 ithstiffchange=1;
00043 jthstiffchange=1;
00044
00045 check_div = off;
00046 div_min_steps = 3;
00047 divc_step = NULL;
00048 divc_err = NULL;
00049 check_lambdar = off;
00050 lambdar = 0.0;
00051 errl = 0.0;
00052 }
00053
00054
00055
00056 nonlinman::~nonlinman (void)
00057 {
00058 delete [] selnodal;
00059 delete [] seldofal;
00060 delete [] divc_step;
00061 delete [] divc_err;
00062 }
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 void nonlinman::read (XFILE *in,long mespr)
00078 {
00079
00080 xfscanf (in, "%k%m", "type_of_nonlin_solver", &nonlinsolvertype_kwdset, (int*)&tnlinsol);
00081
00082
00083 xfscanf (in,"%k%m","stiffmat_type", &stiffmatrix_kwdset, (int*)&stmat);
00084 switch (stmat){
00085 case initial_stiff:
00086 case tangent_stiff:
00087 case secant_stiff:
00088 case incr_tangent_stiff:{
00089 break;
00090 }
00091 case ijth_tangent_stiff:{
00092 xfscanf (in,"%ld %ld",&ithstiffchange,&jthstiffchange);
00093 break;
00094 }
00095 default:{
00096 print_err("unknown type of stiffness matrix is required",__FILE__,__LINE__,__func__);
00097 }
00098 }
00099
00100 switch (tnlinsol){
00101 case arcl:
00102 case adaptram:
00103 case arclrv1:
00104 case arclrv:
00105 case arclg:{
00106 if (mespr==1) fprintf (stdout,"\n system of nonlinear equations will be solved by arc-length method");
00107 xfscanf (in, "%k%m", "lambda_determination", &detlambda_kwdset, &dlam);
00108 xfscanf (in, "%k%ld%k%ld", "al_num_steps", &nial, "al_num_iter", &niilal);
00109 xfscanf (in, "%k%lf%k%lf", "al_error", &erral, "al_init_length", &dlal);
00110 xfscanf (in, "%k%lf%k%lf", "al_min_length", &dlminal, "al_max_length", &dlmaxal);
00111 xfscanf (in, "%k%lf", "al_psi", &psial);
00112
00113 if ((tnlinsol == arclrv1) || (tnlinsol == arclrv))
00114 xfscanf(in, "%k%lf", "reqval_lambda",&lambdar);
00115 if (tnlinsol == arclrv)
00116 xfscanf(in, "%k%lf", "reqerr_lambda",&errl);
00117
00118 if (tnlinsol == arclg){
00119
00120 xfscanf(in, "%k%m", "check_div", &flagsw_kwdset, &check_div);
00121 if (check_div == on){
00122 xfscanf(in, "%k%ld", "div_min_steps", &div_min_steps);
00123 if (div_min_steps < 3){
00124 print_warning("the minimum number of performed steps in the divergency check is < 3.\n"
00125 "It will be set to 3 automatically", __FILE__, __LINE__, __func__);
00126 div_min_steps = 3;
00127 }
00128 }
00129
00130
00131 xfscanf(in, "%k%m", "check_total_arcl", &flagsw_kwdset, &check_tot_al);
00132 if (check_tot_al == on)
00133 xfscanf(in, "%k%lf", "max_total_arc_length", &max_tot_al);
00134
00135 xfscanf(in, "%k%m", "check_req_lambda", &flagsw_kwdset, &check_lambdar);
00136 if (check_lambdar == on){
00137 xfscanf(in, "%k%lf", "reqval_lambda",&lambdar);
00138
00139 xfscanf(in, "%k%lf", "reqerr_lambda",&errl);
00140 }
00141 }
00142
00143
00144 xfscanf (in,"%k%m","al_displ_contr_type",&displacementnorm_kwdset,(int*)&displnorm);
00145
00146 switch (displnorm){
00147 case alldofs:{ break; }
00148 case seldofs:{
00149 xfscanf (in,"%k%ld","num_sel_dofs",&nsdofal);
00150 selnodal = new long [nsdofal];
00151 seldofal = new long [nsdofal];
00152 read_seldof (in);
00153 break;
00154 }
00155 case seldofscoord:{
00156 xfscanf (in,"%ld",&nsdofal);
00157 selnodal = new long [nsdofal];
00158 seldofal = new long [nsdofal];
00159 selnodcoord = new double [3*nsdofal];
00160 read_seldofcoord (in);
00161 break;
00162 }
00163 case selecnodes:{
00164 xfscanf (in,"%k%ld", "num_sel_nodes", &nsnal);
00165 selnodal = new long [nsnal];
00166 read_selnod (in);
00167 break;
00168 }
00169 case nodesdistincr:{
00170 nsnal=2;
00171 xfscanf (in,"%k%ld","probdimal",&probdimal);
00172 selnodal = new long [nsnal];
00173 read_selnod (in);
00174 break;
00175 }
00176 default:
00177 print_err("unknown norm measurement of displacement increment", __FILE__, __LINE__, __func__);
00178 }
00179
00180 break;
00181 }
00182 case newton:{
00183 if (mespr==1) fprintf (stdout,"\n system of nonlinear equations will be solved by Newton-Raphson method");
00184 xfscanf (in, "%k%ld%k%ld", "nr_num_steps", &ninr, "nr_num_iter", &niilnr);
00185 xfscanf (in, "%k%lf%k%lf", "nr_error", &errnr, "nr_init_incr", &incrnr);
00186 xfscanf (in, "%k%lf%k%lf", "nr_minincr", &minincrnr, "nr_maxincr", &maxincrnr);
00187 break;
00188 }
00189 case newtonrv1:{
00190 if (mespr==1) fprintf (stdout,"\n system of nonlinear equations will be solved by Newton-Raphson method");
00191 xfscanf (in, "%k%ld%k%ld", "nr_num_steps", &ninr, "nr_num_iter", &niilnr);
00192 xfscanf (in, "%k%lf%k%lf", "nr_error", &errnr, "nr_init_incr", &incrnr);
00193 xfscanf (in, "%k%lf%k%lf", "nr_minincr", &minincrnr, "nr_maxincr", &maxincrnr);
00194 xfscanf (in, "%k%lf", "req_lambda", &lambdar);
00195 if (mespr==1) fprintf(stdout, "\n requried value of lambda=% e", lambdar);
00196 break;
00197 }
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 case displctrl:{
00210 if (mespr==1) fprintf (stdout,"\n system of nonlinear equations will be solved by Newton-Raphson method with displacement control");
00211 xfscanf (in, "%k%ld%k%ld", "nr_num_steps", &ninr, "nr_num_iter", &niilnr);
00212 xfscanf (in, "%k%lf%k%lf", "nr_error", &errnr, "nr_init_incr", &incrnr);
00213 xfscanf (in, "%k%lf%k%lf", "nr_minincr", &minincrnr, "nr_maxincr", &maxincrnr);
00214 break;
00215 }
00216 case displctrlrv:{
00217 if (mespr==1) fprintf (stdout,"\n system of nonlinear equations will be solved by Newton-Raphson method with displacement control");
00218 xfscanf (in, "%k%ld%k%ld", "nr_num_steps", &ninr, "nr_num_iter", &niilnr);
00219 xfscanf (in, "%k%lf%k%lf", "nr_error", &errnr, "nr_init_incr", &incrnr);
00220 xfscanf (in, "%k%lf%k%lf", "nr_minincr", &minincrnr, "nr_maxincr", &maxincrnr);
00221 xfscanf (in, "%k%lf%k%lf", "req_lambda", &lambdar, "req_lam_err", &errl);
00222 if (mespr==1) fprintf(stdout, "\n requried value of lambda=% e, required error of lambda=% e", lambdar, errl);
00223 break;
00224 }
00225 case newtong:
00226 if (mespr==1) fprintf (stdout,"\n system of nonlinear equations will be solved by Newton-Raphson method");
00227 xfscanf (in, "%k%ld%k%ld", "nr_num_steps", &ninr, "nr_num_iter", &niilnr);
00228 xfscanf (in, "%k%lf%k%lf", "nr_error", &errnr, "nr_init_incr", &incrnr);
00229 xfscanf (in, "%k%lf%k%lf", "nr_minincr", &minincrnr, "nr_maxincr", &maxincrnr);
00230
00231
00232 xfscanf(in, "%k%m", "check_div", &flagsw_kwdset, &check_div);
00233 if (check_div == on)
00234 {
00235 xfscanf(in, "%k%ld", "div_min_steps", &div_min_steps);
00236 if (div_min_steps < 3)
00237 {
00238 print_warning("the minimum number of performed steps in the divergency check is < 3.\n"
00239 "It will be set to 3 automatically", __FILE__, __LINE__, __func__);
00240 div_min_steps = 3;
00241 }
00242 }
00243
00244
00245 xfscanf(in, "%k%m", "check_req_lambda", &flagsw_kwdset, &check_lambdar);
00246 if (check_lambdar == on)
00247 {
00248 xfscanf(in, "%k%lf", "reqval_lambda",&lambdar);
00249
00250 xfscanf(in, "%k%lf", "reqerr_lambda",&errl);
00251 }
00252 break;
00253 default:
00254 print_err("unknown solver of nonlinear system of equations is required", __FILE__, __LINE__, __func__);
00255 }
00256 if (check_div == on)
00257 {
00258 divc_step = new double[div_min_steps];
00259 divc_err = new double[div_min_steps];
00260 }
00261 }
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275 void nonlinman::print (FILE *out)
00276 {
00277
00278 fprintf (out,"%d\n",(int)tnlinsol);
00279
00280 fprintf (out, "\n%d \n", (int)stmat);
00281 switch (stmat){
00282 case initial_stiff:
00283 case tangent_stiff:
00284 case secant_stiff:
00285 case incr_tangent_stiff:{
00286 break;
00287 }
00288 case ijth_tangent_stiff:{
00289 fprintf (out,"%ld %ld\n",ithstiffchange,jthstiffchange);
00290 break;
00291 }
00292 default:{
00293 print_err("unknown type of stiffness matrix is required",__FILE__,__LINE__,__func__);
00294 }
00295 }
00296
00297 switch (tnlinsol){
00298 case arcl:
00299 case arclrv1:
00300 case arclg:
00301 {
00302 fprintf (out,"%d\n",(int)dlam);
00303 fprintf (out, "%ld %ld %e %e %e %e %e\n", nial, niilal, erral, dlal,
00304 dlminal, dlmaxal, psial);
00305 if ((tnlinsol == arclrv1) || (tnlinsol == arclrv))
00306 fprintf(out, "%f\n", lambdar);
00307 if (tnlinsol == arclrv)
00308 fprintf(out, "%f\n", errl);
00309
00310 if (tnlinsol == arclg)
00311 {
00312
00313 fprintf(out, "%d", check_div);
00314 if (check_div == on)
00315 fprintf(out, " %ld\n", div_min_steps+1);
00316 else
00317 fprintf(out, "\n");
00318
00319
00320 fprintf(out, "%d", check_tot_al);
00321 if (check_tot_al == on)
00322 fprintf(out, " %le\n", max_tot_al);
00323 else
00324 fprintf(out, "\n");
00325
00326
00327 fprintf(out, "%d", check_lambdar);
00328 if (check_lambdar == on)
00329 fprintf(out, " %le %le\n", lambdar, errl);
00330 else
00331 fprintf(out, "\n");
00332 }
00333
00334 fprintf (out,"%d\n",displnorm);
00335
00336 switch (displnorm){
00337 case alldofs:{ break; }
00338 case seldofs:{
00339 fprintf (out,"%ld\n",nsdofal);
00340 print_seldof (out);
00341 break;
00342 }
00343 case seldofscoord:{
00344 fprintf (out,"%ld\n",nsdofal);
00345 print_seldofcoord (out);
00346 break;
00347 }
00348 case selecnodes:{
00349 fprintf (out,"%ld\n",nsnal);
00350 print_selnod (out);
00351 break;
00352 }
00353 case nodesdistincr:{
00354 nsnal=2;
00355 fprintf (out,"%ld\n",probdimal);
00356 print_selnod (out);
00357 break;
00358 }
00359 default:
00360 print_err("unknown norm measurement of displacement increment", __FILE__, __LINE__, __func__);
00361 }
00362 break;
00363 }
00364 case newton:{
00365 fprintf (out, "%ld %ld %e %e %e %e\n", ninr, niilnr, errnr, incrnr, minincrnr, maxincrnr);
00366 break;
00367 }
00368 case newtonrv1:{
00369 fprintf (out, "%ld %ld %e %e %e %e %e\n", ninr, niilnr, errnr, incrnr, minincrnr, maxincrnr, lambdar);
00370 break;
00371 }
00372 case newtonrestart:{
00373 fprintf (out,"%ld %ld %e %e %e\n",ninr,niilnr,errnr,incrnr,minincrnr);
00374 fprintf (out, "%ld %ld\n", nienr, hdbr);
00375 if (hdbr)
00376 fprintf(out, "%s\n %ld\n", backupfname, hdbid);
00377 break;
00378 }
00379 case displctrl:{
00380 fprintf (out, "%ld %ld %e %e %e\n", ninr, niilnr, errnr, incrnr, minincrnr);
00381 break;
00382 }
00383 case displctrlrv:{
00384 fprintf (out,"%ld %ld %lf %lf %lf %lf %lf\n",ninr,niilnr,errnr,incrnr,minincrnr,lambdar,errl);
00385 break;
00386 }
00387 case newtong:
00388 {
00389 fprintf (out, "%ld %ld\n", ninr, niilnr);
00390 fprintf (out, "%le %le %le %le\n", errnr, incrnr, minincrnr, maxincrnr);
00391
00392 fprintf(out, "%d", check_div);
00393 if (check_div == on)
00394 fprintf(out, " %ld\n", div_min_steps+1);
00395 else
00396 fprintf(out, "\n");
00397
00398 fprintf(out, "%d", check_lambdar);
00399 if (check_lambdar == on)
00400 fprintf(out, " %le %le\n", lambdar, errl);
00401 else
00402 fprintf(out, "\n");
00403
00404 break;
00405 }
00406 default:{}
00407 }
00408
00409 }
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422 void nonlinman::read_selnod (XFILE *in)
00423 {
00424 long i;
00425
00426 for (i=0;i<nsnal;i++){
00427 xfscanf (in,"%ld",selnodal+i);
00428 selnodal[i]--;
00429 }
00430
00431 }
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444 void nonlinman::read_seldof (XFILE *in)
00445 {
00446 long i;
00447
00448 for (i=0;i<nsdofal;i++){
00449 xfscanf (in,"%ld %ld",selnodal+i,seldofal+i);
00450 selnodal[i]--; seldofal[i]--;
00451 }
00452
00453 }
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466 void nonlinman::read_seldofcoord (XFILE *in)
00467 {
00468 long i;
00469
00470 for (i=0;i<nsdofal;i++){
00471 xfscanf (in,"%lf %lf %lf %ld",selnodcoord+3*i,selnodcoord+3*i+1,selnodcoord+3*i+2,seldofal+i);
00472 seldofal[i]--;
00473 }
00474 }
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487 void nonlinman::print_selnod (FILE *out)
00488 {
00489 long i;
00490
00491 for (i=0;i<nsnal;i++){
00492 fprintf (out,"%ld\n",selnodal[i]+1);
00493 }
00494
00495 }
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508 void nonlinman::print_seldof (FILE *out)
00509 {
00510 long i;
00511
00512 for (i=0;i<nsdofal;i++){
00513 fprintf (out,"%ld %ld\n",selnodal[i]+1,seldofal[i]+1);
00514 }
00515
00516 }
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529 void nonlinman::print_seldofcoord (FILE *out)
00530 {
00531 long i;
00532
00533 for (i=0;i<nsdofal;i++){
00534 fprintf (out,"%f %f %f %ld\n",selnodcoord[3*i],selnodcoord[3*i+1],selnodcoord[3*i+2],seldofal[i]+1);
00535 }
00536
00537 }
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550 void nonlinman::initiate (nonlinman &nm)
00551 {
00552 long i;
00553
00554 tnlinsol = nm.tnlinsol;
00555
00556 stmat = nm.stmat;
00557 ithstiffchange = nm.ithstiffchange;
00558 jthstiffchange = nm.jthstiffchange;
00559
00560
00561 displnorm = nm.displnorm;
00562 dlam = nm.dlam;
00563 hdbackupal = nm.hdbackupal;
00564 nial = nm.nial;
00565 niilal = nm.niilal;
00566 erral = nm.erral;
00567 dlal = nm.dlal;
00568 dlminal = nm.dlminal;
00569 dlmaxal = nm.dlmaxal;
00570 psial = nm.psial;
00571
00572 nsnal = nm.nsnal;
00573 nsdofal = nm.nsdofal;
00574 probdimal = nm.probdimal;
00575 check_tot_al = nm.check_tot_al;
00576 max_tot_al = nm.max_tot_al;
00577
00578 nxal = nm.nxal;
00579 nyal = nm.nyal;
00580 nzal = nm.nzal;
00581
00582
00583 switch (displnorm){
00584 case alldofs:{ break; }
00585 case seldofs:{
00586 selnodal = new long [nsdofal];
00587 seldofal = new long [nsdofal];
00588
00589 for (i=0;i<nsdofal;i++){
00590 selnodal[i]=nm.selnodal[i];
00591 seldofal[i]=nm.seldofal[i];
00592 }
00593
00594 break;
00595 }
00596 case seldofscoord:{
00597 seldofal = new long [nsdofal];
00598 selnodcoord = new double [3*nsdofal];
00599
00600 for (i=0;i<nsdofal;i++){
00601 selnodcoord[3*i]=nm.selnodcoord[3*i];
00602 selnodcoord[3*i+1]=nm.selnodcoord[3*i+1];
00603 selnodcoord[3*i+2]=nm.selnodcoord[3*i+2];
00604 seldofal[i]=nm.seldofal[i];
00605 }
00606
00607 break;
00608 }
00609 case selecnodes:{
00610 selnodal = new long [nsnal];
00611
00612 for (i=0;i<nsnal;i++){
00613 selnodal[i]=nm.selnodal[i];
00614 }
00615
00616 break;
00617 }
00618 case nodesdistincr:{
00619 nsnal=2;
00620 selnodal = new long [nsnal];
00621
00622 for (i=0;i<nsnal;i++){
00623 selnodal[i]=nm.selnodal[i];
00624 }
00625
00626 break;
00627 }
00628 default:
00629 print_err("unknown norm measurement of displacement increment", __FILE__, __LINE__, __func__);
00630 }
00631
00632
00633 check_lambdar = nm.check_lambdar;
00634 lambdar = nm.check_lambdar;
00635 errl = nm.errl;
00636
00637 check_div = nm.check_div;
00638 div_min_steps = nm.div_min_steps;
00639 if (check_div == on)
00640 {
00641 divc_step = new double[div_min_steps];
00642 divc_err = new double[div_min_steps];
00643 for(i=0; i<div_min_steps; i++)
00644 {
00645 divc_step[i] = nm.divc_step[i];
00646 divc_err[i] = nm.divc_err[i];
00647 }
00648 }
00649
00650
00651 ninr = nm.ninr;
00652 niilnr = nm.niilnr;
00653 errnr = nm.errnr;
00654 incrnr = nm.incrnr;
00655 minincrnr = nm.minincrnr;
00656 maxincrnr = nm.maxincrnr;
00657 lambdar = nm.lambdar;
00658 nienr = nm.nienr;
00659 hdbr = nm.hdbr;
00660 if (hdbr)
00661 {
00662 hdbid = nm.hdbid;
00663 for (i=0; i < long(strlen(nm.backupfname)); i++)
00664 backupfname[i] = nm.backupfname[i];
00665 }
00666 }